⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 430单片机自升级程序
💻 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 + -