assembly.s
.text
SPMCR = 0x57 ; RWW area busy flag, read RWW area allowed, allow write program storage area
; void write_page (unsigned int adr, unsigned char function);
; bits 8:15 adr addresses the page...(must setup RAMPZ beforehand!!!)
_write_page::
XCALL __WAIT_SPMEN__
movw r30, r16 ;move address to z pointer (R31 = ZH, R30 = ZL)
STS SPMCR, R18 ;argument 2 decides function
SPM ;perform pagewrite
RET
;-----------------------------------------
; void fill_temp_buffer (unsigned int data, unsigned int adr);
; bits 7:1 in adr addresses the word in the page... (2=first word, 4=second word etc..)
_fill_temp_buffer::
XCALL __WAIT_SPMEN__
movw r30, r18 ;move adress to z pointer (R31=ZH R30=ZL)
movw r0, r16 ;move data to reg 0 and 1
LDI R19, 0x01
STS SPMCR, R19
SPM ;Store program memory
RET
;-----------------------------------------
;unsigned char read_flash(unsigned int add);
_read_flash::
mov r31,r17
mov r30,r16
lpm r16,z
clr r17
ret
;unsigned int read_program_memory (unsigned int adr ,unsigned char cmd);
_read_program_memory::
movw r30, r16 ;move adress to z pointer
SBRC R18, 0 ;read lockbits? (second argument = 0x09)
STS SPMCR, R18 ;if so, place second argument in SPMEN register
LPM r16, Z+
LPM r17, Z
RET
;-----------------------------------------
_enableRWW::
XCALL __WAIT_SPMEN__
LDI R27,0x11
STS SPMCR,R27
SPM
RET
;-----------------------------------------
__WAIT_SPMEN__:
LDS R27,SPMCR ; load SPMCR to R27
SBRC R27,0 ; check SPMEN flag
RJMP __WAIT_SPMEN__ ; wait for SPMEN flag cleared
RET
;-----------------------------------------
assembly.h
void write_page (unsigned int adr, unsigned char function);
void fill_temp_buffer (unsigned int data,unsigned int adr);
unsigned int read_program_memory (unsigned int adr,unsigned char cmd);
//void write_lock_bits (unsigned char val);
void enableRWW(void);
unsigned char read_flash(unsigned int add);
main.c
/******************************************************************************
Atmega16 BootLoader program
date: the last day of 2004
/****************************************************************************/ //×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× #define Atmega16 0x31 //******************************************************************************** //Baud rate setting under 16M clock //EEPROM used #if (ChipType == Atmega16) void FlashLoad(void); #define BUFLEN 200 //Read EEPROM function //Read EEPROM function #if 0 unsigned char ucPageDateSuccessFlag=0; return; if (ucPageDateSuccessFlag==1)//Get a page of correct data //SendChar('%'); /*****************************************************************************/ for(j=0;j<100;j++) static unsigned int GetCRC16Code(unsigned char* pCalcBuf, unsigned char ucSize) for(i=0;i<200;i++) //LocalCheckSum=GetCRC16Code(PageBuffer, PageByte); BE(); return 2; return 0; /*****************************************************************************/ //TempInt=PageBuffer[i]+(PageBuffer[i+1]<<8); //The program is written by 'word', one page is 128 bytes, 64 words fill_temp_buffer(TempInt,i); //call asm routine. See assembly code, store a page of data //BE(); return 0;
#include
#include
#include "assembly.h"//Include assembly code header file
//Please select the chip model according to the target board
//#define ChipType Atmega8
#define ChipType Atmega16
//#define ChipType Atmega32
//#define ChipType Atmega64
//#define ChipType Atmega128
//#define ChipType Atmega8535
//*************************************************************
//Select the BOOT area size
//#define BootSize 'a' //128
//#define BootSize 'b' //256
//#define BootSize 'c' //512
//#define BootSize 'd' //1024
//#define BootSize 'e' //2048 (Not sure if there is a chip with 2048 words of BOOT space)
//Select BootLoad version number
//#define BootVer 'f' //Version 1.0
//#define BootVer 'g' //Version 1.1
//#define BootVer 'h' //Version 1.2
//#define BootVer 'i' //Version 1.3
//#define BootVer 'j' //Version 1.4
//#define BootVer 'k' //Version 1.5
//#define BootVer 'l' //Version 1.6
//#define BootVer 'm' //Version 1.7
//#define BootVer 'n' //Version 1.8
//#define BootVer 'o' //Version 1.9
//#define BootVer 'p' //Version 2.0 (should be the final version)
//**************************************************************
//#define InteClk //Whether to use the internal clock
//#define OscAddress 0x1fff //Clock calibration value storage address
//#define OscAddress 0x3fff //Clock calibration value storage address
//********************************************************************************
//Baud rate setting under 8 clocks
//#define BAU 103 //4800
//#define BAU 51 //9600
//#define BAU 34 //14400
//#define BAU 25 //19200
#define BAU 103 //9600
#define EEPROM_UPDATE_0X00_0X06 7
#define EEPROM_REPEAT_ENTER_BOOT_TIMES 0x07
#define EEPROM_DEBUG0 0x08
#define EEPROM_DEBUG1 0x09
#define ERASE_FLASH_PAGE_NUM 112 //Erase page number
const unsigned char ucEepromWriteSuccess[EEPROM_UPDATE_0X00_0X06]={"success"};
const unsigned char ucEepromWriteUpdates[EEPROM_UPDATE_0X00_0X06]={"updates"};
//*****************************************************************************
#include "iom16v.h"
#define PageByte 128
#define AddressShift 7
#endif
unsigned char GetPageNumber(void);
void ExecCode(void);
char GetOnePageData(void);
unsigned char WriteFlash(void);
char CheckFlash(void);
void SendChar(unsigned char c);
void delay(void); //1ms延时函数
//unsigned char RecChar(void);
static unsigned int GetCRC16Code(unsigned char* pCalcBuf, unsigned char ucSize);
//unsigned char PageBuffer[PageByte+2];
unsigned int PageAddress=0;
char uRxData;
char ucRecvBuf[BUFLEN];
unsigned int uiBufLen=0;
unsigned int uiStartBufDateLen=0;
static void EEPROM_Write(unsigned int Add,unsigned char Data)
{
if(Add<512) //If the address is greater than 512, invalid
{
while(EECR&BIT(EEWE)); //Check whether the last EEPROM write operation is completed
EEAR=Add; //Write address
EEDR=Data; //Write data
EECR|=BIT(EEMWE); //EEPROM write host enable: prepare
EECR|=BIT(EEWE); //EEPROM write enable: write
}
}
static unsigned char EEPROM_Read(unsigned int Add)
{
unsigned char Temp=0;
if(Add<512) //If the address is greater than 512, read 0 value
{
while(EECR&BIT(EEWE)); //Check whether the last EEPROM write operation is completed
EEAR=Add; //Write address
EECR|=BIT(EERE); //EEPROM read enable: read out
Temp=EEDR; //Read data
}
return Temp; //Return data
}
void PrintfStringToArm(char * str)
{
int i=0;
for(i=0;i
SendChar(*(str+i));
}
}
#endif
/*****************************************************************************/
//Flash编程
/*****************************************************************************/
void FlashLoad(void)
{
unsigned int i;
SendChar('!');
while (1)
{
if(!GetPageNumber())//Get page address
{
return;
}
else
{
if (PageAddress == 0xff80)//Write completed
{
SendChar('$');
CLI();
for(i=0;i
EEPROM_Write(i,ucEepromWriteSuccess[i]);
}
SEI();
}
ucPageDateSuccessFlag=GetOnePageData();
{
if(WriteFlash())
{
if (CheckFlash())
SendChar('!');
else
SendChar('@');
}
else
{
return;
}
}
else if(ucPageDateSuccessFlag==2)//Get a page of incorrect data
{
SendChar('@');
}
else//Timeout
{
return;
}
}
}
}
unsigned char GetPageNumber(void)
{
unsigned int i;
unsigned char j;
unsigned int uiAddress;
{
for(i=0; (i+4)<=uiBufLen; i++)
{
if(memcmp(ucRecvBuf+i,"##",2)==0)//"##" is followed by the page address
{
memcpy(&uiAddress,ucRecvBuf+i+2,2);
PageAddress=(uiAddress<
return 1;
}
}
delay();
}
return 0;
}
{
unsigned char i = 0;
unsigned char j = 0;
unsigned int usReturnValue = 0xFFFF;
unsigned int usNew = 0xA001;
for (i=0; i
usReturnValue ^= pCalcBuf[i];
for(j=0; j<8; ++j)
{
if(usReturnValue & 0x0001)
{
usReturnValue >>= 1;
usReturnValue ^= usNew;
}
else
{
usReturnValue >>= 1;
}
}
}
return usReturnValue;
}
/*****************************************************************************/
char GetOnePageData(void)
{
unsigned char i;
unsigned int LocalCheckSum = 0;
unsigned int CheckSum = 0;
{
if(uiBufLen>=(uiStartBufDateLen+PageByte+2))
{
//for(i=0;i<(PageByte+2);i++)
//{
// PageBuffer[i]=ucRecvBuf[i+uiStartBufDateLen];
//}
LocalCheckSum=GetCRC16Code(&ucRecvBuf[uiStartBufDateLen-2], PageByte+2);//Check the page address as well, a total of PageByte+2 bytes.//memcpy(&CheckSum,&PageBuffer[PageByte],2)
;
memcpy(&CheckSum,&ucRecvBuf[uiStartBufDateLen+PageByte],2);
if (LocalCheckSum == CheckSum)
{
return 1;
}
else
{
CLI();
memset(ucRecvBuf,0,BUFLEN);
uiBufLen=0;
}
}
delay();
}
}
unsigned char WriteFlash(void)
{
unsigned int i;
unsigned int TempInt;
for (i=0;i
TempInt=ucRecvBuf[uiStartBufDateLen+i]+(ucRecvBuf[uiStartBufDateLen+i+1]<<8);
}
if(PageAddress==0x0000)
{
if(ucRecvBuf[uiStartBufDateLen]==0xFF)
{
//CLI();
//EEPROM_Write(EEPROM_DEBUG1,0xD1);
}
else //Erase data, when it is the first page, consistently erase all data from pages 0-103
{
for(;PageAddress
write_page(PageAddress,0x03); //0x03,Bit1=1,page erase,Bit0=1,stored program memory enable (SPMEN)
}
PageAddress=0x0000;
}
}
else if(PageAddress==0x3700) //When it is the first page address of page 110, consistently erase data from pages 110-111
{
for(;PageAddress<0x3800;PageAddress+=128)
{
write_page(PageAddress,0x03); //0x03,Bit1=1,page erase,Bit0=1,stored program memory enable (SPMEN)
}
PageAddress=0x3700;
}
Previous article:ADC acquisition digital tube display simulation program based on AVR microcontroller Atmega16
Next article:AVR series keyboard scanning
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
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
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Brief Analysis of Automotive Ethernet Test Content and Test Methods
- How haptic technology can enhance driving safety
- CCS3.3
- Request the schematic diagram of this system board
- How many Gs is the AT in the PULLin VALUE of the reed switch?
- July 9 live broadcast review: Enjoy the purity - AMS active noise reduction and proximity sensing bring a new level of headphone design (including video, ppt)
- ADI chips have increased by NNN times?
- How to improve the anti-interference ability of wireless modules
- [Zero-knowledge ESP8266 tutorial] WIFI TCP protocol communication TCP server example
- What is RFID technology?
- RISCV DMIPS0.8, 80Mhz soft core open source CPU implementation in FPGA
- [Synopsys IP Resources] 97% of tested applications have security vulnerabilities. Is your software secure?