本人最近用PIC18F8720外扩一片28F320来作为256色彩屏LCD的显存。对28F320的解锁,擦除,读取操作已成功,可是对FLASH的BUFFER编程操作总是出问题,每次对大约4Kbytes左右的空间进行buffer编程(一次写入32字节)时,总是会有6、7个或者10来个buffer编程不成功。高手请指点一下!以下是本人的代码 /***************************************************************************** *功能说明:对FLASH缓冲区编程操作(一次性写入16WROD) *入口参数: * BufferAddr-写入首地址(BufferAddr须为32的倍数) * DataBuff-待写入FLASH的数据缓冲区首址 *返回参数: *****************************************************************************/ void Flash_WriteBuffer(uint32 BuffAddr,uchar *DataBuff) { uchar blocknum=0; uchar portbnum=0; uchar addrU=0; uchar addrH=0; uchar addrL=0; uchar Temp1=0,Temp2=0; uint overtime=0; uchar i=0; portbnum=(uchar)((BuffAddr&0x300000)>>20); //取出地址的最高2位 blocknum=(uchar)((BuffAddr&0x3e0000)>>16); //取出BLOCI地址 addrU=(uchar)((BuffAddr&0x3f0000)>>16); addrH=(uchar)((BuffAddr&0x00ff00)>>8); addrL=(uchar)(BuffAddr&0x0000ff); MEMCON=0X22; do{ Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; TABLAT=0x50; //Clear the Status register asm("TBLWT*+"); TABLAT=0x50; asm("TBLWT*"); OverTimeCount1=0x00; //Clear the overtime counter while(1) { Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; TABLAT=0xE8; //Write Buffer Porgram Command asm("TBLWT*+"); TABLAT=0XE8; asm("TBLWT*"); Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; asm("TBLRD*+"); Temp1=TABLAT; //Read XSR status register asm("TBLRD*"); Temp2=TABLAT; if(Temp1&0x80) //如果缓冲区有效,则对缓冲区进行编程 { Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; TABLAT=0x0f; //Write Buffer length asm("TBLWT*+"); TABLAT=0X0f; asm("TBLWT*");
GIE=0; //关闭系统所有中断 Choose_Portb_Addr(portbnum); TBLPTRU=addrU; TBLPTRH=addrH; TBLPTRL=addrL; for(i=0;i<16;i++) { TABLAT=DataBuff[2*i];//Write Even byte asm("TBLWT*+"); asm("nop");asm("nop"); TABLAT=DataBuff[2*i+1];//Write Odd byte asm("TBLWT*+"); asm("nop");asm("nop"); } Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; TABLAT=0xd0; //Confirm buffer porgram asm("TBLWT*+"); TABLAT=0XD0; asm("TBLWT*"); GIE=1; //打开系统所有中断 break; } if(OverTimeCount1>3) break; } OverTimeCount1=0x00; //Clear the overtime counter while(1) { Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; TABLAT=0x70; asm("TBLWT*+"); TABLAT=0X70; asm("TBLWT*"); Choose_Portb_Addr(portbnum); TBLPTRU=blocknum&0x0e; TBLPTRH=0X00; TBLPTRL=0X00; asm("TBLRD*+"); Temp1=TABLAT; if(Temp1&0x80) break; asm("TBLRD*"); Temp2=TABLAT; if(OverTimeCount1>2) break; } WriteFlag=Temp1; // if(overtime>1000) // break; // overtime++; DelayNus(100); }while(WriteFlag&0X3A); }
|