还是直接上程序吧,这样直观一点,也方便大家指出小弟的不足和误区。
先说明几点:1、我的bootloader区设置在1F00----1FFF这段区间,如下图:
2、现在程序能实现上电的时候通过下图四句实现跳转到BootStar
3、但是现在的问题是我现在通过写flash,把程序写进了0200H的地址处,
想通过改变PCL的指针来跳转到0200H的地方执行,但是PC指针老是不对
下图是点亮一个LED的机器码。
4、求大侠们看看我这个粗略的程序有什么问题啊。谢谢了……
/******************************************************************/
//项目时间:2012/5/7
//程序功能:PIC实现简单的bootloader
//芯片型号:PIC16F877A
//晶振频率:20M
//程序备注:MPLAB IDE V8.33 ------ PICC V8.05
/*****************************************************************/
#include<pic.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define RX_PIN TRISC7
#define TX_PIN TRISC6
uint8 DataH,DataL;
const uint8 FlashData[] = {0x01,0x83,0x30,0x02,0x00,0x8a,0x28,0xe4,0x01,0x83,
0x12,0x0a,0x11,0x8a,0x2f,0xfa,0x16,0x83,0x13,0x03,0x10,0x88,0x12,0x83,
0x10,0x88,0x2f,0xff,0x3f,0xff,0x3f,0xff};//点亮一个LED灯
/*****************************************************************/
//函数名称:void USART_init(void)
//功能描述:串口通信初始化
//全局变量:无
//参数说明:无
//返回说明:无
//程序说明:波特率9600 高速
/*****************************************************************/
void USART_init(void)
{
RX_PIN = 1;
TX_PIN = 1;
SPBRG = 0x81; //9600 20M
RCSTA = 0x90;
TXSTA = 0x24;
}
/*****************************************************************/
//函数名称:void PutChar(uint8 byte)
//功能描述:输出单字符
//全局变量:无
//参数说明:byte,要输出的数据
//返回说明:无
//程序说明:无
/*****************************************************************/
void PutChar(uint8 byte)
{
while(!TXIF);
TXREG = byte;
}
/*****************************************************************/
//函数名称:void PutString(const char *s)
//功能描述:输出字符串
//全局变量:无
//参数说明:S,要输出的字符串
//返回说明:无
//程序说明:无
/*****************************************************************/
void PutString(const char *s)
{
while(s && *s)
PutChar(*s ++);
}
/*****************************************************************/
//函数名称:void Flash_Read(uint8 address)
//功能描述:输出单字符
//全局变量:无
//参数说明:uint8 MS_EEADR,地址高字节;uint8 LS_EEADR,地址低字节
//返回说明:无
//程序说明:无
/*****************************************************************/
void Flash_Read(uint8 MS_EEADR,uint8 LS_EEADR)
{
uint8 cnt;
for(cnt = 0;cnt < 16;cnt ++)
{
EEADRH = MS_EEADR;
EEADR = LS_EEADR;
EEPGD = 1; //Point to Program Memory
RD = 1; //EE Read Enable
asm("nop");
asm("nop");
DataL = EEDATA;
DataH = EEDATH;
LS_EEADR++;
PutChar(DataH);
PutChar(DataL);
}
}
/*****************************************************************/
//函数名称:void Flash_Write(uint8 MS_EEADR,uint8 LS_EEADR)
//功能描述:输出单字符
//全局变量:无
//参数说明:uint8 MS_EEADR,数据高字节;uint8 LS_EEADR,数据低字节
//返回说明:无
//程序说明:无
/*****************************************************************/
void Flash_Write(uint8 MS_EEADR,uint8 LS_EEADR)
{
uint8 cnt;
for(cnt = 0;cnt < 16;cnt ++)
{
EEADRH = MS_EEADR;
EEADR = LS_EEADR;
EEDATA = FlashData[cnt*2+1];
EEDATH = FlashData[cnt*2];
EEPGD = 1;
WREN = 1;
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
asm("nop");
asm("nop");
while(WR);
LS_EEADR ++;
WREN = 0;
}
}
/*****************************************************************/
//函数名称:void main(void)
//功能描述:主函数
//程序说明:BootStart 1F00 ------ BootStop 1FFF
/*****************************************************************/
void main(void)
{
USART_init();
//PutString("Bootloader is running now!\n");
PutChar(':');
Flash_Write(0x02,0x00);
// Flash_Read(0x00,0xE0);
#asm //想将PC指针指向0200H的应用程序地址,可是PC指针不对
movlw 0x02
movwf 0x0a //PCLATH
movlw 0x00
movwf 0x02 //PCL
#endasm
while(1);
}
#asm
; Reset vector redirection
; some equates for accessing the program counter
PCL equ 02h
PCLATH equ 0Ah
psect redirect,abs,class=CODE,delta=2 ;absolute psect so it goes
;to address zero
;The boot loader code has been written so that it doesn't need any
;variable initialization runtime startup code.
;Because of this, we can jump directly into the main() function.
global _main
movlw _main >> 8 ;A "long" jump to main - this will cope with
movwf PCLATH ;main being positioned anywhere
movlw _main & 0xFF
movwf PCL
#endasm |