历史上的今天
今天是:2025年03月16日(星期日)
2020年03月16日 | Atmega32 Bootloader测试程序详解
2020-03-16 来源:eefocus
Atmega32的Bootloader程序,下面是源码。
在使用时需要将熔丝位进行配置:
1.编程BOOTSZ0、BOOTSZ1和BOOTRST三处,然后通过下载器将BOOTLOADER的hex下载到单片机中,重启后就从BOOTLOADER处运行了。
2.注意本例子使用的是内部8MHz和9600的波特率。
3.启动后可以看到:

然后按下‘D’键进入Bootloader等待下载。
#include #include #include #include #include //IO定義 #define PIN_RXD 0 //PD0 #define PIN_TXD 1 //PD1 //常數定義 #define SPM_PAGESIZE 128 #define DATA_BUFFER_SIZE SPM_PAGESIZE #define BAUDRATE 9600 #undef F_CPU #define F_CPU 8000000 //定義xmodem控制字符 #define XMODEM_NUL 0x00 #define XMODEM_SOH 0x01 #define XMODEM_STX 0x02 #define XMODEM_EOT 0x04 #define XMODEM_ACK 0x06 #define XMODEM_NAK 0x15 #define XMODEM_CAN 0x18 #define XMODEM_EOF 0x1A #define XMODEM_WAIT_CHAR 'C' struct str_XMODEM { unsigned char SOH; //起始字节 unsigned char BlockNo; //数据块编号 unsigned char nBlockNo; //数据块编号反码 unsigned char Xdata[128]; //数据128字节 unsigned char CRC16hi; //CRC16校验数据高位 unsigned char CRC16lo; //CRC16校验数据低位 } strXMODEM; unsigned long FlashAddress; //FLASH地址 #define BootAdd 0x7000 //Boot区的首地址(应用区的最高地址) unsigned char BlockCount; //数据块累计(仅8位,无须考虑溢出) unsigned char STATUS; //运行状态 #define ST_WAIT_START 0x00 //等待启动 #define ST_BLOCK_OK 0x01 //接收一个数据块成功 #define ST_BLOCK_FAIL 0x02 //接收一个数据块失败 #define ST_OK 0x03 //完成 #define PROG_START 0x0000 //延時 void delay_ms(unsigned int t) { while(t--) { _delay_ms(1); } } void write_one_page(void) { unsigned char i; unsigned char *buf; unsigned int w; boot_page_erase(FlashAddress); boot_spm_busy_wait(); buf=&strXMODEM.Xdata[0]; for(i=0;i w=*buf++; w+=(*buf++)<<8; boot_page_fill(i,w); } boot_page_write(FlashAddress); boot_spm_busy_wait(); } void put_c(unsigned char c) //发送采用查询方式 { loop_until_bit_is_set(UCSRA,UDRE); UDR=c; } void put_s(unsigned char *ptr) { while (*ptr) { put_c(*ptr++); } put_c(0x0D); put_c(0x0A); //结尾发送回车换行 } unsigned char get_data(unsigned char *ptr,unsigned char len,unsigned int timeout) { unsigned count=0; do { if (UCSRA & (1< *ptr++ = UDR; //如果接收到数据,读出 count++; if (count>=len) { break; // } } if(TIFR & (1< TIFR|=(1< } }while (timeout); return count; } unsigned int calcrc(unsigned char *ptr, unsigned char count) { unsigned int crc = 0; while (count--) { crc =_crc_xmodem_update(crc,*ptr++); } return crc; } int main(void) { unsigned char c = 0; unsigned char i; unsigned int crc; WDTCR &= ~(1< UCSRC = (1< UBRRH = (F_CPU/BAUDRATE/16-1)/256; UCSRA = 0x00; UCSRB = (1< TCCR0 = (1< put_c(0x0c); put_c(0x0c); put_c(0x0c); //超級終端清屏 put_s("User want updata the programme,please touch [d]rnOtherwise the MCU run the old programme.rn"); get_data(&c,1,3000); //限时3秒,接收一个数据 if ((c=='d')||(c=='D')) { STATUS=ST_WAIT_START; //并且数据='d'或'D',进入XMODEM put_s("Please use xmodem transmit the *.bin file."); } else { STATUS=ST_OK; //退出Bootloader程序 } FlashAddress=0x0000; BlockCount=0x01; while(STATUS!=ST_OK) { if (STATUS==ST_WAIT_START) {//XMODEM未启动 put_c(XMODEM_WAIT_CHAR); //发送请求XMODEM_WAIT_CHAR } i=get_data(&strXMODEM.SOH,133,1000); if(i) { //分析数据包的第一个数据 SOH/EOT/CAN switch(strXMODEM.SOH) { case XMODEM_SOH: //收到开始符SOH if (i>=133) { STATUS=ST_BLOCK_OK; } else { STATUS=ST_BLOCK_FAIL; //如果数据不足,要求重发当前数据块 put_c(XMODEM_NAK); } break; case XMODEM_EOT: //收到结束符EOT put_c(XMODEM_ACK); //通知PC机全部收到 STATUS=ST_OK; put_s("Updata the programme success."); break; case XMODEM_CAN: //收到取消符CAN put_c(XMODEM_ACK); //回应PC机 STATUS=ST_OK; put_s("Warning! It canceled by user to updata the programme."); break; default: //起始字节错误 put_c(XMODEM_NAK); //要求重发当前数据块 STATUS=ST_BLOCK_FAIL; break; } } if (STATUS==ST_BLOCK_OK) //接收133字节OK,且起始字节正确 { if (BlockCount != strXMODEM.BlockNo)//核对数据块编号正确 { put_c(XMODEM_NAK); //数据块编号错误,要求重发当前数据块 continue; } if (BlockCount !=(unsigned char)(~strXMODEM.nBlockNo)) { put_c(XMODEM_NAK); continue; } crc=strXMODEM.CRC16hi<<8; crc+=strXMODEM.CRC16lo; if(calcrc(&strXMODEM.Xdata[0],128)!=crc) { put_c(XMODEM_NAK); //CRC错误,要求重发当前数据块 continue; } //正确接收128个字节数据,刚好是M16的一页 if (FlashAddress<(BootAdd-SPM_PAGESIZE)) { //如果地址在应用区内 write_one_page(); //将收到128字节写入一页Flash中 FlashAddress+=SPM_PAGESIZE; //Flash页加1 } else { put_c(XMODEM_CAN); //程序已满,取消传送 put_c(XMODEM_CAN); put_c(XMODEM_CAN); STATUS=ST_OK; put_s("The programme is out of the flash,cancle transmitted. "); break; } put_c(XMODEM_ACK); //回应已正确收到一个数据块 BlockCount++; //数据块累计加1 } } put_s("LET'S GO!"); loop_until_bit_is_set(UCSRA,UDRE); //等待结束提示信息回送完成 GICR = (1< boot_rww_enable (); //RWW区读允许,否则无法马上执行用户的应用程序 asm volatile("jmp 0x0000"); //跳转到Flash的0x0000处,执行用户的应用程序 }
史海拾趣
|
上拉电阻和下拉电阻的选择应结合开关管特性和下级电路的输入特性进行设定,主要需要考虑以下几个因素:1. 驱动能力与功耗的平衡。以上拉电阻为例,一般地说,上拉电阻越小,驱动能力越强,但功耗越大,设计是应注意两者之间的均衡。2. 下级电路的 ...… 查看全部问答> |
|
问题一: 如下是服务器端的部分程序,accept成功后,客户端给服务器端发送两次消息,分别为\"01\",\"02\". 发现:如果把szText[]的大小改为3,则只能成功接受一次数据,改成16就能接受两次。 ...… 查看全部问答> |
|
紧急求助专家帮忙。本人大四毕业设计,做DSP的SPWM技术实现。用的是2407的芯片,要求仿真出波形图,并且还要进行算法的计算和改进,提出优化,对误差进行分析,并对死区控制进行分析。 本人现在急求 2407的SPWM C语言的程序,并且最好给张仿真的波 ...… 查看全部问答> |
|
各位硬件达人,我现在是研一,现在面临选向的问题,本科是自动化(并非电气自动化,就是传说中的“万金油”的那个自动化专业),研究生我没有报双控,报的是模式识别与智能系统(我是在研究所读研,报那个不重要,关键是自己选向)。师哥建议我搞电 ...… 查看全部问答> |
|
谁有LM3S8962的SD读写程序,发上来个研究一下我这边的stellarisware光盘里面的SD卡程序用不了,谁有个能用的,给个!谢谢… 查看全部问答> |




