/****说明:结合我手上的板子,显示部分代码没有规律。上班时间没事用了俩小时看芯片资料带改,下班后一试直接成功。用手机看的PDF sheet,可把我累死了!
测试功能:0-60循环计数,断电保护存储最后数值,重启继续。*****/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define RdCommand 0x01 //定义ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定义CPU的等待时间
sfr ISP_DATA=0xe2; //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
sbit L1=P1^2;
sbit L2=P1^3;
sbit L3=P1^4;
sbit L4=P1^5;
uchar code table[20]={
0x14,0xf5,0x19,0x51,
//0 1 2 3
0xf0,0x52,0x12,0x75,
// 4 5 6 7
0x10,0x50,0x30,0x92,
// 8 9 a b
0x1e,0x91,0x1a,0x3a,0x38,0xfb,0xef,0xff};//排列方式: A E C DP D G B F
//c d e F P - . 熄灭
uchar a,b;
uchar num;
/******延时函数*********/
void delay_led(uint z)
{
uint i,j;
for (j=0;j<z;j++)
for ( i=0;i<125;i++);
}
/********显示函数*********/
void display()
{
L1=1;
L2=1;
L3=0;
P0=table[a];//十位显示
delay_led(2);
L3=1;
L4=0;
P0=table; //个位显示
delay_led(2);
L4=1;
}
/* ================ 打开 ISP,IAP 功能 ================= */
void ISP_IAP_enable(void)
{
EA = 0; /* 关中断 */
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */
ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
}
/* =============== 关闭 ISP,IAP 功能 ================== */
void ISP_IAP_disable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
ISP_TRIG = 0x00;
ISP_CMD=0X00;
ISP_ADDRH=0xFF;
ISP_ADDRL=0xff;
EA = 1; /* 开中断 */
}
/* ================ 公用的触发代码 ==================== */
void ISPgoon(void)
{
ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */
ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */
ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */
_nop_();
}
/* ==================== 字节读 ======================== */
unsigned char byte_read(unsigned int byte_addr)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭ISP,IAP功能 */
return (ISP_DATA); /* 返回读到的数据 */
}
/* ================== 扇区擦除 ======================== */
void SectorErase(unsigned int sector_addr)
{
unsigned int iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭ISP,IAP功能 */
}
/* ==================== 字节写 ======================== */
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */
ISP_DATA = original_data; /* 写入数据准备 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭IAP功能 */
}
void main()
{
uchar num1;
TMOD=0x01; //设置定时器0为工作方式1(0000 0001)
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
num1=byte_read(0x2000);//程序开始时读取EEPROM中数据
if(num1>=60) //防止首次上电时读取出错
num1=0;
while(1)
{
if(num>=20)
{
num=0;
num1++;
SectorErase(0x2000);//擦除扇区
byte_write(0x2000,num1);//重新写入数据
if(num1==60)
{
num1=0;
}
a=num1/10;
b=num1%10;
}
display();
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
}
上一篇:关于单片机I/0口置低的引脚不能拉高的问题
下一篇:可以改密码的单片机电子密码锁
推荐阅读最新更新时间:2024-03-16 15:21
设计资源 培训 开发板 精华推荐
- 有奖直播|如何借助Mentor Xpedition AMS对汽车CAN总线进行仿真优化分析?
- 意法半导体工业峰会2019( 深圳 )
- 【EEWORLD第二十二届社区明星人物】畅想十二月明星人物揭晓!
- 2023 DigiKey KOL 系列——将TinyML融入IoT物联网应用中
- 贸泽翻牌挑战赛—一键配齐的乐趣,它不香吗?快来参与贸泽翻牌挑战赛!
- 炎炎盛夏,EEWORLD社区6月明星人物出炉喽!
- 阅读Microchip多种连接接口SAM单片机精彩专题,参与活动赢好礼
- 可靠QTouch技术集成邻键抑制(AKS)功能,适用任何触摸应用领域
- 下载《TI MCU与无线连接技术研讨会讲座实录》抽奖赢好礼!