STC8H8K64 EEPROM读写
STC8H8K64 EEPROM字节读写
#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(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
}
//
}
}
#include "reg51.h"
#include "intrins.h"
#include "stdio.h"
/************* 本程序功能说明 **************
对STC内部自带的EEPROM(FLASH)进行读写测试。
对FLASH做扇区擦除、写入、读出的操作。
通过串口打印读取EEPROM结果。
注意:下载时,下载界面"硬件选项"中设置用户EEPROM大小,
并确保擦除、写入、读出的地址在EEPROM设置的大小范围之内。
下载时, 选择时钟 11.0592MHz (用户可自行修改频率)。
******************************************/
#define MAIN_Fosc 11059200L //定义主时钟参数
#define BAUD 115200
#define TM (65536 -(MAIN_Fosc/BAUD/4))
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sfr TH2 = 0xD6;
sfr TL2 = 0xD7;
sfr AUXR = 0x8E;
sfr P_SW2 = 0xBA;
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xc9;
sfr P5M0 = 0xca;
sfr IAP_DATA = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
sfr IAP_CMD = 0xC5;
sfr IAP_TRIG = 0xC6;
sfr IAP_CONTR = 0xC7;
sfr IAP_TPS = 0xF5;
#define P0PU (*(unsigned char volatile xdata *) 0xFE10)
#define P1PU (*(unsigned char volatile xdata *) 0xFE11)
#define P2PU (*(unsigned char volatile xdata *) 0xFE12)
#define P3PU (*(unsigned char volatile xdata *) 0xFE13)
#define OFFSET 0
sbit KEY1 = P3^2;
u16 Key1_cnt;
bit Key1_Flag;
bit Key1_Function;
void KeyScan(void);
void delay_ms(u8 ms);
void PrintfInit(void)
{
SCON = (SCON & 0x3f) | 0x40;
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TL1 = TM;
TH1 = TM>>8;
TR1 = 1; //定时器1开始计时
// SCON = (SCON & 0x3f) | 0x40;
// T2L = TM;
// T2H = TM>>8;
// AUXR |= 0x15; //串口1选择定时器2为波特率发生器
}
void UartPutc(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
char putchar(char c)
{
UartPutc(c);
return c;
}
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
unsigned char IapRead(int addr)
{
char dat;
IAP_CONTR = 0x80; //使能IAP
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, unsigned char dat)
{
IAP_CONTR = 0x80; //使能IAP
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_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
void main()
{
unsigned char i;
unsigned char a[10];
P_SW2 |= 0x80; //使能XFR访问
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x0c; P3M0 = 0x00; //设置P3.2,P3.3为高阻输入
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P3PU = 0x0c; //使能P3.2,P3.3口上拉
IAP_TPS = 11; //设置EEPROM操作等待参数(11.0592MHz),初始化设置一次即可
PrintfInit();
while (1)
{
delay_ms(1);
KeyScan();
if(Key1_Function)
{
Key1_Function = 0;
printf("Key1 pressed.\r\n");
printf("Read1="); //读取EEPROM原先的内容
for(i=0;i<10;i++)
{
a[i] = IapRead(OFFSET+i);
printf("0x%02bx ",a[i]);
if(a[i] == 0xff) a[i] = i; //如果内容为空,则写入初始化数据
else a[i]++; //如果内容非空,在原先基础上加1
}
printf("\r\n");
IapErase(OFFSET);
printf("Read2="); //擦除、重写后,读取EEPROM现在的内容
for(i=0;i<10;i++)
{
IapProgram(OFFSET+i, a[i]);
a[i] = IapRead(OFFSET+i);
printf("0x%02bx ",a[i]);
}
printf("\r\n");
}
}
}
//========================================================================
// 函数: void KeyScan(void)
// 描述: 按键扫描函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void KeyScan(void)
{
if(!KEY1)
{
if(!Key1_Flag)
{
Key1_cnt++;
if(Key1_cnt >= 50) //50ms防抖
{
Key1_Flag = 1; //设置按键状态,防止重复触发
Key1_Function = 1;
}
}
}
else
{
Key1_cnt = 0;
Key1_Flag = 0;
}
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i); //10T per loop
}
while(--ms);
}
更多推荐



所有评论(0)