|
|
本人新手,請(qǐng)教教各位大佬,使用STC8H8K64U單片機(jī)內(nèi)置eeprom功能保存unsigned int類型數(shù)組,總是出錯(cuò),原始數(shù)據(jù)一切正常,沒有超出int范圍,保存后讀取的數(shù)據(jù)總有幾個(gè)大于65530的數(shù)據(jù),附圖,附程序:
#ifndef __EEPROM_H__
#define __EEPROM_H__
/*STC8H單片機(jī)eeprom開始地址 0x00000-ISP軟件設(shè)置大小
擦除只能擦除整個(gè)扇區(qū),一個(gè)扇區(qū)512字節(jié)*/
#include "STC8H.h"
#include "intrins.h"
void IapIdle() //關(guān)閉IAP功能
{
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0;
}
char IapRead(int addr)//讀取指定地址的數(shù)據(jù)
{
char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 1; //設(shè)置IAP讀命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
EA = 0;
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
EA = 1;
_nop_();
dat = IAP_DATA; //讀IAP數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat;
}
void IapProgram(int addr, char dat) /*向指定地址寫數(shù)據(jù)*/
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 2; //設(shè)置IAP寫命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫IAP數(shù)據(jù)
EA = 0;
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
EA = 1;
_nop_();
IapIdle(); //關(guān)閉IAP功能
}
void IapErase(int addr) //擦除指定地址的數(shù)據(jù)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 3; //設(shè)置IAP擦除命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
EA = 0;
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
EA = 1;
_nop_(); //
IapIdle(); //關(guān)閉IAP功能
}
void SaveUIntToEEPROM(int addr, unsigned int dta)//保存unsigned int類型的數(shù)據(jù)
{
char lowByte,highByte;
lowByte = (char)(dta);
highByte = (char)(dta >> 8);
IapProgram(addr, lowByte);
IapProgram(addr + 1, highByte);
}
unsigned int ReadUIntFromEEPROM(int addr)//讀取指定地址的uint數(shù)據(jù)
{
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)//擦除數(shù)據(jù)
{
IapErase(addr);
IapErase(addr + 1);
}
#endif
上面是eeprom的,下面主函數(shù)的
#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}; //緩存數(shù)組
static unsigned int num = 0,two_num; //一共接受了幾個(gè)脈沖
static unsigned int Overflow = 0; //溢出次數(shù)
static unsigned char val; //接收超時(shí)變量
unsigned int ceshi = 0;//測(cè)試數(shù)據(jù)
//---------------------------------------------------------------------------------------------
void main()
{
unsigned int i = 0,a = 0;
Timer0_Init();
UartInit();
IR();
UartSendString("Starting\r\n");
while(1)
{
if(Overflow == 1 && ch == 0x02)//如果超時(shí)溢出,并且接收到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]);//打印保存到數(shù)組里的數(shù)據(jù)
delays(50);
}
SaveUIntToEEPROM(0x0000, num); //將脈沖個(gè)數(shù)寫入eeprom
UartSendString("End\r\n"); /*End結(jié)束*/
UartSendUint(num);
ir1 = 0x0400;
ch = 0;
num = 0;
Overflow = 0;
PWMA_IER = 0; //關(guān)閉PWM中斷使能
ET0 = 0; //關(guān)閉定時(shí)器0中斷
}else if(P20 == 0 && Overflow==0){
PWMA_IER = 0x06; //打開PWM中斷使能
ET0 = 1; //打開定時(shí)器0中斷
}
if(ch == 0x01)
{
two_num = ReadUIntFromEEPROM(0x0000);
for(a = 0;a<=two_num;a++) //讀取紅外接收數(shù)組
{
eep_captures[a] = ReadUIntFromEEPROM(ir1+a*2); //讀取數(shù)組里的數(shù)據(jù)
UartSendUint(eep_captures[a]);//打印保存到數(shù)組里的數(shù)據(jù)
delays(50);
}
UartSendUint(two_num);
ir1 = 0x0400;
two_num = 0;
ch = 0x00;
}
}
} |
-
原始數(shù)據(jù)和保存后讀取的數(shù)據(jù)
|