📄 main.c
字号:
/***************************************************************
*此程序是以51单片机为控制核心,通过IIC记录,以数码管显示的数字钟*
*数码管驱动芯片:595,两片 *
*定时单元通过单片机内部定时器完成,定时存在一定误差 *
*按键调整模块还未加上 *
*作者:王发修 *
*时间:2008年8月29日 *
*此程序与勤奋的人分享,愿大家共同进步 *
***************************************************************/
#include <AT89X52.H>
#include<intrins.h>
#include <absacc.h>
unsigned char sec,minite=30,hour=12; //定义计数值,每过1秒,sec加1
unsigned int tcnt; //定时中断次数
unsigned char extint0_count=0;
bit write=0; //写24C08的标志;
sbit MPX_DAT=P1^4;
sbit MPX_CLK=P1^5;
sbit MPX_OE =P1^6;
sbit IIC_SCL = P3^6; // 24c08 IIC_SCL
sbit IIC_SDA = P3^5; // 24c08 IIC_SDA
code unsigned char MPX[]={0x20,0x40,0x80,0x01,0x02,0x04,0x08,0x10};//位选信号
// 1 2 3 4 5 6 7 8
code unsigned char Seg7Code[] =
{//定义数码管字型数据
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, //0123456789
// 0x77,0x7C,0x39,0x5E,0x79,0x71, //AbCdEF
0x40, //-
0x00 //空白
};
unsigned char data buffer[8]={0,0,10,0,0,10,0,0};
void delay_ms(unsigned int n)
{
unsigned char i;
while(n--)
for(i=0;i<125;i++);
}
void MPX_Clear()//清除显示
{
unsigned char i;
for(i=25;i>0;i--)
{
MPX_CLK=0;
_nop_();
MPX_CLK=1;
_nop_();
MPX_DAT=1;
_nop_();
}
MPX_CLK=0;
}
void MPX_WriteData(unsigned char j)//向595写入8位数据
{
unsigned char c=8;
while(c--)
{
MPX_DAT=j&0x80;
MPX_CLK=0;
j=j<<1;
_nop_();
MPX_CLK=1;
_nop_();
}
}
void MPX_Display(unsigned char mybit,unsigned char mydata)
{
MPX_WriteData(~MPX[mybit]);
if(mybit>3)
{
MPX_WriteData(0x00);
MPX_WriteData(Seg7Code[mydata]);
}
else if(mybit<4)
{
MPX_WriteData(Seg7Code[mydata]);
MPX_WriteData(0x00);
}
MPX_CLK=0;
_nop_();
MPX_CLK=1;
_nop_();
}
/////////24C08读写驱动程序////////////////////
void shortdelay(unsigned char x)
{ unsigned int i;
for(i=0;i<x;i++);
}
void flash()
{ ; ; }
void IIC_Init() //24c08初始化子程序
{IIC_SCL = 1; flash(); IIC_SDA = 1; flash();}
void IIC_Start() //启动I2C总线
{IIC_SDA = 1; flash(); IIC_SCL = 1; flash(); IIC_SDA = 0; flash(); IIC_SCL = 0; flash();}
void IIC_Stop() //停止I2C总线
{IIC_SDA = 0; flash(); IIC_SCL = 1; flash(); IIC_SDA = 1; flash();}
void IIC_WriteByte(unsigned char dat) //写一个字节
{ unsigned char i,uc_tmp;
uc_tmp=dat;
for (i=0;i<8;i++)
{uc_tmp=uc_tmp<<1; IIC_SCL=0; flash(); IIC_SDA=CY; flash(); IIC_SCL=1; flash();}
IIC_SCL=0; flash(); IIC_SDA=1; flash();
}
unsigned char IIC_ReadByte() //读一个字节
{
unsigned char i,j,uc_tmp=0;
IIC_SCL=0; flash(); IIC_SDA=1;
for (i=0;i<8;i++)
{
flash(); IIC_SCL=1; flash();
if (IIC_SDA==1) j=1;
else j=0;
uc_tmp=(uc_tmp<<1)|j;
IIC_SCL=0;
}
flash();
return(uc_tmp);
}
void IIC_Clock() // I2C总线时钟
{
unsigned char i=0;
IIC_SCL = 1; flash();
while ((IIC_SDA==1)&&(i<255))i++;
IIC_SCL = 0; flash();
}
////////从24c02的地址address中读取一个字节数据/////
unsigned char X24C08_ReadByte(unsigned char address)
{
unsigned char uc_tmp;
IIC_Start(); IIC_WriteByte(0xa0);
IIC_Clock(); IIC_WriteByte(address);
IIC_Clock(); IIC_Start();
IIC_WriteByte(0xa1); IIC_Clock();
uc_tmp=IIC_ReadByte(); IIC_Stop();
shortdelay(10);
return(uc_tmp);
}
//////向24c02的address地址中写入一字节数据info/////
void X24C08_WriteByte(unsigned char address,unsigned char info)
{
EA=0;
IIC_Start(); IIC_WriteByte(0xa0);
IIC_Clock(); IIC_WriteByte(address);
IIC_Clock(); IIC_WriteByte(info);
IIC_Clock(); IIC_Stop();
EA=1;
shortdelay(50);
}
/////////////24C08读写驱动程序完/////////////////////
/*****************以上是IIC的底层协议*******************/
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //重装计数初值
tcnt++; //每过250ust tcnt加一
if(tcnt==20) //计满20次(1秒)时
{
tcnt=0; //重新再计
sec++;
write=1; //1秒写一次24C08
if(sec==60) //定时100秒,在从零开始计时
{
{
sec=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
hour=0;
}
}
}
}
}
void Timer0_Display()
{
unsigned char i;
buffer[0]=hour/10;buffer[1]=hour%10;
buffer[3]=minite/10;buffer[4]=minite%10;
buffer[6]=sec/10;buffer[7]=sec%10;
for(i=0;i<8;i++)
{
MPX_OE =1;
MPX_Display(i,buffer[i]);
MPX_OE=0;
delay_ms(1);
}
/*
MPX_OE =1;
MPX_Display(0,sec/100);
MPX_OE=0;
delay_ms(5);
MPX_OE =1;
MPX_Display(1,sec/10%10);
MPX_OE=0;
delay_ms(5);
MPX_OE =1;
MPX_Display(2,sec%10);
MPX_OE=0;
delay_ms(5);
*/
}
void main(void)
{
TMOD=0x01; //定时器工作在方式1
ET0=1; EA=1;
MPX_Clear();
IIC_Init(); //初始化24C08
/*
X24C08_WriteByte(6,12);
delay_ms(11);
X24C08_WriteByte(4,30);
delay_ms(11);
X24C08_WriteByte(2,30); //在24c08的地址2中写入数据sec
delay_ms(11);
*/
sec=X24C08_ReadByte(2);//读出保存的数据赋于sec
minite=X24C08_ReadByte(4);
hour=X24C08_ReadByte(6);
delay_ms(500);
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //使定时器0.05秒中断一次
TR0=1; //开始计时
while(1)
{
Timer0_Display();
if(write==1) //判断计时器是否计时一秒
{
write=0; //清零
X24C08_WriteByte(6,hour);
delay_ms(11);
X24C08_WriteByte(4,minite);
delay_ms(11);
X24C08_WriteByte(2,sec); //在24c08的地址2中写入数据sec
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -