本人新手,請教教各位大佬,使用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;
}
}
} |