Detailed explanation of Atmega32 Bootloader test program

Publisher:Enchanted2021Latest update time:2020-03-16 Source: eefocusKeywords:Atmega32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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<timeout--;

}

}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<DDRD=(1<GICR = (1<GICR = (0<cli();

UCSRC = (1<UBRRL = (F_CPU/BAUDRATE/16-1)%256; //Set baud rate

UBRRH = (F_CPU/BAUDRATE/16-1)/256;

UCSRA = 0x00;

UCSRB = (1<OCR0 = 28;

TCCR0 = (1<//In CTC mode, the overflow flag is the output compare match OCF0, and the corresponding interrupt is the output compare match interrupt;

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<GICR = (0</* Regardless of whether the BootLoader uses interrupts, migrating the interrupt vector table to the application area header will enhance the robustness of the program*/

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

}


Keywords:Atmega32 Reference address:Detailed explanation of Atmega32 Bootloader test program

Previous article:Design of a simple fire-fighting robot based on ATmega48
Next article:Design of active solar tracking system based on ATmega32 microcontroller

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号