📄 main.c.bak
字号:
/******************************************************************************
Atmega系列单片机 BootLoad程序
日 期:2005年4月
冯建辉:www.mcu8.cn mcu8@tom.com
(说明:本程序是基于www.527dz.com站的程序修改而成,程序框架保持原来风格,只是在
通信协议及程序编程机制上作了一定的修改,以满足于上位机软件的配合)
/*****************************************************************************/
#include <macros.h>
#include "assembly.h"
//×××××××××××××××××××××××××××××××××××××××××××××××××××××××××
#define fosc 8000000 //晶振频率
#define baud1 38400 //波特率
//请根据目标板选择芯片型号
//#define ChipType Atmega8
//#define ChipType Atmega16
//#define ChipType Atmega32
//#define ChipType Atmega64
#define ChipType Atmega128
//#define ChipType Atmega8515
//#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 Atmega8 0x30
#define Atmega16 0x31
#define Atmega32 0x32
#define Atmega64 0x33
#define Atmega128 0x34
#define Atmega8515 0x35
#define Atmega8535 0x36
//*****************************************************************************
#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
//*****************************************************************************
#if (ChipType == Atmega8)
#include "iom8v.h"
#define PageByte 64
#define AddressShift 6
#define INTVECREG GICR
#endif
#if (ChipType == Atmega16)
#include "iom16v.h"
#define PageByte 128
#define AddressShift 7
#define INTVECREG GICR
#endif
#if (ChipType == Atmega32)
#include "iom32v.h"
#define PageByte 128
#define AddressShift 7
#define INTVECREG GICR
#endif
#if (ChipType == Atmega64)
#include "iom64v.h"
#define PageByte 256
#define AddressShift 8
#define INTVECREG MCUCR
#endif
#if (ChipType == Atmega128)
#include "iom128v.h"
#define PageByte 256
#define AddressShift 8
#define INTVECREG MCUCR
#define RAMPZ_FLAG
#endif
#if (ChipType == Atmega8515)
#include "iom8515v.h"
#define PageByte 64
#define AddressShift 6
#define INTVECREG GICR
#endif
void FlashLoad (void);
void GetPageNumber (void);
void ExecCode (void);
char GetPage (void);
void WriteFlash (void);
char CheckFlash (void);
unsigned char IsChar (void);
void SendChar (unsigned char c);
void delay (void); //1ms延时函数
unsigned char RecChar (void);
unsigned char PageBuffer[PageByte];
unsigned int RealPageAddress;
unsigned int PageAddress;
/*****************************************************************************/
//Flash编程
/*****************************************************************************/
void FlashLoad(void)
{
//SendChar('!');
while (1)
{
GetPageNumber();
if (RealPageAddress == 0xffff)
return;
if (GetPage())
{
WriteFlash();
if (CheckFlash())
SendChar('!');
else
SendChar('@');
}
else
SendChar('@');
}
}
/*****************************************************************************/
void GetPageNumber(void)
{
unsigned char PageAddressH;
unsigned char PageAddressL;
PageAddressH = RecChar();
PageAddressL = RecChar();
RealPageAddress=(int)((PageAddressH << 8) + PageAddressL);
PageAddress=RealPageAddress<<AddressShift;
#ifdef RAMPZ_FLAG
if (PageAddressH)
RAMPZ = 1;
else
RAMPZ = 0;
#endif
//SendChar(RealPageAddress>>8);
//SendChar(RealPageAddress);
//SendChar(PageAddress>>8);
//SendChar(PageAddress);
}
/*****************************************************************************/
char GetPage(void)
{
unsigned char i;
unsigned char LocalCheckSum = 0;
unsigned char CheckSum = 0;
for (i=0;i<PageByte/2;i++)
{
while(!IsChar());
PageBuffer[i]=RecChar();
LocalCheckSum ^= PageBuffer[i];
}
for (i=0;i<PageByte/2;i++)
{
while(!IsChar());
PageBuffer[i+PageByte/2]=RecChar();
LocalCheckSum ^= PageBuffer[i+PageByte/2];
}
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;
}
/*****************************************************************************/
/* Serial Port Code */
/*****************************************************************************/
unsigned char IsChar(void)
{
#if (ChipType == Atmega8)||(ChipType == Atmega16)||(ChipType == Atmega32)
if(UCSRA & 0x80)
#endif
#if (ChipType == Atmega64)||(ChipType == Atmega128)
if(UCSR1A & 0x80)
#endif
return 1;
else
return 0;
}
/*****************************************************************************/
/* 字符输入函数 */
unsigned char RecChar(void)
{
#if (ChipType == Atmega8)||(ChipType == Atmega16)||(ChipType == Atmega32)
while(!(UCSRA & 0x80));
return UDR;
#endif
#if (ChipType == Atmega64)||(ChipType == Atmega128)
while(!(UCSR1A & 0x80));
return UDR1;
#endif
}
/*****************************************************************************/
void SendChar(unsigned char c)
{
#if (ChipType == Atmega8)||(ChipType == Atmega16)||(ChipType == Atmega32)
while (!(UCSRA&(1<<UDRE)));
UDR=c;
#endif
#if (ChipType == Atmega64)||(ChipType == Atmega128)
while (!(UCSR1A&(1<<UDRE1)));
UDR1=c;
#endif
}
void delay(void)
{
unsigned int i;
for (i=0;i<65530;i++);
}
/*****************************************************************************/
void ExecCode(void)
{
#ifdef RAMPZ_FLAG
RAMPZ = 0;
#endif
INTVECREG=0x01; //中断向量表移位允许
INTVECREG=0x00; //中断向量指向应用程序区
asm("jmp 0x0000");
}
void main(void)
{
unsigned char BootFlag;
#ifdef InteClk //如果使用内部时钟,读取时钟校准值
OSCCAL=read_flash(OscAddress);
#endif
#if (ChipType == Atmega8)||(ChipType == Atmega16)||(ChipType == Atmega32)
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位停止
UCSRB = (1<<RXEN)|(1<<TXEN); //允许串口发送和接收
UBRR = BAU;
#endif
#if (ChipType == Atmega64)||(ChipType == Atmega128)
//------------------使用串口1为Boot口-----------------
//UCSR1C=(1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10); //8位数据+1位停止
UCSR1C=(1<<UCSZ11)|(1<<UCSZ10);//|(1<<USBS1);
UCSR1B = (1<<RXEN1)|(1<<TXEN1); //允许串口发送和接收
UBRR1L=((fosc/16/baud1)-1)%256;
UBRR1H=((fosc/16/baud1)-1)/256;
#endif
SendChar('>'); //通知PC机,BOOT下载准备就绪
delay(); //延时等待PC机响应
delay();
delay();
delay();
delay();
delay();
delay();
delay();
BootFlag=UDR1;
if (BootFlag == '<')
{
SendChar(ChipType);
while (RecChar()!='N');
SendChar(BootSize);
while (RecChar()!='N');
SendChar(BootVer);
while (1)
{
switch (RecChar())
{
case 'W': FlashLoad(); break;
case 'E': {
SendChar('E'); //通知PC机,进入运用程序区
while (RecChar()!='N');
ExecCode();
} break;
default : break;
}
}
}
SendChar('E'); //通知PC机,进入运用程序区
//while (RecChar()!='N');
delay();
delay();
delay();
delay();
ExecCode();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -