|
本人新手,请教教各位大佬,使用STC8H8K64U单片机内置eeprom功能保存unsigned int类型数组,总是出错,原始数据一切正常,没有超出int范围,保存后读取的数据总有几个大于65530的数据,附图,附程序:
#ifndef __EEPROM_H__
#define __EEPROM_H__
/*STC8H单片机eeprom开始地址 0x00000-ISP软件设置大小
擦除只能擦除整个扇区,一个扇区512字节*/
#include "STC8H.h"
#include "intrins.h"
void IapIdle() //关闭IAP功能
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
char IapRead(int addr)//读取指定地址的数据
{
char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
EA = 0;
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
EA = 1;
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
void IapProgram(int addr, char dat) /*向指定地址写数据*/
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
EA = 0;
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
EA = 1;
_nop_();
IapIdle(); //关闭IAP功能
}
void IapErase(int addr) //擦除指定地址的数据
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
EA = 0;
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
EA = 1;
_nop_(); //
IapIdle(); //关闭IAP功能
}
void SaveUIntToEEPROM(int addr, unsigned int dta)//保存unsigned int类型的数据
{
char lowByte,highByte;
lowByte = (char)(dta);
highByte = (char)(dta >> 8);
IapProgram(addr, lowByte);
IapProgram(addr + 1, highByte);
}
unsigned int ReadUIntFromEEPROM(int addr)//读取指定地址的uint数据
{
char lowByte,highByte;
unsigned int dta;
lowByte = IapRead(addr);
highByte = IapRead(addr + 1);
dta = (((unsigned int)highByte) << 8) | lowByte;
return dta;
}
void EraseUIntFromEEPROM(int addr)//擦除数据
{
IapErase(addr);
IapErase(addr + 1);
}
#endif
上面是eeprom的,下面主函数的
#include "stc8H.h"
#include "intrins.h"
#include <stdio.h>
#include "uart.h"
#include "eeprom.h"
#define VAL 300 //脉冲缓存大小
extern char ch;
int ir1 = 0x0400;
xdata unsigned int captures[VAL] = {0},eep_captures[VAL] = {0}; //缓存数组
static unsigned int num = 0,two_num; //一共接受了几个脉冲
static unsigned int Overflow = 0; //溢出次数
static unsigned char val; //接收超时变量
unsigned int ceshi = 0;//测试数据
//---------------------------------------------------------------------------------------------
void main()
{
unsigned int i = 0,a = 0;
Timer0_Init();
UartInit();
IR();
UartSendString("Starting\r\n");
while(1)
{
if(Overflow == 1 && ch == 0x02)//如果超时溢出,并且接收到0x02
{
EraseUIntFromEEPROM(0x0400);
delays(5);
EraseUIntFromEEPROM(0x0000);
delays(5);
for(i = 0; i <= num; i++)
{
SaveUIntToEEPROM(ir1+i*2, captures[ i]); //写入eeprom
UartSendUint(captures[ i]);//打印保存到数组里的数据
delays(50);
}
SaveUIntToEEPROM(0x0000, num); //将脉冲个数写入eeprom
UartSendString("End\r\n"); /*End结束*/
UartSendUint(num);
ir1 = 0x0400;
ch = 0;
num = 0;
Overflow = 0;
PWMA_IER = 0; //关闭PWM中断使能
ET0 = 0; //关闭定时器0中断
}else if(P20 == 0 && Overflow==0){
PWMA_IER = 0x06; //打开PWM中断使能
ET0 = 1; //打开定时器0中断
}
if(ch == 0x01)
{
two_num = ReadUIntFromEEPROM(0x0000);
for(a = 0;a<=two_num;a++) //读取红外接收数组
{
eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2); //读取数组里的数据
UartSendUint(eep_captures[a]);//打印保存到数组里的数据
delays(50);
}
UartSendUint(two_num);
ir1 = 0x0400;
two_num = 0;
ch = 0x00;
}
}
} |
|