assembly.s
.text
SPMCR = 0x57 ;RWW区忙标志,读RWW区允许,允许写程序存储区
; 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 BootLoad程序
日 期:2004年的最后一天
/*****************************************************************************/ //××××××××××××××××××××××××××××××××××××××××××××××××××××××××× #define Atmega16 0x31 //***************************************************************************** //16M时钟下的波特率设置 //使用的EEPROM #if (ChipType == Atmega16) void FlashLoad(void); #define BUFLEN 200 //读EEPROM函数 //读EEPROM函数 #if 0 unsigned char ucPageDateSuccessFlag=0;
#include
#include
#include "assembly.h"//包含汇编代码头文件
//请根据目标板选择芯片型号
//#define ChipType Atmega8
#define ChipType Atmega16
//#define ChipType Atmega32
//#define ChipType Atmega64
//#define ChipType Atmega128
//#define ChipType Atmega8535
//*********************************************************
//选择BOOT区大小
//#define BootSize 'a' //128
//#define BootSize 'b' //256
//#define BootSize 'c' //512
//#define BootSize 'd' //1024
//#define BootSize 'e' //2048(不知道是否有2048字BOOT空间的芯片)
//选择BootLoad版本号
//#define BootVer 'f' //1.0版本
//#define BootVer 'g' //1.1版本
//#define BootVer 'h' //1.2版本
//#define BootVer 'i' //1.3版本
//#define BootVer 'j' //1.4版本
//#define BootVer 'k' //1.5版本
//#define BootVer 'l' //1.6版本
//#define BootVer 'm' //1.7版本
//#define BootVer 'n' //1.8版本
//#define BootVer 'o' //1.9版本
//#define BootVer 'p' //2.0版本(应该是最终版本了)
//**********************************************************
//#define InteClk //是否使用内部时钟
//#define OscAddress 0x1fff //时钟校准值存储地址
//#define OscAddress 0x3fff //时钟校准值存储地址
//*****************************************************************************
//8时钟下的波特率设置
//#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//擦除页数
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) //如果地址大于512,无效
{
while(EECR&BIT(EEWE)); //查询上一次EEPROM写操作是否完成
EEAR=Add; //写入地址
EEDR=Data; //写入数据
EECR|=BIT(EEMWE); //EEPROM写主机使能:准备
EECR|=BIT(EEWE); //EEPROM写使能:写入
}
}
static unsigned char EEPROM_Read(unsigned int Add)
{
unsigned char Temp=0;
if(Add<512) //如果地址大于512,读取0值
{
while(EECR&BIT(EEWE)); //查询上一次EEPROM写操作是否完成
EEAR=Add; //写入地址
EECR|=BIT(EERE); //EEPROM读使能:读出
Temp=EEDR; //读取数据
}
return Temp; //返回数据
}
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())//获取页地址
{
return;
}
else
{
if (PageAddress == 0xff80)//写结束
{
SendChar('$');
CLI();
for(i=0;i
EEPROM_Write(i,ucEepromWriteSuccess[i]);
}
SEI();
设计资源 培训 开发板 精华推荐
- LTC1864、250 ksps、16 位微功率 ADC 提供了尺寸、功率和速度的出色组合
- 用于低待机功耗离线 SMPS 的 NCP1012 自供电单片开关的典型应用
- USB3.0高速集线器,1转4
- SC122低压同步升压转换器的典型应用
- CN0104
- EVB-LAN9500A-MII、LAN9500A 高速 USB 2.0 转 10/100 以太网客户评估板 MII 接口
- OP184FSZ-REEL 缓冲网络补偿容性负载的典型应用
- LT1021CCN8-10 精密 DAC 电压基准的典型应用
- NCP6151A 双输出 4 相 +1/0 相控制器的典型应用,具有单 SVID 接口,适用于台式机和笔记本 CPU 应用
- MPC86XADS、MPC8xx 参考板,基于 MPC857T MPU PowerQUICC MPC8xx 处理器