DS1302四位八段数码管显示的完整程序-C语言
#include
#include
#define uchar unsigned char
#define unint unsigned int
/* 时钟程序*/
/************************************/
sbit T_CLK=P2^4; /* 实时时钟的时钟线引脚*/
sbit T_IO=P3^1; /* 实时时钟的数据线*/
sbit T_RST=P3^0; /* 实时时钟的复位线引脚*/
sbit gw=P2^3; //个位
sbit sw=P2^2; //十位
sbit bw=P2^1; //百位
sbit qw=P2^0; //千位
unint a[4];//={0,0,0,0};
/*位段的数字*/
uchar code ledk[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code ledk1[10]={0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};
//加了小数点后
unint ucCurtime[7]={30,59,23,26,07,02,0x06}; // 秒 分 时 日 月 星期 年
unint temp;
uchar data BUFFER[1]={0};
void delay() /*延时*/
{
uchar m,n;
for(m=10;m>0;m--)
for(n=100;n>0;n--);
}
void v_RTInputByte(uchar ucDa) //写1个字节的数据
{
uchar i;
ACC=ucDa;
for(i=8;i>0;i--)
{
if((ACC&0x01)==1)
//T_IO=ACC0; /* 相当于汇编中的RRC */
T_IO=1;
else T_IO=0;//if((ACC&0x01)==0)
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
}
uchar uc_RTOutputByte(void)
{
uchar i,ACC;
ACC=0;
for(i=0;i {
ACC=ACC>>1; /*相当于汇编中的RRC*/
if(T_IO==1)
ACC=ACC|0x80;
T_CLK=1;
T_CLK=0;
}
return(ACC);
}
void v_W1302(uchar ucAddr,uchar ucDa)
{
T_RST=0;
T_CLK=0;
T_RST=1;
v_RTInputByte(ucAddr); /*地址,命令*/
v_RTInputByte(ucDa); /*写1Byte数据*/
T_CLK=1;
T_RST=0;
}
uchar uc_R1302(uchar ucAddr)
{
unsigned char ucDa,k;
k=0x00;
T_RST=0;
T_CLK=0;
T_RST=1;
v_RTInputByte(ucAddr); /*地址,命令*/ //输入一个字节的数据。 写入读地址的控制命令。
ucDa=uc_RTOutputByte(); /*读取1Byte数据*/
T_CLK=1;
T_RST=0;
k=ucDa/16; //在将10进制的数转化为16进制的数。
ucDa=ucDa%16;
ucDa=ucDa+k*10;
return(ucDa);
}
void v_Set1302()//uchar *pSecDa)
{
uchar i,j;
uchar ucAddr=0x80;
v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(i=0;i {
j=ucCurtime[i];
v_W1302(ucAddr,j); /* 秒 分 时 日 月 星期 年 */
ucAddr +=2;
}
v_W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
}
void v_Get1302() //读1302里的数据。
{
uchar i;
uchar ucAddr=0x81;
for (i=0;i {
ucCurtime[i]=uc_R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
ucAddr +=2;
}
}
void t2_10()
{
unint k;
a[3]=temp/1000;
k=temp%1000;
a[2]=k/100;
k=k%100;
a[1]=k/10;
a[0]=k%10;
}
/*显示*/
void display1()
{
uchar c;
t2_10();
c=a[0];
P1=ledk[c];
gw=0;
delay();
gw=1;
c=a[1];
P1=ledk[c];
sw=0;
delay();
sw=1;
c=a[2];
P1=ledk1[c]; //带小数点的共阴数码管的码值。
bw=0;
delay();
bw=1;
c=a[3];
P1=ledk[c];
qw=0;
delay();
qw=1;
}
void display2()
{
uchar c;
t2_10();
c=a[0];
P1=ledk[c];
gw=0;
delay();
gw=1;
c=a[1];
P1=ledk[c];
sw=0;
delay();
sw=1;
c=a[2];
P1=ledk[c];
bw=0;
delay();
bw=1;
c=a[3];
P1=ledk[c];
qw=0;
delay();
qw=1;
}
void main1(void)
{ v_Get1302();
temp=ucCurtime[4]*100+ucCurtime[3]; //temp里的值是为了显示到数码管里而设定的值.
display1();
}
void main2(void)
{ v_Get1302();
temp=ucCurtime[4]*100+ucCurtime[3];
display2();
}
void main()
{
unint i,k;
for(i=0;i {
k=ucCurtime[i]/10; //将数组里的16进制的数转换成10进制的数。
ucCurtime[i]=ucCurtime[i]%10;
ucCurtime[i]=ucCurtime[i]+16*k;
}
v_Set1302();
while(1) //这个循环里的程序,在应用到硬件上的现象是:让人们感觉数码管中的小数点每秒中都会闪烁一次.
{
BUFFER[0]=BUFFER[0]+1;
if(BUFFER[0]==101)
{
main1();
BUFFER[0]=0;
}
else main2();
}
}
总结:本人不贪功,这篇程序是我转载的.
我使用四个共阴的数码管进行实验,效果是非常好的.
yu5315461 2007年09月23日 星期日 下午 04:56
这段程序,不仅可以运用在数码管上,同样可以运用到液晶上进行显示.只要对程序上稍加改进就可以了.