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();
上一篇:基于AVR单片机Atmega16的ADC采集数码管显示仿真程序
下一篇:AVR系列之键盘扫描
推荐阅读最新更新时间:2024-11-09 21:32
设计资源 培训 开发板 精华推荐
- LTC3621IMS8E-23.3 1.2Vout、强制连续模式、1MHz 同步降压稳压器的典型应用
- LTC3642IDD-3.3 5V、50mA 降压转换器的典型应用电路
- LT1171HVIQ 的典型应用,2.5A 外部电流限制
- DN05061/D,通用交流输入,5 伏输出,10 瓦电源设计说明
- #第四届立创大赛#智能空调控制器
- OM13531: SA606DK评估演示板
- ADA4075-2ARZ 低功耗运算放大器的典型 DAC 输出滤波器电路(差分)
- LT1512 的典型应用 - SEPIC 恒流/恒压电池充电器
- LTC1760CFW 演示板,VIN=12V 至 20V,V OUT1 =4A
- DC9003A-C,基于 LTC5800 的 SmartMesh WirelessHART 评估/开发节点