📄 main.c
字号:
#include"msp430x14x.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long int
//------------------内嵌汇编的宏定义---------------------------------------------
#define NOP asm("NOP")//无操作,延时一个时钟
#define DINT asm("DINT")//禁止中断
#define EINT asm("EINT")//打开中断
#define NOP4 {_NOP();_NOP();_NOP();_NOP();}
#define NOP2 {_NOP();_NOP();}
#define SEG_START 0x1100 //Flash Start
#define SEG_CNT (0xF400-SEG_START)/0x200 //Flash end
#define TX0BUSY ((IFG1&UTXIFG0)==0)
#define WATCHDOG_CLEAR {P5DIR|=BIT4;P5OUT|=BIT4;NOP4;NOP4;NOP4;P5OUT&=~BIT4;}
//变量区
uchar *pStrTmp;
uint tmp;
uint idx;
uint para_A;
uint para_B;
uint waittime=0;
uint RecvLen =0;
uint ReadAddr;
uchar nChar;
uchar ctmpa;
uchar ctmpb;
#define COMBUFF_LEN 128
uchar ComBuff[COMBUFF_LEN];
//函数声明
uchar IsString(uchar *pStr);
void UARTSendChar(uchar ch);
void UARTSend(const uchar *str);
void UARTSendCharHex(uchar data);
void FlashEraseBlock(uint address);
void Get2Para(uchar *str);
void Init_UART();
const uchar LF[]="\r\n";
//存储器组织(MSP430F149,MSP430F1491)
//Main: interrupt vector FFFFh--FFE0h
//Main: code memory(59.75KB) FFFFh--1100h
//Information memory (256B) 10FFh--1000h
//Boot memory(1K) 0FFFh--0C00h
//RAM(2KB) 09FFh--0200h
//Peripherals 16-bit (256B) 01FFh--0100h
// 8-bit (240B) 00FFh--0010h
// 8-bit SFR(16B) 000Fh--0000h
void main()
{
//时钟初始化
WDTCTL = WDTPW + WDTHOLD; // WDT
BCSCTL1 &= ~XT2OFF; // XT2on
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (idx = 0xFF; idx > 0; idx--); // Time for flag to set
}while ((IFG1 & OFIFG)); // OSCFault flag s
BCSCTL2 |= SELM_2 + SELS;
DINT;
waittime = 0;
Init_UART();
again:
RecvLen = 0;
UARTSend(LF);
UARTSend("?>");
tmp =0;
while (RecvLen<COMBUFF_LEN)
{
WATCHDOG_CLEAR;
if (IFG1 & URXIFG0)
{
ComBuff[RecvLen] = U0RXBUF;
UARTSendChar(ComBuff[RecvLen]);
if (ComBuff[RecvLen]==0x0D || ComBuff[RecvLen]==0x0A)
{
ComBuff[RecvLen] = 0;
break;
}else{
++RecvLen;
}
}
tmp++;
if (tmp==0xFFFF) waittime++;
if (waittime>30) goto end;//修改为15??
}
if (RecvLen<3) goto again;
UARTSend(LF);
//解析命令
if (IsString("echip"))
{
//擦除芯片
para_A = SEG_START;
for (idx=0;idx<SEG_CNT;idx++)
{
FlashEraseBlock(para_A);
para_A += 0x200;
WATCHDOG_CLEAR;
}
FlashEraseBlock(0xFE00);//最后一块
//恢复中断向量
FCTL2 = FWKEY+FSSEL0+FN3; //设为主时钟,4分频状态
FCTL1 = FWKEY + WRT;
FCTL3 = FWKEY; // LOCK=0,复位锁定标志
pStrTmp = (uchar*) 0xFFFE;
*pStrTmp++ = 0x00;
while (FCTL3&BUSY) _NOP();
*pStrTmp = (uchar)0xF4;
FCTL3 = FWKEY + LOCK;
UARTSend("Ok!");
}
else if (IsString("read"))
{
Get2Para(ComBuff+5);
pStrTmp = (uchar*)para_A;
ctmpb = 0;
UARTSendChar('@');
UARTSendCharHex((int)pStrTmp>>8);
UARTSendCharHex((int)pStrTmp);
UARTSend(LF);
for(idx=0;idx<para_B;idx++)
{
WATCHDOG_CLEAR;
UARTSendCharHex(*pStrTmp++);
++ctmpb;
if (ctmpb==16)
{
ctmpb = 0;
UARTSend(LF);
}else
UARTSendChar(' ');
}
UARTSend("Ok!");
}
else if (IsString("prog"))
{
pStrTmp = 0;
ReadAddr = 5;
while ((IFG1 & URXIFG0)==0);
ctmpa = U0RXBUF;
FCTL2 = FWKEY+FSSEL0+FN3; //设为主时钟,4分频状态
FCTL1 = FWKEY + WRT;
FCTL3 = FWKEY; // LOCK=0,复位锁定标志
while(ctmpa!='q')
{
WATCHDOG_CLEAR;
if (ctmpa!=0 && ctmpa!=' ' && ctmpa!='\r' && ctmpa!='\n')
{
if (ctmpa=='@')
{
ReadAddr = 1;
}else{
if (ReadAddr<5)
{
pStrTmp = (uchar*)(((uint)pStrTmp<<4));
if (ctmpa>=(uchar)'A')
pStrTmp = (uchar*)((uint)pStrTmp | (uint)(ctmpa - 'A' +10));
else
pStrTmp = (uchar*)((uint)pStrTmp |(uint)(ctmpa - '0'));
ReadAddr++;
}else{
//读字节,写入
if (ReadAddr==5)
{
ctmpb = ctmpa;
}
ReadAddr ++;
if (ReadAddr==7)
{
if (ctmpa>=(uchar)'A')
ctmpa= (ctmpa - 'A' +10);
else
ctmpa= (ctmpa - '0');
if (ctmpb>=(uchar)'A')
ctmpb= (ctmpb - 'A' +10);
else
ctmpb= (ctmpb - '0');
*pStrTmp++ = ((ctmpb<<4) | ctmpa);
while (FCTL3&BUSY) _NOP(); //等待
ReadAddr = 5;
}
}
}
}
while ((IFG1 & URXIFG0)==0);
ctmpa = U0RXBUF;
}
FCTL3 = FWKEY + LOCK;
UARTSend("Ok!");
}
else if (IsString("boot"))
{
goto end;
}
waittime = 0;
goto again;
end:
asm("MOV #01100h, PC");//直接执行上电复位
}
/********************不带奇校验的串口初始化**********************/
void Init_UART()
{
P3DIR = BIT4;
P3SEL = 0x30;
IE1 = 0; // Disable USART0
UCTL0 = CHAR + SWRST;// 8位数据 ,可以设置参数
UTCTL0 = 0X30; // UCLK = SMCLK
URCTL0 = 0X08;
UBR00 = 0x71;
UBR10 = 0x02;
UMCTL0= 0x00; // modulation
UCTL0 &= ~SWRST; //执行参数
ME1 = (UTXE0 + URXE0); // Enable USART0 RXD, TXD
}
void Get2Para(uchar *str)
{
uchar count=0;
para_A = 0;
para_B = 0;
if (*str==0) return;
while (str[count]==' ') ++count;
para_A = 0;
while(str[count]!=' ' && str[count]!=0)
{
para_A = para_A *10 + str[count] - '0';
count++;
}
while (str[count]==' ') ++count;
if (str[count]==0) return;
while (str[count]!=' ' && str[count]!=0)
{
para_B = para_B *10 + str[count] - '0';
count++;
}
}
uchar IsString(uchar *pStr)
{
tmp = 0;
pStrTmp = pStr;
while ( *pStrTmp)
{
if (*pStrTmp != ComBuff[tmp])
{
return 0;
}
tmp++;
pStrTmp++;
}
return 1;
}
//等待发送,直到完成
void UARTSend(const uchar *str)
{
tmp = 0;
while (str[tmp])
{
while (TX0BUSY) NOP;
U0TXBUF = str[tmp];
tmp++;
}
}
//等待发送,直到完成
void UARTSendChar(uchar ch)
{
while (TX0BUSY) NOP;
U0TXBUF = ch;
}
void UARTSendCharHex(uchar data)
{
ctmpa = (data>>4) &0x0F;
if (ctmpa>9) ctmpa = ctmpa -10 + 'A';
else ctmpa = ctmpa +'0' ;
while (TX0BUSY) NOP;
U0TXBUF = ctmpa;
ctmpa = data&0x0F;
if (ctmpa>9) ctmpa = ctmpa -10 + 'A';
else ctmpa = ctmpa +'0' ;
while (TX0BUSY) NOP;
U0TXBUF = ctmpa;
}
void FlashEraseBlock(uint address)
{
char *Ptr = (char*)(address&0xFF00);
//等待忙标志复位
while (FCTL3&BUSY) _NOP();
FCTL1 = FWKEY+ERASE; //设置片擦除状态
FCTL2 = FWKEY+FSSEL0+FN2; //设为主时钟,4分频状态
FCTL3 = FWKEY; // LOCK=0,复位锁定标志
*Ptr = 0; //启动擦除操作
while (FCTL3&BUSY) _NOP(); //等待擦除完毕
FCTL3 = FWKEY + LOCK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -