avr bootloader 源码

发布者:光明2599最新更新时间:2021-06-18 来源: eefocus关键字:avr  bootloader  源码 手机看文章 扫描二维码
随时随地手机看文章

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年的最后一天

/*****************************************************************************/
#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  Atmega16       0x31

//*****************************************************************************
//#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

//16M时钟下的波特率设置
#define  BAU  103   //9600

//使用的EEPROM
#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"};


//*****************************************************************************

#if (ChipType == Atmega16)
  #include  "iom16v.h"
  #define   PageByte     128   
  #define   AddressShift   7
#endif

void FlashLoad(void);
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;

#define BUFLEN 200
char uRxData;
char ucRecvBuf[BUFLEN];
unsigned int uiBufLen=0;
unsigned int uiStartBufDateLen=0;


//读EEPROM函数
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写使能:写入
 }
}

//读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;    //返回数据
}

#if 0
void PrintfStringToArm(char * str)
{
 int i=0;
 for(i=0;i {
  SendChar(*(str+i));
 }
}
#endif


/*****************************************************************************/
//Flash编程                            
/*****************************************************************************/
void FlashLoad(void)
{
 unsigned int i;

 unsigned char ucPageDateSuccessFlag=0;
 SendChar('!');
 while (1)
 {
  if(!GetPageNumber())//获取页地址
  {
   return;
  }
  else
  {
   if (PageAddress == 0xff80)//写结束
   {
    SendChar('$');
    CLI();
    
    for(i=0;i    {
     EEPROM_Write(i,ucEepromWriteSuccess[i]);
    }
    SEI();

[1] [2] [3]
关键字:avr  bootloader  源码 引用地址:avr bootloader 源码

上一篇:基于AVR单片机Atmega16的ADC采集数码管显示仿真程序
下一篇:AVR系列之键盘扫描

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved