c51单片机数字钟代码
时间: 2024-04-14 20:21:26 浏览: 149
C51单片机数字钟代码可以分为以下几个部分:
1. 时钟芯片驱动部分:通过I2C总线协议与时钟芯片进行通信,获取当前时间并进行显示。
2. 数码管驱动部分:通过数码管驱动芯片控制数码管的亮灭,实现数字显示。
3. 按键扫描部分:通过按键扫描程序检测按键的状态,实现对时间的调整和设置。
4. 主程序部分:将以上三个部分结合起来,实现数字钟的功能。
以下是一个简单的C51单片机数字钟代码示例:
```
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCL=P1^0; //I2C总线时钟线
sbit SDA=P1^1; //I2C总线数据线
sbit DIO=P2^0; //74HC595数据线
sbit RCLK=P2^1; //74HC595锁存线
sbit SRCLK=P2^2; //74HC595时钟线
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f //数码管显示表
};
uchar sec,min,hour; //秒、分、时
uchar secflag=0; //秒标志位
void delay(uint x) //延时函数
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void I2C_Start() //I2C总线起始信号
{
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=0;
}
void I2C_Stop() //I2C总线停止信号
{
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
}
void I2C_SendByte(uchar dat) //I2C总线发送一个字节
{
uchar i;
for(i=0;i<8;i++)
{
SDA=dat&0x80;
dat<<=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SCL=0;
}
uchar I2C_RecvByte() //I2C总线接收一个字节
{
uchar i,dat=0;
SDA=1;
for(i=0;i<8;i++)
{
dat<<=1;
SCL=1;
_nop_();
_nop_();
_nop_();
if(SDA)
dat|=0x01;
SCL=0;
_nop_();
_nop_();
_nop_();
}
return dat;
}
void DS1307_Write(uchar addr,uchar dat) //向DS1307写入一个字节
{
I2C_Start();
I2C_SendByte(0xd0);
I2C_SendByte(addr);
I2C_SendByte(dat);
I2C_Stop();
}
uchar DS1307_Read(uchar addr) //从DS1307读取一个字节
{
uchar dat;
I2C_Start();
I2C_SendByte(0xd0);
I2C_SendByte(addr);
I2C_Start();
I2C_SendByte(0xd1);
dat=I2C_RecvByte();
I2C_Stop();
return dat;
}
void DS1307_Init() //DS1307初始化
{
uchar i;
DS1307_Write(0x00,0x00); //停止计时
for(i=0x01;i<=0x07;i++)
DS1307_Write(i,0x00); //清零寄存器
DS1307_Write(0x00,0x80); //启动计时
}
void HC595_SendByte(uchar dat) //74HC595发送一个字节
{
uchar i;
for(i=0;i<8;i++)
{
DIO=dat&0x80;
dat<<=1;
SRCLK=0;
_nop_();
_nop_();
_nop_();
SRCLK=1;
_nop_();
_nop_();
_nop_();
}
RCLK=0;
_nop_();
_nop_();
_nop_();
RCLK=1;
}
void Display(uchar dat) //数码管显示一个数字
{
HC595_SendByte(table[dat/10]);
HC595_SendByte(table[dat%10]);
}
void KeyScan() //按键扫描
{
if(P3!=0xff)
{
delay(10);
if(P3!=0xff)
{
if(P3==0xfe) //调整小时
{
hour++;
if(hour==24)
hour=0;
DS1307_Write(0x02,hour);
}
else if(P3==0xfd) //调整分钟
{
min++;
if(min==60)
min=0;
DS1307_Write(0x01,min);
}
else if(P3==0xfb) //调整秒钟
{
sec=0;
DS1307_Write(0x00,sec);
}
while(P3!=0xff);
}
}
}
void main()
{
DS1307_Init(); //DS1307初始化
while(1)
{
sec=DS1307_Read(0x00); //读取秒钟
min=DS1307_Read(0x01); //读取分钟
hour=DS1307_Read(0x02); //读取小时
Display(hour); //显示小时
Display(min); //显示分钟
if(secflag==0) //秒标志位为0时显示秒钟
{
Display(sec);
secflag=1;
}
else //秒标志位为1时不显示秒钟
{
HC595_SendByte(0x00);
HC595_SendByte(0x00);
secflag=0;
}
KeyScan(); //按键扫描
delay(100); //延时100ms
}
}
--相关问题--:
阅读全文