STC15F104E eeprom技术求助,高手过来顶下啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
本人参照宏晶的eeprom程序,验证STC15F104E eeprom的功能,但现在编译出来后,功能是实现了,但程序运行到状态5后,关掉电源,再通电,状态能保存,但按键就失灵了,程序就想是跑飞了一样,有没有高手知道是什么原因啊?而且刚上电时要按好几下按键,灯才会亮。真心求解,还望各位大侠帮忙分析下,不胜感激!#include<stc_new_8051.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//定义EEPROM的操作命令
#define Idlecommand 0x00
#define Rdcommand 0x01
#define Prgcommand 0x02
#define Erasecommand 0x03
sfr IAP_data=0xc2; //Flash数据寄存器申明
sfr IAP_addrh=0xc3; //Flash高字节地址寄存器申明
sfr IAP_addrl=0xc4; //Flash低字节地址寄存器申明
sfr IAP_cmd=0xc5; //Flash命令模式寄存器申明
sfr IAP_trig=0xc6; //Flash命令触发寄存器申明
sfr IAP_contr=0xc7; //ISP/IAP控制寄存器申明
#define Enable_IAP 0x81//晶振<24M
sbit key=P3^5; //按键定义
sbit red=P3^2; //红灯管脚定义
sbit blue=P3^4; //蓝灯管脚定义
uchar temp=0x01;
//************ N*1ms延时程序********
void delay(uint ms)
{
uchar a;
while(ms--)
for(a=110;a>0;a--);
}
//************ 初始化程序************
void init()
{
blue=1;
red=1;
}
//************ 关闭ISP,IAP功能************
void ISP_IAP_disable(void)
{
IAP_contr=0;
IAP_cmd=0;
IAP_trig=0;
IAP_addrh=0x80;
IAP_addrl=0;
}
//************ 字节读************
uchar byte_read(uint byte_addr)
{
uchar dat;
IAP_contr=Enable_IAP;
IAP_cmd=Rdcommand;
IAP_addrl=byte_addr;
IAP_addrh=byte_addr>>8;
IAP_trig=0x5a;
IAP_trig=0xa5;
_nop_();
dat=IAP_data;
ISP_IAP_disable();
return dat;
}
//************ 扇区擦除************
void Setorerase(uint sector_addr)
{
IAP_contr=Enable_IAP;
IAP_cmd=Erasecommand;
IAP_addrl=sector_addr;
IAP_addrh=sector_addr>>8;
IAP_trig=0x5a;
IAP_trig=0xa5;
_nop_();
ISP_IAP_disable();
}
//************ 字节写************
void byte_write(uint byte_addr,uchar original_data)
{
IAP_contr=Enable_IAP;
IAP_cmd=Prgcommand;
IAP_addrl=byte_addr;
IAP_addrh=byte_addr>>8;
IAP_data=original_data;
_nop_();
IAP_trig=0x5a;
IAP_trig=0xa5;
_nop_();
ISP_IAP_disable();
}
//************ 按键程序************
void KEY()
{
if(key==0)
{
delay(10);
if(key==0)
{
temp++;
switch(temp)
{
case 0x01: //状态一
red=1;
blue=1;
break;
case 0x02: //状态二
red=0;
blue=1;
break;
case 0x03: //状态三
red=1;
blue=0;
break;
case 0x04: //状态四
red=0;
blue=0;
break;
case 0x05: //状态五
red=1;
blue=1;
break;
}
Setorerase(0x0000);//擦除扇区
byte_write(0x0000,temp);//重新写入数据
if(temp==0x05)temp=0x01; //设定返回值
while(!key);
} //判断按键释放
}
}
//************ 主程序************
void main()
{
init(); //初始化
temp=byte_read(0x0000); //读EEPROM数据
switch(temp)
{
case 0x01: //状态一
red=1;
blue=1;
break;
case 0x02: //状态二
red=0;
blue=1;
break;
case 0x03: //状态三
red=1;
blue=0;
break;
case 0x04: //状态四
red=0;
blue=0;
break;
case 0x05: //状态五
red=1;
blue=1;
break;
}
while(1)
{
KEY();
}
} 你程序有太多缺陷了,KEY函数在哪调用? 回复【1楼】longwu911
你程序有太多缺陷了,key函数在哪调用?
-----------------------------------------------------------------------
有很多缺陷?可以说清楚点嘛?key在最后的主函数里啊!
while(1)
{
KEY();
}
} 高手,大虾们都跑哪去了?我需要你们!!! 没人顶,我自己顶!精诚所至,铁石会开! 继续顶! 自己自顶起来!!!! 首先,风格太差,不出问题是奇迹
temp作为全局变量是极其不好的习惯,其次temp的switch/case语句没有default。
再次,temp=5以后++,变成6就没有人管了
最后
注意这个顺序:
//temp==5
byte_write(0x0000,temp);//重新写入数据
if(temp==0x05)temp=0x01;//设定返回值
//下次启动
temp=byte_read(0x0000); //读EEPROM数据
//temp==5
KEY()
temp++
//temp==6 ????有问题吗? 给个用的木有问题的你换一下试试,用在STC11F03E的程序,建议你程序换别的型号跑,测试正常后在换回STC15F104E,之前用这颗IC
外部中断是有问题的。所以你还是换别的型号确认程序没问题后在换回来。
/***************************
STC11F03EEEPROM
***************************
IAP_DATA数据寄存器
IAP_ADDRH 地址寄存器高八位
IAP_ADDRL 地址寄存器低八位
IAP_CMD 命令寄存器
IAP_TRIG命令触发寄存器
写入5AH,在写入A5H 命令才会生效
IAP_CONTR ISP_IAP命令寄存器
****************************/
#define isp_dataIAP_DATA
#define isp_addrh IAP_ADDRH
#define isp_addrl IAP_ADDRL
#define isp_cmd IAP_CMD
#define isp_trigIAP_TRIG
#define isp_contr IAP_CONTR
void IAP_Disable()
{
//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
isp_contr = 0; //关闭IAP 功能
isp_cmd = 0; //清命令寄存器,使命令寄存器无命令,此句可不用
isp_trig= 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
isp_addrh = 0;
isp_addrl = 0;
}
void eeprom_eares(unsigned int addres)//扇区擦除。
{
isp_addrl=addres; //低位地址
isp_addrh=addres>>8; //高位地址
isp_contr=0x03;//设置等待时间
isp_contr=isp_contr|0x80; //设时间与ISP操作。
isp_cmd=0x03; //扇区命命令
isp_trig=0x5a; //触发
isp_trig=0xa5; //触发启动。
delay(1);
IAP_Disable();//关闭IAP 功能
}
void eeprom_write(unsigned int addres,unsigned char write_data)//写数据。
{
isp_data=write_data; //要写入的数据。
isp_addrl=addres; //低位地址
isp_addrh=addres>>8; //高位地址
isp_contr=0x03; //设置等待时间
isp_contr=isp_contr|0x80; //设时间与ISP操作。
isp_cmd=0x02; //写命令
isp_trig=0x5a; //触发
isp_trig=0xa5; //触发启动。
delay(1);
IAP_Disable();//关闭IAP 功能
}
unsigned char eeprom_read(unsigned int addres)//读数据
{
unsigned char z;
isp_addrl=addres; //低位地址
isp_addrh=addres>>8; //高位地址
isp_contr=0x03; //设置等待时间
isp_contr=isp_contr|0x80; //设时间与ISP操作。
isp_cmd=0x01; //读命令
isp_trig=0x5a; //触发
isp_trig=0xa5; //触发启动。
delay(1);
IAP_Disable();//关闭IAP 功能
z=isp_data;
return(z);//返回数据
} 回复【8楼】hnzhy870215
给个用的木有问题的你换一下试试,用在stc11f03e的程序,建议你程序换别的型号跑,测试正常后在换回stc15f104e,之前用这颗ic
外部中断是有问题的。所以你还是换别的型号确认程序没问题后在换回来。
/***************************
stc11f03eeeprom
***************************
iap_data数据寄存器
iap_addrh 地址寄存器高八位
iap_addrl 地址寄存器低八位
iap_cmd 命令寄存器
iap_trig命令触发寄存器
写入5ah,在写入a5h 命令才会生效
iap_contr isp_iap命令寄存器
****************************/
#define isp_dataiap_data
#defi......
-----------------------------------------------------------------------
首先谢谢你的程序与建议,我试下,我现在一直在搞着IC,希望你能多指教指教啊! 你单片机选用多少M晶振,比如12M时“#define Enable_IAP 0x81//晶振<24M”这项可不符合,
12M应该“#define Enable_IAP 0x83”比较合适
页:
[1]