欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11230|回復: 11
打印 上一主題 下一主題
收起左側

AVR單片機BootLoader功能應用源碼與詳細介紹

  [復制鏈接]
跳轉到指定樓層
樓主
一、    題目:

AVR單片機BootLoader功能應用

二、    特色芯片技術介紹、使用說明:

AVR單片機中多數Mega系列單片機具有片內引導程序自編程功能即BootLoader功能。MCU 通過運行一個常駐FLASH的BootLoader 程序,利用任何可用的數據接口讀取代碼后寫入自身的FLASH存儲器中,實現自編程目的。
BootLoader功能將FLASH程序存儲器其分為應用程序區和引導加載區,通過設置熔絲位BOOTSZ0和BOOTSZ1可以配置不同大小的引導加載區空間;通過設置熔絲位BOOTRST用于設置復位向量,當BOOTRST未被編程時器件復位后從應用程序區首地址開始執行,當BOOTRST被編程時器件復位后從引導區首地址開始執行。在設置好BOOTSZ0、BOOTSZ1和BOOTRST熔絲位后,需要把BootLoader程序定位并寫入到引導區中,其首地址由熔絲位ROOTSZ0和BOOTSZ1的編程狀態決定。在單片機上電復位后BootLoader程序開始執行,BootLoader程序可以通過USART、TWI或其它方式從計算機或其它數據源讀取應用程序代碼并寫入到應用區中。
avr-libc提供一組C程序接口API來支持BootLoader功能,包含在<avr/boot.h>中,主要幾個宏有:
boot_page_erase ( address ):擦除FLASH指定頁,address是以字節為單位的FLASH地址。
boot_page_fill ( address, data ):填充BootLoader 緩沖頁,address為以字節為單位的緩沖頁地址(對mega8:0~64),而data是長度為兩個字節的字數據,因此調用前address 的增量應為2。此時data的高字節寫入到高地址,低字節寫入到低地址。
boot_page_write ( address ):boot_page_write執行一次的SPM指令,將緩沖頁數據寫入到FLASH指定頁。
boot_rww_enable ( ):RWW區讀使能,根據自編程的同時是否允許讀FLASH存儲器。RWW(Read-While-Write)可同時讀寫區,在對RWW 區自編程即頁寫入或頁擦除時,由硬件鎖定RWW區,RWW區的讀操作被禁止,在對RWW區的編程結束后應當調用boot_rww_enable()使RWW區開放。

三、    驅動程序的流程圖

本應用以實際使用的Mega系列單片機Mega168為例,說明AVR單片機BootLoader的功能應用。BootLoader程序通過串口與計算機進行通信,執行讀、寫以及跳轉到FLASH應用區的操作。單片機與計算機通信使用Xmodem通信協議,Xmodem通信協議見相關文檔。其程序流程如下圖。(可見附件中“流程圖.vsd”文件)


四、    驅動程序的源程序

對應Mega168的BootLoader程序包括bootloader.c和bootloader.h。
源程序清單如下:(可見附件中“bootloader.c”和“bootloader.h”文件)

五、    設計及調試技巧

BootLoader程序不使用中斷,以查詢的方式讀寫UART數據。退出BootLoader程序后程序指針跳轉到應用程序區首地址,如果要重新執行BootLoader程序以加載應用區程序,必須使用硬件復位。

六、    典型問題及解決辦法

在程序升級過程中遇到多個模塊通過485總線連接在一起時,引起多個模塊響應,造成誤擦除,升級不能成功,在硬件及Bootloader程序中設置升級條件,條件滿足時升級模塊程序,否則跳轉到應用程序區。

單片機源程序如下:
  1. #include "bootloader.h"

  2. //串口初始化
  3. void ComInit(void)                                                               
  4. {                                                                                       
  5.         UBRR0H = BAUDREG/256;                                       
  6.         UBRR0L = BAUDREG%256;                                       
  7.         UCSR0A = 0;                                                               
  8.         UCSR0B = (1 << RXEN0)|(1 << TXEN0);               
  9.         UCSR0C = (1 << UCSZ00)|(1 << UCSZ01);       
  10. }

  11. //使用定時器1:產生以毫秒為單位的時間
  12. void TimerInit()                                                      
  13. {                                                                 
  14.         OCR1A  = (unsigned int)(timeclk * (F_CPU  / (1024 * 1000.0f)));
  15.         TCCR1A = 0;                                    
  16.         TCCR1B = (1 << WGM12)|(1 << CS12)|(1 << CS10);
  17. }

  18. //更新一個Flash頁
  19. void write_one_page(unsigned char *buf)
  20. {
  21.         boot_page_erase(FlashAddr);                  
  22.         boot_spm_busy_wait();
  23.         for(pagptr = 0; pagptr < SPM_PAGESIZE; pagptr += 2)
  24.         {
  25.                 boot_page_fill(pagptr, buf[pagptr] + (buf[pagptr + 1] << 8));
  26.         }
  27.         boot_page_write(FlashAddr);                 
  28.         boot_spm_busy_wait();            
  29. }

  30. //跳轉到用戶程序
  31. void quit()
  32. {
  33.         boot_rww_enable();
  34.         (*((void(*)(void))PROG_START))();
  35. }

  36. //寫入數據到串口
  37. void WriteCom(unsigned char dat)
  38. {
  39. #if RS485
  40.         RS485Enable();
  41. #endif

  42.         UDR0 = dat;
  43.         while(!(UCSR0A & (1<<TXC0)));
  44.         UCSR0A |= (1<<TXC0);

  45. #if RS485
  46.         RS485Disable();
  47. #endif
  48. }

  49. //等待串口數據
  50. unsigned char WaitCom()
  51. {
  52.         while(!(UCSR0A & (1<<RXC0)));
  53.         return UDR0;
  54. }

  55. //向串口輸出字符串
  56. void putstr(const char *str)
  57. {
  58.         while(*str)
  59.                 WriteCom(*str++);
  60.         WriteCom(0x0D);
  61.         WriteCom(0x0A);
  62. }

  63. //CRC校驗
  64. void crc16(unsigned char *buf, unsigned char n)
  65. {
  66.         unsigned char j;
  67.         unsigned char i;
  68.         unsigned int crc, t;

  69.         crc = 0;
  70.         for(j = n; j > 0; j--)
  71.         {
  72.             crc = (crc ^ (((unsigned int) *buf) << 8));
  73.                 for(i = 8; i > 0; i--)
  74.                 {
  75.                         t = crc << 1;
  76.                         if(crc & 0x8000)
  77.                                 t = t ^ 0x1021;
  78.                         crc = t;
  79.                 }
  80.                 buf++;
  81.         }
  82.         ch = crc / 256;
  83.         cl = crc % 256;
  84. }

  85. int main(void)
  86. {
  87.         unsigned char cnt;
  88.         unsigned char packNO;
  89.         unsigned char crch, crcl;
  90.         unsigned char li;

  91.         asm volatile("cli": : );

  92.         wdt_enable(WDTO_1S);
  93.         TimerInit();

  94. #if RS485
  95.         DDRREG(RS485PORT) |= (1 << RS485TXEn);
  96.         RS485Disable();
  97. #endif

  98.         ComInit();

  99.         putstr(msg1);

  100.         cnt = TimeOutCnt;
  101.         cl = 0;
  102.         while(1)
  103.         {
  104.                 if(TIFR1 & (1<<OCF1A))   
  105.                 {
  106.                         TIFR1 |= (1 << OCF1A);

  107.                         if(cl == CONNECTCNT)
  108.                                 break;

  109.                         wdt_reset();

  110.                         cnt--;
  111.                         if(cnt == 0)
  112.                         {
  113.                         putstr(msg2);

  114.                                 quit();
  115.                         }
  116.                 }

  117.             if(DataInCom())
  118.             {
  119.                         if(ReadCom() == KEY[cl])
  120.                                 cl++;
  121.                         else
  122.                                 cl = 0;
  123.             }
  124.         }

  125.         putstr(msg3);

  126.         cnt = TimeOutCntC;
  127.         while(1)        
  128.         {
  129.                 if(TIFR1 & (1<<OCF1A))   
  130.                 {
  131.                         TIFR1 |= (1 << OCF1A);
  132.                         WriteCom(XMODEM_RWC) ;

  133.                         wdt_reset();

  134.                         cnt--;
  135.                         if(cnt == 0)
  136.                         {
  137.                         putstr(msg2);
  138.                         quit();
  139.                         }
  140.                 }

  141.                 if(DataInCom())
  142.                 {
  143.                         if(ReadCom() == XMODEM_SOH)
  144.                                 break;
  145.                 }
  146.         }

  147.         TCCR1B = 0;

  148.         packNO = 0;
  149.         bufptr = 0;
  150.         cnt = 0;
  151.         FlashAddr = 0;
  152.         do
  153.         {
  154.                 packNO++;
  155.                 ch =  WaitCom();                     
  156.                 cl = ~WaitCom();
  157.                 if ((packNO == ch) && (packNO == cl))
  158.                 {
  159.                         for(li = 0; li < BUFFERSIZE; li++)     
  160.                         {
  161.                                 buf[bufptr++] = WaitCom();
  162.                         }
  163.                         crch = WaitCom();
  164.                         crcl = WaitCom();
  165.                         crc16(&buf[bufptr - BUFFERSIZE], BUFFERSIZE);
  166.                         if((crch == ch) && (crcl == cl))
  167.                         {
  168.                                 if(FlashAddr < BootStart)            
  169.                                 {
  170.                                         while(bufptr > 0)            
  171.                                         {
  172.                                                 write_one_page(&buf[BUFSIZE - bufptr]);
  173.                                                 FlashAddr += SPM_PAGESIZE;      
  174.                                                 bufptr -= SPM_PAGESIZE;
  175.                                         }
  176.                                 }
  177.                                 else                              
  178.                                 {
  179.                                         bufptr = 0;                        
  180.                                 }

  181.                                 WriteCom(XMODEM_ACK);
  182.                                 cnt = 0;

  183.                                 wdt_reset();

  184.                         }
  185.                         else
  186.                         {
  187.                                 WriteCom(XMODEM_NAK);
  188.                                 cnt++;
  189.                         }
  190.             }
  191. ……………………

  192. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼


所有資料51hei提供下載:

AVR單片機BootLoader功能應用.rar (88 KB, 下載次數: 144)




評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:25103 發表于 2018-8-2 23:17 | 只看該作者
謝謝謝謝分享,頂一個!!
回復

使用道具 舉報

板凳
ID:85043 發表于 2019-3-15 16:26 | 只看該作者
學習學習,
謝謝謝謝分享,頂一個!
回復

使用道具 舉報

地板
ID:455955 發表于 2019-10-31 23:28 | 只看該作者
多謝,多謝!
回復

使用道具 舉報

5#
ID:108023 發表于 2019-11-24 16:07 | 只看該作者
謝謝分享  正需要這個
回復

使用道具 舉報

6#
ID:438099 發表于 2020-2-6 22:12 | 只看該作者
這方面資料比較少,謝謝樓主分享
回復

使用道具 舉報

7#
無效樓層,該帖已經被刪除
8#
ID:738095 發表于 2020-7-3 23:56 | 只看該作者
感謝分享,資料很不錯
回復

使用道具 舉報

9#
ID:413383 發表于 2020-8-6 22:09 | 只看該作者
感謝分享,資料很不錯,以前知道用并口專用編程器,可用ISP, JTAG下載程序,單位有一臺特靈的冷機,有一個溫度傳感器壞了,廠家說不能自已換,要寫編號和代碼,廠家來的人換上新的溫度傳感器,用一永磁塊靠近傳感器,然后用電腦下載程序,后來把壞的傳感器拆開,里面是ATmega8a和485通信模塊,就奇怪ATmega8a怎么能通過RS232串口下載程序呢,后來查資料才知道要先下載BootLoader引導程序,這個還不會用
回復

使用道具 舉報

10#
ID:81138 發表于 2021-1-29 09:30 | 只看該作者
我的Atmega32在Arduino Pro Mini  上無發刷BootLoader引導程序
回復

使用道具 舉報

11#
ID:81138 發表于 2021-1-29 10:49 | 只看該作者
我的ATmega328適用次方法不
回復

使用道具 舉報

12#
無效樓層,該帖已經被刪除
13#
ID:128321 發表于 2024-7-4 14:58 | 只看該作者
我的ATmega328適用次方法不
回復

使用道具 舉報

14#
ID:71233 發表于 2024-7-17 11:02 | 只看該作者
這個不知道是否適合于ATmega 16.
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表