?? main._c
字號:
/******************************************************************************
Atmega系列單片機 BootLoader程序
日 期:2007年4月
作 者:likeeavr
版權所有:avrvi論壇 www.avrvi.com bbs.avrvi.com
說明:當前版本只針對本論壇M16開發板
上位機借用了馮建輝的程序。
/*****************************************************************************/
#include <macros.h>
#include "assembly.h"
#define ChipType Atmega16
//*********************************************************
//選擇BOOT區大小 此必須與ICC options中的選項相對應
//#define BootSize 'a' //128
//#define BootSize 'b' //256
//#define BootSize 'c' //512
#define BootSize 'd' //1024
//選擇BootLoad版本號
#define BootVer 'f' //1.0版本
//**********************************************************
#define Atmega16 0x31
//*****************************************************************************
#define InteClk //是否使用內部時鐘
#define OscAddress 0x1fff //時鐘校準值存儲地址
//*****************************************************************************
//7.3728M時鐘下的波特率為19200的設置,此設置可根據ICC生成,選對芯片,時鐘,波特率既可
//由此語句調用UBRR = BAU;
#define BAU 23 // 7.3728M 19200
//#define BAU 191 // 7.3728M 2400
//#define BAU 95 // 7.3728M 4800
//#define BAU 47 // 7.3728M 9600
//#define BAU 31 // 7.3728M 14400
//#define BAU 23 // 7.3728M 19200
//#define BAU 15 // 7.3728M 28800
//#define BAU 38 // 12M 19200
//*****************************************************************************
#include <iom16v.h>
#define PageByte 128
#define AddressShift 7
#define INTVECREG GICR
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
}
/*****************************************************************************/
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(UCSRA & 0x80)
return 1;
else
return 0;
}
/*****************************************************************************/
/* 字符輸入函數 */
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)
{
#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
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位數據+1位停止
UCSRB = (1<<RXEN)|(1<<TXEN); //允許串口發送和接收
UBRR = BAU;
SendChar('>'); //通知PC機,BOOT下載準備就緒
delay(); //延時等待PC機響應
delay();
delay();
delay();
delay();
delay();
delay();
delay();
BootFlag=UDR;
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 + -