📄 main._c
字号:
/******************************************************************************
Atmega8、16 BootLoad程序
日 期:2004年的最后一天
肖 鹏 www.527dz.com 527dz@527dz.com
/*****************************************************************************/
//修改pei2005.6.24
//1.针对W0和W1的硬件进行修改,主要是使用晶振、修改Baud、关无线模块
//2.增加:用户区无程序时不跳出Boot循环
//3.修正Bug:原GetPageNumber()由于移位的原因,PageAddress!=0xffff,即FlashLoad()无法退出
//4.增加:Page地址比较重要,也要效验
#include <macros.h>
#include "assembly.h"
#define W0
//×××××××××××××××××××××××××××××××××××××××××××××××××××××××××
//请根据目标板选择芯片型号
#ifdef W0
#define ChipType Atmega8
#else
#define ChipType Atmega16
#endif
//#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版本 pei
//#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 Atmega8 0x30
#define Atmega16 0x31
#define Atmega32 0x32
#define Atmega64 0x33
#define Atmega128 0x34
#define Atmega8535 0x35
//*****************************************************************************
//#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
//*****************************************************************************
//11.0592M pei
#define BAU 35 //pei baud19200
//#define BAU 17 //pei baud38400
#if (ChipType == Atmega8)
#include "iom8v.h"
#define PageByte 64
#define AddressShift 6
#endif
#if (ChipType == Atmega16)
#include "iom16v.h"
#define PageByte 128
#define AddressShift 7
#endif
void FlashLoad (void);
void GetPageNumber (void);
void ExecCode (void);
char GetPage (void);
void WriteFlash (void);
char CheckFlash (void);
void SendChar (unsigned char c);
void delay (void); //1ms延时函数
unsigned char RecChar (void);
unsigned char PageBuffer[PageByte];
unsigned int PageAddress;
/*****************************************************************************/
//Flash编程
/*****************************************************************************/
void FlashLoad(void)
{unsigned char AddH,AddL;
SendChar('!');
while (1)
{
//GetPageNumber();//bug!由于移位的原因,PageAddress!=0xffff
//if (PageAddress == 0xffff) return;//退不出了:)
if (GetPage())
{
if (PageAddress == 0xffff) return;//pei Page地址读取和判断加到GetPage()中了
WriteFlash();
if (CheckFlash()) SendChar('!');
else SendChar('@');
}
else SendChar('@');
}
}
/****************************************************************************
void GetPageNumber(void)
{
unsigned char PageAddressH;
unsigned char PageAddressL;
PageAddressH = RecChar();
PageAddressL = RecChar();
PageAddress=((int)((PageAddressH << 8) + PageAddressL))<<AddressShift;
}
/*****************************************************************************/
char GetPage(void)
{
unsigned char i,AddH,AddL;
unsigned char LocalCheckSum = 0;
unsigned char CheckSum = 0;
AddH=RecChar();AddL=RecChar();
PageAddress=(AddH<<8)+AddL;
if (PageAddress==0xffff) return 1;//exit..
PageAddress=PageAddress<<AddressShift;
LocalCheckSum=AddH+AddL;//考虑Page的效验
for (i=0;i<PageByte;i++)
{
PageBuffer[i]=RecChar();
LocalCheckSum += PageBuffer[i];
}
CheckSum = RecChar();
if (LocalCheckSum == CheckSum) return 1;
else return 0;
}
/*****************************************************************************/
void WriteFlash(void)
{
unsigned int i;
unsigned int TempInt;
for (i=0;i<PageByte;i+=2)
{
TempInt=PageBuffer[i]+(PageBuffer[i+1]<<8);
fill_temp_buffer(TempInt,i); //call asm routine.
}
write_page(PageAddress,0x03); //擦除页
write_page(PageAddress,0x05); //写页数据
enableRWW();
}
/*****************************************************************************/
char CheckFlash(void)
{
unsigned char i;
unsigned int TempInt;
unsigned int TempInt2;
for (i=0;i<PageByte;i+=2)
{
TempInt = read_program_memory(PageAddress + i,0x00);
TempInt2 = PageBuffer[i] +(PageBuffer[i+1]<<8);
if (TempInt != TempInt2) return 0;
}
return 1;
}
/*****************************************************************************/
/* 字符输入函数 */
unsigned char RecChar(void)
{
while(!(UCSRA & 0x80));
return UDR;
}
/*****************************************************************************/
void SendChar(unsigned char c)
{
while (!(UCSRA&(1<<UDRE)));
UDR=c;
}
void delay(void)
{
unsigned int i;
for (i=0;i<65530;i++);
}
/*****************************************************************************/
void ExecCode(void)
{
GICR=0X01; //中断向量表移位允许
GICR=0X00; //中断向量指向应用程序区
asm("jmp 0x0000");
}
void main(void)
{
unsigned char BootFlag;
unsigned int TempInt;
char iTry;
#ifdef InteClk //如果使用内部时钟,读取时钟校准值
OSCCAL=read_flash(OscAddress);
#endif
#ifdef W0
//pei 拷贝W0的PortInit
PORTB = 0x0F;//rfslp,fs123=1
DDRB = 0xFF;//bit1=output
PORTC = 0x21;//0x20;//rfrst=1,not reset!
DDRC = 0x7F;
PORTD = 0x0C;
DDRD = 0xF0;
#else
#endif
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位停止
UCSRB = (1<<RXEN)|(1<<TXEN); //允许串口发送和接收
UBRR = BAU;
iTry=20;
STARTBOOT://pei未下载程序时重复等待
#ifdef W0
PORTC=PORTC^0x03;
#endif
SendChar('>'); //通知PC机,BOOT下载准备就绪
delay(); //延时等待PC机响应
BootFlag=UDR;
if (BootFlag == '<')
{
SendChar(ChipType);
SendChar(BootSize);
SendChar(BootVer);
while (1)
{
switch (RecChar())
{
case 'W': FlashLoad();
break;
case 'E': {
SendChar('E'); //通知PC机,进入运用程序区
ExecCode();
} break;
default : break;
}
}
}
SendChar('E'); //通知PC机,进入运用程序区
TempInt = read_program_memory(0,0);//pei
if (TempInt==0xFFFF) goto STARTBOOT;
else{ iTry--;
if (iTry>0) goto STARTBOOT;}
ExecCode();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -