📄 bootldr.c
字号:
#pragma psect text=bootldr
#include <pic18.h>
#include "bootldr.h"
/*============================================================================
配置字节
============================================================================*/
__CONFIG(1,IESODIS&FCMDIS&HS);
//__CONFIG(1,0x32FF); // 0011,0010,1111,1111
//振荡器为HS(20M),系统振荡器时钟转换选择禁止,故障保护时钟监视器禁止
//CONFIG1H(IESO,FCMEN,-,-,FOSC3,FOSC2,FOSC1,FOSC0)
//IESO: Internal/External Oscillator Switchover bit, 0=Oscillator Switchover mode disabled
//FCMEN:Fail-Safe Clock Monitor Enable bit,0=Fail-Safe Clock Monitor disabled
//FOSC=0010=HS oscillator
//低8位保留
__CONFIG(2,WDTDIS&WDTPS32K&BORV28&BOREN&PWRTEN);
//__CONFIG(2,0xFEF6); // 1110,1110, 1111,0110
//监视定时器WDT禁止,掉电锁定复位硬件使能,复位电压为2.8V,上电定时器使能
//CONFIG2H(-,-,-,WDTPS3,WDTPS2,WDTPS1,WDTPS0,WDTEN),看门狗定标和允许位)
//WDTEN=0,狗定标禁止
//CONFIG2L(-,-,-,BORV1,BOVR0,BOREN1,BOREN0,/PWRTEN)
//BORV1:BOVR0=10=2.8V
//BOREN1:BOREN0=11=Brown-out Reset enabled in hardware only(SBOREN is disabled)
///BORTEN=0=Power-up Timer Enable
__CONFIG(3,MCLREN&LPT1DIS&PBADDIS);
//__CONFIG(3,0xF9FF); // 1111,1001,1111,1111
//选定B口为数字通道,低电压定时器1振荡禁止高功率,MCLR使能
//CONFIG3H(MCLRE,-,-,-,-,LPT1OSC,PBADEN,-)
//MCLRE:MCLR Pin Enable bit=1=MCLR pin enabled;RE3 input pin disabled
//LPT1OSC:高功率振荡器1,1=低功率,0=高功率
//PBADEN:PB口AD允许位=0,禁止AD
//低8位保留
__CONFIG(4,DEBUGDIS&XINSTDIS&BBSIZ1K&LVPDIS&STVREN);
//__CONFIG(4,0xFF2B); //调试使能(1111,1111,0010,1011)
//使能RB6、RB7为专用调试器接口,堆栈溢出复位使能,低压编程禁止
//CONFIG4L(/DEBUG,XINST,-,BBSIZ,-,LVP,-,STVREN)
///DEBUG:0=调试,RB6/RB7用于ICD,
//XINST:Extended Instruction Set Enable bit=Legacy mode
//BBSIZ:0=1K words (2 Kbytes) boot block
//LVP:0=Single-Supply ICSP disabled
//STVREN:1=Stack full/underflow will cause Reset
//高8位保留
__CONFIG(5,UNPROTECT);
//__CONFIG(5,0xFFFF); //11111111,11111111
//程序存储区、数据EEPROM,引导区都无代码保护
//CONFIG5H(CPD,CPB,-,-,-,-,-,-)
//CPD:1=数据 EEPROM 不保护
//CPB:1=启动块 (000000-0007FFh) 不保护
//CONFIG5L(-,-,-,-,CP3,CP2,CP1,CP0)
//CP3:1=块3(006000-007FFFh)不保护
//CP2:1=块2(004000-005FFFh)不保护
//CP1:1=块1(002000-003FFFh)不保护
//CP0:1=块0(000800-001FFFh)不保护
__CONFIG(6,WRTEN);
//__CONFIG(6,0xFFFF);
//程序存储区、数据EEPROM,引导区、配置寄存器都无写保护
//CONFIG6L(-,-,-,-,WRT3,WRT2,WRT1,WRT0)
//WRT3:1=块3(006000-007FFFh)无写保护
//WRT2:1=块2(004000-005FFFh)无写保护
//WRT1:1=块1(002000-003FFFh)无写保护
//WRT0:1=块0(000800-001FFFh)无写保护
//CONFIG6H(WRTD,WRTB,WRTC,-,-,-,-,-)
//WRTD:1=数据 EEPROM 无写保护
//WRTB:1=启动块(000000-0007FF)无写保护
//WRTC:1=配置寄存器(300000-3000FF)无写保护
__CONFIG(7,TREN);
//__CONFIG(7,0xFFFF);
//程序存储区、引导区都无表读保护
//CONFIG7L(-,-,-,-,EBTR3,EBTR2,EBTR1,EBTR0)
//EBTR3:1=块3(006000-007FFFh)无表读保护
//EBTR2:1=块2(004000-005FFFh)无表读保护
//EBTR1:1=块1(002000-003FFFh)无表读保护
//EBTR0:1=块0(000800-001FFFh)无表读保护
//CONFIG7H(-,ERTRB,-,-,-,-,-,-)
//ERTRB:1=启动块(000000-0007FF)无表读保护
/*============================================================================
原型函数
============================================================================*/
void checksum(void);
void putch(unsigned char);
void puts(const char *s);
unsigned char gx(void);
unsigned char g2x(void);
void zap(void);
void table_write(void);
void flash8(void);
void clear_buffer(void);
/*============================================================================
RAM定义
============================================================================*/
persistent near unsigned char buff[16]; //16字节发送缓冲,用于写入程序存储器
persistent near unsigned char DO_NOT_INCREMENT;
persistent near unsigned char cksum,rectype,bcount;
persistent near unsigned char delay_time;
persistent near unsigned char index;
persistent near unsigned short erase;
persistent near unsigned char START_MSG[] = "SHIRDE-FURNACE(C)2008\n";
persistent near unsigned char DOWNLOAD_MSG[] = "\rDownload-";
unsigned char FILE_MSG[] = "Select a HEX file:";
unsigned char SUCSESS_MSG[] = "SUCSESS!";
/*============================================================================
重新定向中断向量地址
============================================================================*/
#asm
psect intcode // 高级中断
goto PROG_START+8
psect intcodelo // 低级中断
goto PROG_START+0x18
#endasm
/*============================================================================
输出1字节到串口
============================================================================*/
void
putch(unsigned char byte)
{
while(!TRMT); // 当发送寄存器空时,TRMT=1
TXREG = byte; //输出1字节
}
/*============================================================================
输出1串字节到串口
============================================================================*/
void puts(const char *s)
{
while(s && *s)
putch(*s++);
}
/*============================================================================
接收校验字节并检查
============================================================================*/
void checksum(void)
{
g2x();
if(cksum) // 如果校验和不等于0,错误校验,重启
RESET(); // 重启单片机
putch('\r'); // 用换行来应答接收每行数据
}
/*============================================================================
从串口得到4 bit的 HEX数字(半个字节)
============================================================================*/
unsigned char gx(void)
{
while(!RCIF);
EEDATA=RCREG;
if(!TRMT) // 如果发送缓冲器空,
TXREG=EEDATA; // 回发收到的数据
if(EEDATA>='A')
return ((EEDATA - (unsigned char)'A')+10); //
return (EEDATA - '0'); //
}
/*============================================================================
将接收到的16进制数字并计算校验(1个字节)
============================================================================*/
unsigned char g2x(void)
{
unsigned char temp = (gx()<<4); // 接收高4位数据
temp += gx(); // 合并低4位数据
cksum+=temp; // 累加校验值
return temp;
}
/*============================================================================
启动闪存程序或数据EEPROM写入(长周期写操作)============================================================================*/
void zap(void)
{
WREN=1; // 允许闪存程序/数据EEPROM的写周期
EECON2=0x55; // 向EECON2写入0x55,必须执行的步骤
EECON2=0xAA; // 向EECON2写入0xAA,必须执行的步骤
WR=1; // 启动数据EEPROM擦写周期或程序存储器擦写周期
while(WR); // 等待写入结束
NOP();
WREN=0; // 禁止闪存程序/数据EEPROM的写周期
}
/*============================================================================
从RAM传递字节到 flash 寄存器
============================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -