Bootloader program of Atmega32, below is the source code.
The fuse bits need to be configured when in use:
1. Program BOOTSZ0, BOOTSZ1 and BOOTRST, then download the hex of BOOTLOADER to the MCU through the downloader, and it will run from BOOTLOADER after restart.
2. Note that this example uses the internal 8MHz and 9600 baud rate.
3. After startup, you can see:
Then press the 'D' key to enter the Bootloader and wait for downloading.
#include #include #include #include #include //IO definition #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; //starting byte unsigned char BlockNo; //data block number unsigned char nBlockNo; //data block number inverse code unsigned char Xdata[128]; //128 bytes of data unsigned char CRC16hi; //CRC16 checksum high bit unsigned char CRC16lo; //CRC16 check data low bit } strXMODEM; unsigned long FlashAddress; //FLASH地址 #define BootAdd 0x7000 //The first address of the Boot area (the highest address of the application area) unsigned char BlockCount; //Data block accumulation (only 8 bits, no need to consider overflow) unsigned char STATUS; //operating status #define ST_WAIT_START 0x00 //Wait for start #define ST_BLOCK_OK 0x01 //Receive a data block successfully #define ST_BLOCK_FAIL 0x02 //Failed to receive a data block #define ST_OK 0x03 //Completed #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) //Send using query method { 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); //Send carriage return and line feed at the end } unsigned char get_data(unsigned char *ptr,unsigned char len,unsigned int timeout) { unsigned count=0; do { if (UCSRA & (1< *ptr++ = UDR; //If data is received, read it out 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); //Time limit 3 seconds, receive a data if ((c=='d')||(c=='D')) { STATUS = ST_WAIT_START; // and data = 'd' or 'D', enter XMODEM put_s("Please use xmodem transmit the *.bin file."); } else { STATUS=ST_OK; //Exit Bootloader program } FlashAddress=0x0000; BlockCount=0x01; while(STATUS!=ST_OK) { if (STATUS==ST_WAIT_START) {//XMODEM is not started put_c(XMODEM_WAIT_CHAR); //Send request XMODEM_WAIT_CHAR } i=get_data(&strXMODEM.SOH,133,1000); if(i) { //Analyze the first data of the data packet SOH/EOT/CAN switch(strXMODEM.SOH) { case XMODEM_SOH: //Receive the start character SOH if (i>=133) { STATUS=ST_BLOCK_OK; } else { STATUS=ST_BLOCK_FAIL; //If the data is insufficient, request to resend the current data block put_c(XMODEM_NAK); } break; case XMODEM_EOT: //Receive the end character EOT put_c(XMODEM_ACK); //Notify PC that all received STATUS=ST_OK; put_s("Updata the programme success."); break; case XMODEM_CAN: //Receive cancel symbol CAN put_c(XMODEM_ACK); //respond to PC STATUS=ST_OK; put_s("Warning! It canceled by user to updata the programme."); break; default: //Starting byte error put_c(XMODEM_NAK); //Request to resend the current data block STATUS=ST_BLOCK_FAIL; break; } } if (STATUS==ST_BLOCK_OK) //Receive 133 bytes OK, and the start byte is correct { if (BlockCount != strXMODEM.BlockNo) // Check that the data block number is correct { put_c(XMODEM_NAK); //Data block number error, request to resend the current data block 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 error, request to resend the current data block continue; } //Correctly receive 128 bytes of data, which is exactly one page of M16 if (FlashAddress<(BootAdd-SPM_PAGESIZE)) { //If the address is in the application area write_one_page(); //Write the received 128 bytes into one page of Flash FlashAddress+=SPM_PAGESIZE; //Flash页加1 } else { put_c(XMODEM_CAN); //Program is full, cancel transmission 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); //Response that a data block has been received correctly BlockCount++; //Data blocks add 1 } } put_s("LET'S GO!"); loop_until_bit_is_set(UCSRA,UDRE); //Wait for the end prompt message to be sent back GICR = (1< boot_rww_enable (); //RWW area read permission, otherwise the user's application program cannot be executed immediately asm volatile("jmp 0x0000"); //Jump to Flash at 0x0000 and execute the user's application }
Previous article:Design of a simple fire-fighting robot based on ATmega48
Next article:Design of active solar tracking system based on ATmega32 microcontroller
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- c6678 sys/bios add hwi interrupt does not trigger, send successfully in bare metal case
- NUCLEO_G431RB review->File structure & ST-Link online debugging experience
- Sugar Glider ⑤ Sugar Glider Health Monitoring System Based on RSL10--Project Introduction
- Problems with using the bq28z610EVM development board
- How to create a transcoding table using HZK16 font in micropython?
- 【TI recommended course】#What is I2C design tool? #
- Digital Input Closed-Loop Class-D Audio Amplifier Evaluation Module
- Come and recommend a book!!! April is a great time to read when the flowers are blooming and the grass is green!
- [GD32L233C-START Review] 4. USART uses idle interrupts and DMA to receive data of variable length
- How to convert orcad library into pads library?