#define uint unsigned int
#define uchar unsigned char
sbit PRESS1=P1^0
sbit PRESS2=P1^1
sbit PRESS3=P1^2
uint a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}//0到9
uint b[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}
int miao=45,fen=58,shi=15
uint jishu
uint miaog,miaos,feng,fens,shig,shis
int ji
void init()//初始化函数设桥迅置中断寄存器的值。
{
jishu=0
TMOD=0x01
TR0=1
ET0=1
EA=1
TH0=0x3c
TL0=0xb0
}
void delay(x)//延时函数。
{
uint i,j
for(i=xi>0i--)
for(j=120j>0j--)
}
void xian()//把时分秒送到数码管显示。
{
uint i
miaog=miao%10
miaos=miao/10
feng=fen%10
fens=fen/10
shig=shi%10
shis=shi/10
for(i=0i<8i++)
{
switch(i)
{
case 0:P3=b[7]P2=a[miaog]break
case 1:P3=b[6]P2=a[miaos]break
case 2:P3=b[5]P2=0x40break
case 3:P3=b[4]P2=a[feng]break
case 4:P3=b[3]P2=a[fens]break
case 5:P3=b[2]P2=0x40break
case 6:P3=b[1]P2=a[shig]break
case 7:P3=b[0]P2=a[shis]break
}
delay(1)
}
}
void jiance()//检测键是否按下按不同键实现不同的处理。
{
if(PRESS1==0)
{
delay(2)
if(PRESS1==0)
{
while(!PRESS1)
ji++
if(ji>=4)
ji=0
}
}
if(ji==1)
{
if(PRESS2==0)
{
delay(1)
while(!PRESS2)
miao++
if(miao>=60)
{
miao=0
fen++
}
}
if(PRESS3==0)
{
delay(1)
while(!PRESS3)
miao--
if(miao<0)
{
miao=59
}
}
}
if(ji==2)
{
if(PRESS2==0)
{
delay(1)
while(!PRESS2)
fen++
if(fen>=60)
{
fen=0
shi++
}
}
if(PRESS3==0)
{
delay(1)
while(!PRESS3)
fen--
if(fen<0)
{
fen=59
}
}
}
if(ji==3)
{
if(PRESS2==0)
{
delay(1)
while(!PRESS2)
shi++
if(shi>=24)
{
shi=0
}
}
if(PRESS3==0)
{
delay(1)
while(!PRESS3)
shi--
if(shi<0)
{
shi=23
}
}
}
if(ji==0)
EA=1
else
EA=0
}
void main()
{
init()
while(1)
{
xian()
jiance()
}
}
void duan() interrupt 1 //计时中断0工作敏丛此方式1函数。
{
TH0=0x3c
TL0=0xb0
jishu++
if(jishu==20)
{
jishu=0
miao++
if(miao==60)
{
miao=0
fen++
if(fen==60)
{
fen=0
shi++
if(shi==24)
shi=0
}
}
}
}
单片机中有EPROM,我用的是STC12C5A60S2,有1K空间的EPROM,是可以断电保存用户数据的,其他型号STC单粗培片机的EPROM大小不一,参考手册,但程序差不多的,程序如下:/********************************************************************
* *
* 单片机学习开发板BP-51A - 内部EPROM读写演示程序 *
* 版本: V1.0 (2011/10/13) *
* 作者: BestProvider *
* 说明: STC12C5A60S2单片机有1K字节的内部EPROM,可森档以用来存放用户数 *
*据(断电不丢失),EPROM分2个扇区,地址为0X0000-0X1FFF和0X2000 *
*-0X3FFF,需要注意的是在进行写 *** 作时,必须先要进行所在扇区 *
*的清除 *** 作*
* 硬件: 本实验需要液晶屏LCD1602来显示数据 *
* 参考: 《STC12C5A60S2中文资料》- 第12章 STC12C5A60S2系列单片机 *
*EPROM的应用 *
* *
********************************************************************/
#include <stc12c5a60s2.h>
typedef unsigned char BYTE // 数据范围0-255
typedef unsigned int WORD // 数据范围0-65535
typedef bit BOOL // 数据范围0-1
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_WRITE 2
#define CMD_ERASE 3
#define ENABLE_IAP 0X82
BYTE write_data[5]={0,1,2,3,4}
BYTE read_data[5]
BYTE code dis1[ ] = {"EPROM Write/Read"}
BYTE code dis2[ ] = {"Data: "}
sbit LCD_RS = P2^0 // LCD控制线
sbit LCD_RW = P2^1
sbit LCD_EN = P2^2
/* ms级延时 */
/********************************/
void delay_ms(WORD n)
{
WORD i=0
WORD j
while(i<n)
{
for(j=0j<1000j++){}
i++
}
}
/* 测试LCD忙碌状态 */岩春唯
/********************************/
BOOL lcd_bz()
{
BOOL result
LCD_RS = 0
LCD_RW = 1
LCD_EN = 1
delay_ms(1)
result = (BOOL)(P0 &0x80)
LCD_EN = 0
return result
}
/* 写入指令数据到LCD*/
/********************************/
void lcd_wcmd(BYTE cmd)
{
while(lcd_bz())
LCD_RS = 0
LCD_RW = 0
LCD_EN = 0
delay_ms(1)
P0 = cmd
delay_ms(1)
LCD_EN = 1
delay_ms(1)
LCD_EN = 0
}
/* 设定显示位置 */
/********************************/
void lcd_pos(BYTE pos)
{
lcd_wcmd(pos | 0x80)
}
/* 写入字符显示数据到LCD*/
/********************************/
void lcd_wdat(BYTE dat)
{
while(lcd_bz())
LCD_RS = 1
LCD_RW = 0
LCD_EN = 0
P0 = dat
delay_ms(1)
LCD_EN = 1
delay_ms(1)
LCD_EN = 0
}
/* LCD初始化设定*/
/********************************/
void lcd_init()
{
lcd_wcmd(0x38)
delay_ms(10)
lcd_wcmd(0x0c)
delay_ms(10)
lcd_wcmd(0x06)
delay_ms(10)
lcd_wcmd(0x01) // 清除LCD的显示内容
delay_ms(10)
}
/* EPROM 扇区清除 */
/********************************/
void Iaperasesector(unsigned char addr)
{
IAP_ADDRH=addr
IAP_ADDRL=0x00
IAP_CONTR=ENABLE_IAP
IAP_CMD=CMD_ERASE
IAP_TRIG=0x5a
IAP_TRIG=0xa5
delay_ms(10)
}
/* EPROM 写 *** 作 */
/********************************/
void Iapwritebyte()
{
BYTE i
Iaperasesector(0x00) // 在进行内部EPROM写 *** 作前需进行扇区清除 *** 作
IAP_CONTR=ENABLE_IAP
for(i=0i<5i++)
{
IAP_ADDRH=0x00
IAP_ADDRL=0x00+i
IAP_DATA=write_data[i]
IAP_CMD=CMD_WRITE
IAP_TRIG=0x5a
IAP_TRIG=0xa5
delay_ms(10)
}
IAP_CONTR=0x00
}
/* EPROM 读 *** 作 */
/********************************/
void Iapreadbyte()
{
BYTE i
for(i=0i<5i++)
{
IAP_DATA=0
IAP_CONTR=ENABLE_IAP
IAP_ADDRH=0x00
IAP_ADDRL=0x00+i
IAP_CMD=CMD_READ
IAP_TRIG=0x5a
IAP_TRIG=0xa5
delay_ms(10)
read_data[i]=IAP_DATA
}
IAP_CONTR=0x00
}
/* 数据显示 */
/********************************/
void Display()
{
BYTE m
lcd_pos(0) // 设置显示位置为第一行的第1个字符
m = 0
while(dis1[m] != '\0')
{
lcd_wdat(dis1[m]) // 显示字符
m++
}
lcd_pos(0x40) // 设置显示位置为第二行第1个字符
m = 0
while(dis2[m] != '\0')
{
lcd_wdat(dis2[m]) // 显示字符
m++
}
lcd_pos(0x46) // 显示读取的第1个数据
lcd_wdat(0x30+read_data[0])
lcd_pos(0x48) // 显示读取的第2个数据
lcd_wdat(0x30+read_data[1])
lcd_pos(0x4a) // 显示读取的第3个数据
lcd_wdat(0x30+read_data[2])
lcd_pos(0x4c) // 显示读取的第4个数据
lcd_wdat(0x30+read_data[3])
lcd_pos(0x4e) // 显示读取的第5个数据
lcd_wdat(0x30+read_data[4])
}
/* 主程序 */
/********************************/
main()
{
delay_ms(200) // 通电后延迟200ms,再进行EPROM *** 作
Iapwritebyte() // 将4个数据存入单片机内部EPROM中
delay_ms(10)
Iapreadbyte() // 从EPROM中读取数据
lcd_init() // 初始化LCD
delay_ms(10)
Display() // 显示读取的数据
while(1)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)