AI8H8K64U移植16S EEPROM读写还是不对
#define IAP_ADDRESS0x4000 //EEPROM首地址//烧录时要设定 DATA-FLASH / EEPROM 的大小
//IAP 时 EEPROM的首地址是从 0 开始的
sfr IAP_TPS = 0xF5;
// 楼主这是请您设置工作主频,通知等待时间,如果是 24MHz, 就送 0x18
// 楼主这是请您设置工作主频,通知等待时间,如果是 12MHz, 就送 0xC
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
BYTE IapReadByte(WORD addr)
{
char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
void IapProgramByte(WORD addr,BYTE 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数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
/*---扇区擦除---------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
/*-----------------------------------------*/
void red_eeprom(void)
{
uint j,k,s,p;
RunTime_A=IapReadByte(IAP_ADDRESS); //上料延时
RunTime_B=IapReadByte(IAP_ADDRESS+1); //光电延时
CT=IapReadByte(IAP_ADDRESS+2); //占空比
j=IapReadByte(IAP_ADDRESS+3);//
k=IapReadByte(IAP_ADDRESS+4);//
s=IapReadByte(IAP_ADDRESS+5);//
p=IapReadByte(IAP_ADDRESS+6);//
total=j*1000+k*100+s*10+p; //
j=IapReadByte(IAP_ADDRESS+7);//
k=IapReadByte(IAP_ADDRESS+8);//
s=IapReadByte(IAP_ADDRESS+9);//
p=IapReadByte(IAP_ADDRESS+10);//
FHz=j*1000+k*100+s*10+p; //
RunTime_C=IapReadByte(IAP_ADDRESS+11); //
}
/***************************************/
void write_eeprom( )
{
uint j,k,s,p;
IapEraseSector(IAP_ADDRESS); //扇区擦除
IapProgramByte(IAP_ADDRESS,RunTime_A); //上料延时
IapProgramByte(IAP_ADDRESS+1,RunTime_B);//光电延时
IapProgramByte(IAP_ADDRESS+2,CT); //占空比
j=total/1000;
k=(total-j*1000)/100;
s=(total-j*1000-k*100)/10;
p=total-j*1000-k*100-s*10;
IapProgramByte(IAP_ADDRESS+3,j);/**/
IapProgramByte(IAP_ADDRESS+4,k);/**/
IapProgramByte(IAP_ADDRESS+5,s);/**/
IapProgramByte(IAP_ADDRESS+6,p);/**/
j=FHz/1000;
k=(FHz-j*1000)/100;
s=(FHz-j*1000-k*100)/10;
p=FHz-j*1000-k*100-s*10;
IapProgramByte(IAP_ADDRESS+7,j);/**/
IapProgramByte(IAP_ADDRESS+8,k);/**/
IapProgramByte(IAP_ADDRESS+9,s);/**/
IapProgramByte(IAP_ADDRESS+10,p);/**/
IapProgramByte(IAP_ADDRESS+11,RunTime_C);//
}
楼主不用移植,可以参考我们STC8H8K64U的范例
程序太复杂了,我只想读写一个字节 删除
几分钟搞定机器急用 搞了一天了
现在下载到开天斧 打开串口通讯软件COM7没有反应
感谢版主热心帮助
烧录时要设定 DATA-FLASH / EEPROM 的大小
范例程序改了一下 用三个按键写入7F 1F FE
再用一个按键读出后送P2显示
上电后所有P2闪三次
再读出EEPROM显示
结果错误
EEPROM容量已设置0.5K
不复位显示正确
复位后再读数据就错误了
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sfr IAP_TPS = 0xF5;
sbit KEY_0=P3^2; //
sbit KEY_1=P3^3; //
sbit KEY_2=P3^4; //
sbit KEY_3=P3^5; //
uchar kcounter,kstatus; //按键计数标志 按键状态标志
/**************Delay*******************************/
void Delay_50ms(unsigned int Del_50ms) //
{
unsigned int m;
for(;Del_50ms>0;Del_50ms--)
for(m=62450;m>0;m--);
}
/***********************************/
void IapIdle()
{
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高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_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数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_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高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
}
/***********************************/
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
Delay_50ms(20);
P2 =0X00;
Delay_50ms(20);
P2 =0XFF;
Delay_50ms(20);
P2 =0X00;
Delay_50ms(20);
P2 =0XFF;
Delay_50ms(20);
P2 =0X00;
Delay_50ms(20);
P2 =0XFF;
P2 = IapRead(0x0400);
Delay_50ms(20);
while (1)
{
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_0) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_0) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0400);
IapProgram(0x0400, 0xEF);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_1) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_1) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0400);
IapProgram(0x0400, 0x7F);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_2) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_2) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0400);
IapProgram(0x0400, 0xFE);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_3) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_3) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
P2=IapRead(0x0400); //P1=0x12
}
//
}
}
参考附件例子,这个比较简单 也许正是IAP方式和MOVC方式
以前一直不了解这两种方式
范例程序写的4000H 就照抄了
现在改成0000H
写入读出复位再读好像可以
谢谢
P2 = IapRead(0x0000);
Delay_50ms(20);
while (1)
{
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_0) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_0) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0000);
IapProgram(0x0000, 0xEF);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_1) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_1) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0000);
IapProgram(0x0000, 0x7F);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_2) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_2) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
IapErase(0x0000);
IapProgram(0x0000, 0xFE);
}
//
RstKey();
for(;kcounter<10;) //按键循环5次
{
if(!KEY_3) //按键低电平
{
LowVoltKey();
}
else if(~!KEY_3) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=8) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
P2=IapRead(0x0000); //P1=0x12
}
//
}
}
页:
[1]