打印

PIC18F8720操作FLASH问题,高手指点一下。

[复制链接]
2341|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiao442613|  楼主 | 2008-3-17 14:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人最近用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);
}
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

50

帖子

1

粉丝