各位高手请帮忙:
STC12C5202AD串口中断中调用EEPROM读写函数,再把EEPROM中内容用液晶显示出来,结果没有显示,而单独对EEPROM读写再液晶显示、串口中断程序调试都没问题,哪里的问题呢?
(EEPROM读写前都关了中断的)
部分函数如下:
/*************串口接收中断处理********************/
void UART_Routine(void) interrupt 4
{
if(RI==1)
{
RI = 0;
EEPROM_Bytes_Write(1024,string1,12); // 将字符串写入首地址为0x00的EEPROM连续区域
EEPROM_Byte_Read(1024,string,12); // 将首地址为0x00的EEPROM连续区域数据读取存放到sting数组中
// Flag =1 ;
}
else
TI = 0;
}
/***********关闭 ISP_IAP 功能,安全防误操作*************/
void ISP_IAP_disable(void)
{
ISP_CONTR = 0x00; // 禁止ISP_IAP操作
ISP_CMD = 0x00; // 去除ISP_IAP命令
ISP_TRIG = 0x00; // 防止ISP_IAP命令误触发
ISP_ADDRH = 0x0FF; // 送地址高字节单元为00,指向非EEPROM区
ISP_ADDRL = 0x0FF; // 送地址低字节单元为00,防止误操作
EA = 1; // 开中断
}
/*********************公用的触发代码********************/
void ISPgoon(void)
{
EA = 0; // 关中断
ISP_CONTR = 0x80|WAIT_TIME; // 开ISP_IAP功能,设置FLASH操作等待时间
ISP_TRIG = 0x5A;
ISP_TRIG = 0xA5; // 触发ISP_IAP命令
_nop_();
}
/********************************************************************************
功能说明:
从指定首地址为addr的EEPROM区域读出size字节数据到buf指向的区域内,并返回实际读
出数据的字节数 *
********************************************************************************/
uint EEPROM_Byte_Read(uint addr, uchar *buf, const uint size)
{
uchar *p_buf;
uint i, current_size;
p_buf = buf;
current_size = 0;
ISP_CMD = ISP_IAP_BYTE_READ; // 读字节命令
for (i = 0; i < size; i++)
{
if ((addr < EEPROM_ADDR_START) || (addr > EEPROM_ADDR_END))
{
break; //地址越界检测
}
ISP_ADDRH = addr>>8; // 地址赋值
ISP_ADDRL = addr&0x00ff;
ISPgoon(); // 触发执行
*p_buf = ISP_DATA;
addr++;
p_buf++;
current_size++;
}
ISP_IAP_disable(); // 关闭ISP_IAP功能
return (current_size); // 返回读到数据的字节数
}
/********************************************************************************
功能说明:
把buf指向单元内的数据写入地址为addr的EEPROM单元内,成功返回1,或则返回0 *
********************************************************************************/
BOOL EEPROM_Byte_Write(uint addr, uchar *buf)
{
ISP_CMD = ISP_IAP_BYTE_PROGRAM; // 字节编程命令
if ((addr < EEPROM_ADDR_START) || (addr > EEPROM_ADDR_END))
{
return 0;
}
ISP_ADDRH = addr>>8; // 地址赋值
ISP_ADDRL = addr&0x00ff;
ISP_DATA = (*buf); // 写入数据准备
ISPgoon(); // 触发执行
ISP_IAP_disable(); // 关闭ISP_IAP功能
return 1;
}
/********************************************************************************
功能说明:擦除AddrInSector地址所在的整个扇区
********************************************************************************/
void Erase_Sector(uint AddrInSector)
{
ISP_CMD = ISP_IAP_SECTOR_ERASE; // 扇区擦除命令
ISP_ADDRH = AddrInSector>>8;
ISP_ADDRL = AddrInSector&0x00ff; // 地址赋值
ISPgoon(); // 触发执行
ISP_IAP_disable(); // 关闭ISP_IAP功能
}
/********************************************************************************
功能说明:
从首地址为src扇区单元拷贝连续size字节数据到首地址为des的连续扇区单元内,并返
回实际拷贝的字节数
********************************************************************************/
uint CopySector(uint src, uint des, const uint size)
{
uchar temp;
uint current_size, i;
current_size = 0;
for (i = 0; i < size; i++)
{
if (!EEPROM_Byte_Read(src, &temp, 1))
{
break;
}
if (!EEPROM_Byte_Write(des, &temp))
{
break;
}
des++;
src++;
current_size++;
}
return current_size;
}
/********************************************************************************
功能说明:
把buf指向区域内的size字节数据写入首地址为addr的EEPROM连续区域,并返回实际写入
数据的字节数 *
********************************************************************************/
uint EEPROM_Bytes_Write(uint addr, uchar *buf, const uint size)
{
uchar *p_buf, temp, move;
uint i, bufaddr, current_size, cur_sector_start_addr;
p_buf = buf;
move = 0;
current_size = 0;
for (i = 0; i < size; i++)
{
if (!EEPROM_Byte_Read(addr, &temp, 1))
{
break;
}
if (temp == 0xff)
{
EEPROM_Byte_Write(addr, p_buf);
}
else // 发现第一个单元不是0xff,要重新写入数据需要擦除整个扇区
{
Erase_Sector(EEPROM_ADDR_END); // 擦除用作缓冲的这个扇区
cur_sector_start_addr = addr&0xfe00;
CopySector(cur_sector_start_addr
, (EEPROM_ADDR_END + 1 - BYTES_EACH_SECTOR)
, (addr - cur_sector_start_addr));
bufaddr = (addr - cur_sector_start_addr) // 把第一个非0xff单元前的数据拷贝到缓冲扇区
+ (EEPROM_ADDR_END + 1 - BYTES_EACH_SECTOR); // 计算剩余需要存储的数据需写入缓冲扇区的首个单元地址
for ( ; i < size; i++) // 把剩余要存储的数据写入缓冲扇区
{
EEPROM_Byte_Write(bufaddr, p_buf);
addr++;
bufaddr++;
p_buf++;
current_size++;
}
if (addr < cur_sector_start_addr + USEING_EACH_SECTOR ) // 把需要改变区域后的数据写入缓冲扇区
{
CopySector(addr, bufaddr, USEING_EACH_SECTOR
- (addr - cur_sector_start_addr));
}
Erase_Sector(cur_sector_start_addr); // 擦除当前扇区
move = 1;
break;
}
addr++;
p_buf++;
current_size++;
}
if (move)
{
CopySector((EEPROM_ADDR_END - BYTES_EACH_SECTOR + 1) // 把缓冲扇区数据拷贝到当前扇区
, cur_sector_start_addr, USEING_EACH_SECTOR);
}
return current_size;
} |