新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機一鍵下載相關

        51單片機一鍵下載相關

        作者: 時間:2016-11-28 來源:網絡 收藏

        // 作品:STC免手動燒寫(自適應波特率自動冷啟) + 簡易邏輯分析儀
        // 芯片:STC15F104E
        // 晶振:45MHz
        // 編譯:Keil uVision4 V9.00
        //
        // 說明:自適應STC-ISP軟件最低波特率(1200bps/2400bps/4800bps)
        //3種模式:①自動燒寫(默認)【LED_key不亮:模式① ,LED亮:通電 ,LED不亮:關電】
        //②邏輯分析儀(正向波形) 【LED_key亮:模式② ,LED亮:預備 ,LED不亮:采樣】
        //③邏輯分析儀(反向波形) 【LED_key閃爍:模式③ ,LED亮:預備 ,LED不亮:采樣】
        //①②③模式下,系統板都可以正常串口通信。
        //②③模式下,也可以燒寫程序(手動燒寫),不過正在“采樣”時請不要燒寫程序以及系統板串口通信。
        //
        // 注:建議燒寫程序時啟動看門狗(預分頻數256,約2.2S @ 45MHz)
        //
        //另:關于STC-ISP V4.88版本,發現用PL2303HX芯片燒寫STC15系列很難成功,最低/高波特率都選用4800bps才可以燒寫。
        //關于STC-ISP V6.06版本,用PL2303HX芯片燒寫STC15系列非常好(直接用默認的最低/高波特率),
        //但V6.06版本內部R/C振蕩器最高只可以選33.1776MHz。
        //用FT232芯片燒寫,則通殺STC-ISP所有版本(直接用默認的最低/高波特率)。
        //

        #include "STC15F104E.H"
        #include "MY_SET.h"

        sbit LED= P3^0;//指示燈
        sbit KEY= P3^1;//按鍵
        sbit RXB= P3^2;
        sbit TXB= P3^3;
        sbit PNP= P3^4;//PNP三極管
        sbit IO_in = P3^5;//分析儀采樣引腳

        uint8Mode;//模式
        bitB_init;//初始化標志
        uint8KEY_Value; //按鍵消抖計數
        bitON;//按鍵標志
        bitOver;
        bitLED_key;//模式指示燈(在按鍵上擴展)
        uint16Count;//閃爍計數
        bitP_N;//正向標志
        uint8BIT8,cnt,Dat;
        uint16Time;

        uint8 TBUF,RBUF;//發送/接收緩存
        uint8 TDAT,RDAT;//發送/接收數據暫存
        uint8 TCNT,RCNT;//發送/接收計數器
        uint8 TBIT,RBIT;//發送/接收比特數
        bitTING,RING;//開始發送/接收標志
        bitTEND,REND;//發送/接收完成標志

        bitSTART;//重啟標志
        uint8 Correct_nums;//『連續正確』計數器
        uint8 Error_nums;//錯誤累加計數器
        uint8 Status;//波特率狀態


        void YS(uint8 n)
        {
        uint8 a,b,c;

        while(n--)
        {
        for(c=66;c>0;c--)
        for(b=100;b>0;b--)
        for(a=100;a>0;a--);
        }
        }

        void UART_INIT()
        {
        TING = 0;
        RING = 0;
        TEND = 1;
        REND = 0;
        TCNT = 0;
        RCNT = 0;
        }

        void Analyzer_Init()
        {
        TR1 = 0;
        TF1 = 0;
        Time = 0;
        BIT8 = 0;
        TL0 = 0x7E; //初始化T0和設定重載值
        TH0 = 0xFF;//修改成 115200bps
        LED = 0;//指示燈開
        }

        void UART_Change()
        {
        if(++Status > 2)Status=0;
        switch(Status)
        {
        case 0: TL0=(65536-15000000/1200); TH0=(65536-15000000/1200)>>8; break; // 1200bps
        case 1: TL0=(65536-15000000/2400); TH0=(65536-15000000/2400)>>8; break; // 2400bps
        case 2: TL0=(65536-15000000/4800); TH0=(65536-15000000/4800)>>8; break; // 4800bps
        }
        }

        void Restart()
        {
        if(START)
        {
        START = 0;

        TR0 = 0;
        PNP = 1;//關電
        LED = 1;
        YS(10);//從『加載HEX』到『提示上電』有5秒,但不必等到『提示上電』
        WDT_CONR |= 0x10;//清看門狗(預分頻數256,約2.2S @ 45MHz)
        PNP = 0;//通電
        LED = 0;
        YS(30);
        WDT_CONR |= 0x10;//清看門狗(預分頻數256,約2.2S @ 45MHz)

        TR0 = 1;
        RING = 0;
        REND = 0;
        RCNT = 0;
        }
        }

        void main()
        {
        uint8 i;

        P33 = 1;
        WDT_CONR |= 0x10; //清看門狗(預分頻數256,約2.2S @ 45MHz)
        PNP = 0;//通電
        LED= 0;
        LED_key = 1;//關

        for(i=0;i<30;i++){ YS(1); LED = ~LED; } //冷啟/低壓復位 指示
        WDT_CONR |= 0x10; //清看門狗(預分頻數256,約2.2S @ 45MHz)

        TMOD = 0x00;//T0、T1處于16位自動重裝模式
        AUXR = 0xC0;//T0、T1工作在1T模式
        TL1 = (65536-903);
        TH1 = (65536-903)>>8;
        UART_Change();
        TR0 = 1;
        EA= 1;
        ET0 = 1;
        PT0 = 1;//提高T0的中斷優先級
        ET1 = 1;
        UART_INIT();

        Mode = 0;

        while(1)
        {
        switch(Mode)
        {
        case 0: if(B_init)
        {
        B_init=0;
        TR1=0;
        PNP = 0;//通電
        LED=0;
        UART_Change();
        UART_INIT();
        }
        Restart();
        LED_key = 1;
        break;

        case 1: if(B_init){ B_init=0; P_N=1; Analyzer_Init(); }
        if(!IO_in){ TR1=1; LED=1;}//啟動定時器1,采樣開始
        if(Over)
        {
        Over=0;
        if(++Time > 3320)Analyzer_Init();//約16.6秒(5ms * 3320),即每次采集完,過4秒(16.6S-12.6S)后重新工作
        }
        LED_key = 0;
        break;

        case 2: if(B_init){ B_init=0; P_N=0; Analyzer_Init(); }
        if(!IO_in){ TR1=1; LED=1;}
        if(Over)
        {
        Over=0;
        if(++Time > 3320)Analyzer_Init();
        }
        if(++Count >10000){ Count=0; LED_key=!LED_key;} //閃爍
        break;

        default:Mode=0;
        break;
        }

        //按鍵檢測
        KEY = 1;//拉高電平
        NOP12();//稍微延時
        if(!KEY)
        {
        if(ON==0)KEY_Value++;
        if(KEY_Value > 200)
        {
        KEY_Value = 0;
        ON = 1;//按鍵標志置“1”
        if(++Mode > 2)Mode=0;
        B_init = 1;//『初始化標志』置“1”
        }
        }
        else { KEY_Value=0; ON=0; }

        //恢復指示燈狀態
        if(LED_key)KEY=1;
        elseKEY=0;

        WDT_CONR |= 0x10;//清看門狗(預分頻數256,約2.2S @ 45MHz)
        }
        }

        void tm0() interrupt 1 using 1
        {
        if(RING)
        {
        if(--RCNT == 0)
        {
        RCNT = 3;//復位接收波特率計數器
        if(--RBIT == 0)
        {
        RBUF = RDAT;//保存數據到RBuf管理
        RING = 0;//停止接收
        REND = 1;//設置接收完成標志
        }
        else
        {
        RDAT >>= 1;
        if(RXB) RDAT |= 0x80; //RX數據轉移到RX緩沖區
        }
        }
        }
        else if(!RXB)//是否檢測到低電平
        {
        RING = 1;//設置開始接收標志
        RCNT = 4;//初始接收波特率計數器
        RBIT = 9;//初化始接收比特數(8個數據位+1個停止位)
        }

        if(--TCNT == 0)
        {
        TCNT = 3;//復位發送波特率計數器
        if(TING)//判斷是否發送
        {
        if(TBIT == 0)
        {
        TXB = 0;//發送起始位
        TDAT = TBUF;//加載數據從TBUF至TDAT
        TBIT = 9;//初化始發送比特數(8位數據位+1個停止位)
        }
        else
        {
        TDAT >>= 1;//位移數據至CY
        if(--TBIT == 0)
        {
        TXB = 1;
        TING = 0;//停止發送
        TEND = 1;//設置發送完成標志
        }
        else
        {
        TXB = CY;//寫CY至TX端口
        }
        }
        }
        }

        if((Mode==0) && REND)
        {
        REND = 0;
        if(RBUF == 0x7F)
        {
        if(++Correct_nums > 10)
        {
        START=1;
        Correct_nums=0;
        Error_nums=0;
        }
        }
        else
        {
        Correct_nums=0;
        if(++Error_nums > 6)
        {
        TR0 = 0;
        Error_nums=0;
        Correct_nums=0;
        UART_Change();
        RING = 0;
        REND = 0;
        RCNT = 0;
        TR0 = 1;
        }
        }
        }
        }

        void tm1() interrupt 3
        {
        if(IO_in)Dat |= 0x01;
        if(++BIT8 == 8) //每采集8次發送一次
        {
        if(P_N)TBUF =Dat;//正向輸出
        elseTBUF = ~Dat;//反向輸出
        TING = 1;
        BIT8 = 0;
        }
        Dat <<= 1;
        if(++cnt == 0)Over=1;//約5ms置1一次
        }【主位的電路,11.0592M】
        那個是舊版本,電路圖也有些不妥(應該把10Ω電阻去掉),下載“最低波特率”固定,而且沒有邏輯分析儀功能

        【32樓的電路,11.0592M】
        在舊版上改進:自動適應STC-ISP軟件中的“最低波特率” 3種波特率,可選“1200bps/2400bps/4800bps”
        但也沒有邏輯分析儀功能

        【49樓的電路,45M】
        程序全新修改;
        自動適應STC-ISP軟件中的“最低波特率” 3種波特率,可選“1200bps/2400bps/4800bps”;
        增加簡易單路邏輯分析儀。

        PS:
        STC-ISP軟件中選用不同型號的STC時,默認的下載“最低波特率”不同,比如:
        STC89系列:默認 最低波特率 1200bps
        STC12系列:默認 最低波特率 2400bps
        STC15系列:默認 最低波特率 4800bps
        懶得每次選擇,所以增加自適應3種最低波特率“1200bps/2400bps/4800bps”功能




        另:
        在STC單片機中有兩個程序區,用戶程序區與ISP程序區。單片機上電后(冷啟動,并非外部手動復位或看門狗復位),先會運行ISP程序,檢測是否有合法的下載命令流,占時幾十毫秒到幾百毫秒,如果沒有合法的下載命令流,則立即運行用戶程序。
        如果有合法的下載命令流,則ISP監控程序開始與ISP下載軟件通信,軟件也會進入編程模式,向監控程序發送程序碼,監控程序接收程序碼,并將其寫入用戶程序區中。在編程完畢,對程序校驗成功后,用戶程序立即生效,開始運行用戶程序。
        STC-ISP嘗試與MCU握手連接的時候,是以“最低波特率”設置項中的波特率不斷的從串口發送“0x7F”信號,直到MCU上電冷啟(或者軟復位至ISP)經幾十毫秒到幾百毫秒檢測下載命令流后,MCU做出響應,STC-ISP才停止發送“0x7F”信號開始燒寫。

        用簡易單路邏輯分析儀捕捉,STC-ISP下載程序前的串口命令流
        這個程序構思不完善,主要是自動適應波特率部分有些BUG,
        如果是固定程序中的最低波特率(對應STC-ISP的最低波特率選項,最高波特率選項任意),這個程序就運行很好,
        但這樣就不方便了,因為STC-ISP不同版本及不同型號默認最低波特率選項不同,懶得每次更換都改下STC-ISP的最低波特率選項。

        所以使用新方案解決:
        不再用硬件串口/模擬串口捕捉數據,先直接用計時器捕捉TXD上一定數量的連續電平數據,然后分析電平數據(比如:低電平時間相等,0x7F次數,……等等多重驗證),
        如果符合條件就重啟(斷電幾百ms后上電,隔>1.5S恢復監測);
        如果不符合條件則重新監測。

        上面這個方案幾近完美,負責監控的STC15F104E也不需要超頻到45M了,22.1184M就可以,
        同時自動適STC-ISP的最低波特率選項范圍更寬1200bps/2400bps/4800bps/9600bps,
        完美版的方案就是這樣,挺簡單的,程序就不傳了















        上一頁 1 2 3 下一頁

        關鍵詞: 51單片機一鍵下

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 岱山县| 宕昌县| 和田县| 桐城市| 崇阳县| 元朗区| 保康县| 卓尼县| 安达市| 永泰县| 阿拉尔市| 焦作市| 河池市| 荔浦县| 巍山| 汶川县| 长葛市| 南京市| 绥芬河市| 涿州市| 精河县| 仁怀市| 东兰县| 丰县| 乌兰县| 西充县| 磐安县| 栾城县| 尼木县| 芜湖县| 修文县| 南通市| 灌阳县| 昌江| 静乐县| 洪江市| 鲁甸县| 三门县| 南汇区| 阿拉善盟| 阳东县|