用的是STC89C52RC
单片机,买的LY-51S板子;A0,A1,A2接高电平,wp接地;能实现0-99s计时,就是不能实现记忆功能。
麻烦各位大虾帮帮忙,小弟不胜感激!先谢谢了!
/*************************************************
用定时器制作一个0--99s的秒表,并在数码管上显示,
把当前时间写入AT24C02;再次开机时能,从上次断电
时的时间开始计时!
*************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit scl = P2^0; //串行时钟输入端
sbit sda = P2^1; //串行数据输入/输
出端
sbit dula = P2^2; //段锁存端
sbit wela = P2^3; //位锁存端
bit write = 0; //写24c02的标志
uchar code table[]={ //0
-9数字
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
uchar sec,tcnt;
/***************5um延时**************/
void delay()
{
uchar tt;
for(tt=5;tt>0;tt--);
}
/***************xms延时**************/
void delay_1ms(uchar x)
{
uchar y;
for(;x>0;x--)
{
for(y=110;y>0;y--);
}
}
/****************总线初始化***************/
void init()
{ //将总线都拉高,以释放总线
scl = 1;
delay();
sda = 1;
delay();
}
/****************启动信号****************/
void start()
{
sda = 1; //在scl为高电平时,sda
一个下降沿启动信号
delay();
scl = 1;
delay();
sda = 0;
delay();
}
/***************应答信号****************/
void respons()
{ //scl高电平时
,sda被拉低,并且持续>4us
uchar i;
scl = 1;
delay();
while((1==sda)&&(i<255)) //如果如果从器件无
应答,
i++; //延时一段
时间后,主器件默认已应答
i = 0; //再次应答时,i还从0开始计时,来延时
scl = 0;
delay();
}
/****************停止信号***************/
void stop()
{ //scl
高电平时,sda一个上升沿停止信号
sda = 0;
delay();
scl = 1;
delay();
sda = 1;
delay();
}
/***************写一个字节*************/
void write_byte(uchar date)
{
uchar i,temp;
temp = date;
for(i=0;i<8;i++)
{
temp = temp<<1; //数据位一位一位的左
移到CY位
scl = 0; //scl低电平
时,允许数据变化
delay();
sda = CY; //从CY位一位
一位的把数据发出去
delay();
scl = 1; //scl高电平时
,要求数据稳定
delay();
}
scl = 0; //啥作用
delay(); // 啥作用
sda = 1; // 啥作
用
delay(); // 啥作用
}
/**************读一个字节*************/
uchar read_byte()
{
uchar i,k;
scl = 0;
delay();
sda = 1;
delay();
for(i=0;i<8;i++)
{
scl = 1;
delay();
k = (k<<1)|sda; //k左移一位后,与sda
与运算,一位一位的把数据读走
scl = 0;
delay();
}
delay();
return k;
}
/****向AT24C02指定地址写一个字节数据****/
void write_add(uchar address,uchar date)
{
start(); //启动
write_byte(0xae); //写控制字
respons(); //应答
write_byte(address); //送入一个字节的存储器
单元地址
respons();
write_byte(date); //写入数据
respons();
stop();
}
/****从AT24C02指定地址读一个字节数据****/
uchar read_add(uchar address)
{
uchar date;
start(); //启动
write_byte(0xae); //写入含片选单元的
写操作控制字
respons();
write_byte(address); //送入一个字节的存储器
单元地址
respons();
start(); //启动
write_byte(0xaf); //写入含片选单元的
读操作控制字
respons();
date = read_byte(); //
stop();
return date;
}
/*********数码管显示**********/
void display(uchar shi,uchar ge)
{
dula = 0;
P0 = table[shi];
dula = 1;
dula = 0;
wela = 0;
P0 = 0xfe;
wela = 1;
wela = 0;
delay_1ms(5);
dula = 0;
P0 = table[ge];
dula = 1;
dula = 0;
wela = 0;
P0 = 0xfd;
wela = 1;
wela = 0;
delay_1ms(5);
}
/*******************************************
主函数
*******************************************/
void main()
{
init();
sec = read_add(4);
if(100>sec)
sec = 0;
TMOD = 0x01;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
while(1)
{
display(sec/10,sec%10);
if(1==write)
{
write = 0;
write_add(4,sec);
}
}
}
void
timer0 () interrupt 1
{
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
tcnt++;
if(20==tcnt)
{
tcnt = 0;
sec++;
write = 1;
if(100==sec)
sec = 0;
}
}
一周热门 更多>