标题:
自己写的ds1302时钟程序 数码管调节时间一个暗一个亮的
[打印本页]
作者:
lele4090039
时间:
2018-3-5 12:40
标题:
自己写的ds1302时钟程序 数码管调节时间一个暗一个亮的
//有些地方没删除,是调试的时候用的。请专家帮看看,为什么我写到开发板上,数码管调节时间一个暗一个亮的,
功能:显示时钟
显示日期
调节时钟日期
四位数码管显示
#include<reg52.h>
#include<intrins.h>
sbit Ge=P0^0 ; //数码管段
sbit Shi=P0^1 ;
sbit Bai=P0^2 ;
sbit Qian = P0^3;
sbit SCK = P1^0; //DS1302模块
sbit DS = P1^1;
sbit CE = P1^2;
sbit KEY1=P1^3; //按键
sbit KEY2=P1^4;
void configTime0(unsigned int ms);//配置定时器0配置中断
void configUART(unsigned int begin);//配置UART串口通信设置波特率
void Shownum(); //扫描函数
void display(); //数码管刷新函数
void Write_ds1302(unsigned char dat); //写1302函数1字节
void Write_ds1302_CE(unsigned char cmd,unsigned char dat); //读取1302函数1字节 对命令处理
//void read_ds1302_burst(unsigned char *dat); //burst模式读取8个字节 突发模式
void initds1302();//初始化ds1302
void keyset();
void keycan();
unsigned char Read_ds1302_CE(unsigned char cmd); //1302函数1字节 对命令处理
unsigned char Read_ds1302(); //读取1302函数1字节
unsigned char Smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//真值表 123456789abcdefg
unsigned char SmgI[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};//带标点的真值表1.2.3.4.5.6.7.8.9.
unsigned char SmgTmp[8];//数码管缓存
unsigned char Time[8]; //时间缓存
unsigned char Tmp[4]; //调节时间的数组//0~分钟 1~小时 2~天 3~月
unsigned char flg = 1;//决定显示日期还是时间
unsigned char T0RL,T0RH;//重装定时器时间
unsigned char flg0,flg1,set0,set1;
bit backup0,backup1;
bit gb;
void main()
{
EA = 1;
configTime0(500);
configUART(9600);
initds1302();
while(1)
{
Shownum();
keyset();
}
}
void Shownum() //扫描函数
{
static unsigned char i;
if(flg0==0){
for(i=0;i<7;i++)
{
Time[i]=Read_ds1302_CE(i);
}
gb = (bit)(Read_ds1302_CE(0)&0x01);//将ds1302秒寄存器最低位取出用于数码管中间的两个点闪烁
SmgTmp[0]=(Time[1]&0x0F); //显示分钟,小时
SmgTmp[1]=(Time[1]>>4);
SmgTmp[2]=(Time[2]&0x0F);
SmgTmp[3]=(Time[2]>>4);
SmgTmp[4]=Time[3]&0x0F; //显示日期,月份
SmgTmp[5]=Time[3]>>4;
SmgTmp[6]=Time[4]&0x0F;
SmgTmp[7]=Time[4]>>4;
}
}
void configTime0(unsigned int m) //配置定时器0配置中断
{
T0RH =(65536-m)/256;
T0RL =(65536-m)%256;
TMOD &=0xF0;
TMOD |=0x01;
TH0=T0RH;
TL0=T0RL;
ET0 = 1;
TR0 = 1;
}
void configUART(unsigned int begin) //配置UART串口通信设置波特率
{
SCON = 0x50;
TMOD &=0x0F;
TMOD |=0x20;
TH1=256-(11059200/12/32)/begin;
TL1=TH1;
ET1 = 0;
ES = 1;
TR1 = 1;
}
void Write_ds1302(unsigned char dat) //写1302函数1字节
{
unsigned char mask;
for (mask=0x01; mask!=0; mask<<=1) //低位在前,逐位移出
{
if ((mask&dat) != 0) //首先输出该位数据
DS = 1;
else
DS = 0;
SCK = 1; //然后拉高时钟
SCK = 0; //再拉低时钟,完成一个位的操作
}
DS = 1;
} //最后确保释放IO引脚
unsigned char Read_ds1302() //读取1302函数1字节
{
unsigned char mask;
unsigned char dat = 0;
for (mask=0x01; mask!=0; mask<<=1) //低位在前,逐位读取
{
if (DS!= 0) //首先读取此时的IO引脚,并设置dat中的对应位
{
dat |= mask;
}
SCK = 1; //然后拉高时钟
SCK = 0; //再拉低时钟,完成一个位的操作
}
return dat; //最后返回读到的字节数据
}
void Write_ds1302_CE(unsigned char cmd,unsigned char dat) //读取1302函数1字节 对命令处理
{
CE = 1;
Write_ds1302((cmd<<1)|0x80);
Write_ds1302(dat);
CE = 0;
}
unsigned char Read_ds1302_CE(unsigned char cmd) //1302函数1字节 对命令处理
{
unsigned char dat;
CE = 1;
Write_ds1302((cmd<<1)|0x81);
dat=Read_ds1302();
CE = 0;
return dat;
}
/*void write_ds1302_burst(unsigned char *dat) //burst模式写8个字节 突发模式
{
unsigned char i;
CE = 1;
Write_ds1302(0xBE);
for(i=0;i<8;i++)
{
Write_ds1302(dat[i]);
}
CE = 0;
}
void read_ds1302_burst(unsigned char *dat) //burst模式读取8个字节 突发模式
{
unsigned char i;
CE = 1;
Write_ds1302(0xBF);
for(i=0;i<8;i++)
{
dat[i]=Read_ds1302;
}
CE = 0;
}*/
void initds1302()
{
unsigned char dat ;
unsigned char code init[]={0x00,0x56,0x20,0x28,0x02,0x05,0x18}; //2018 2 16 20 20 00
CE = 0;
SCK = 0;
dat=Read_ds1302_CE(0);
if((dat&0x80)!=0)
{
Write_ds1302_CE(7,0x00);
for(dat=0;dat<8;dat++)
{
Write_ds1302_CE(dat,init[dat]);
}
Write_ds1302_CE(7,0x80);
}
}
void display(unsigned char a,unsigned char b,unsigned char c,unsigned char d) //数码管刷新函数
{
static unsigned char i = 0;
P2 = 0xFF;
switch(i)//调用不带标点的数组
{
case 0:Qian = 1;Bai = 1;Shi = 1;Ge = 0;i++;P2 = Smg[a];break;
case 1:Qian = 1;Bai = 1;Shi = 0;Ge = 1;i++;P2 = Smg[b];break;
case 2:Qian = 1;Bai = 0;Shi = 1;Ge = 1;i++;P2 = Smg[c];break;
case 3:Qian = 0;Bai = 1;Shi = 1;Ge = 1;i=0;P2 = Smg[d];break;
default:break;
}
}
void displayI(unsigned char a,unsigned char b,unsigned char c,unsigned char d) //数码管刷新函数代表点
{
static unsigned char i = 0;
P2 = 0xFF;
switch(i)//调用不带标点的数组
{
case 0:Qian = 1;Bai = 1;Shi = 1;Ge = 0;i++;P2 = Smg[a];break;
case 1:Qian = 1;Bai = 1;Shi = 0;Ge = 1;i++;P2 = SmgI[b];break;
case 2:Qian = 1;Bai = 0;Shi = 1;Ge = 1;i++;P2 = SmgI[c];break;
case 3:Qian = 0;Bai = 1;Shi = 1;Ge = 1;i=0;P2 = Smg[d];break;
default:break;
}
}
void keycan()
{
static unsigned char keybuf[]={0xFF,0xFF};
keybuf[0]=(keybuf[0]<<1)|KEY1;
keybuf[1]=(keybuf[1]<<1)|KEY2;
if(keybuf[0]==0xFF)
{
set0 = 1;
}
else if(keybuf[0]==0x00)
{
set0 = 0;
}
else
{}
if(keybuf[1]==0xFF)
{
set1 = 1;
}
else if(keybuf[1]==0x00)
{
set1 = 0;
}
else
{}
}
void keyset()
{
if(set0!=backup0)
{
backup0 = set0;
if(set0==0)
{
flg0++;
if(flg0>5)
{
flg0=0;
}
}
}
switch(flg0)
{
case 1: P2 = 0xFF;Qian = 1;Bai = 1;Shi = 1;Ge = 0;P2 = Smg[SmgTmp[0]];//小时的个位
P2 = 0xFF;Qian = 1;Bai = 1;Shi = 0;Ge = 1;P2 = SmgI[SmgTmp[1]];break; //小时的十位
case 2: P2 = 0xFF;Qian = 1;Bai = 0;Shi = 1;Ge = 1;P2 = SmgI[SmgTmp[2]];//分钟的个 位
P2 = 0xFF;Qian = 0;Bai = 1;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[3]];break;//分钟的十位
case 3: P2 = 0xFF;Qian = 1;Bai = 1;Shi = 1;Ge = 0;P2 = Smg[SmgTmp[4]];//月份的个位
P2 = 0xFF;Qian = 1;Bai = 1;Shi = 0;Ge = 1;P2 = Smg[SmgTmp[5]];break;//月份的十位
case 4: P2 = 0xFF;Qian = 1;Bai = 0;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[6]];//日期的个位
P2 = 0xFF;Qian = 0;Bai = 1;Shi = 1;Ge = 1;P2 = Smg[SmgTmp[7]];break;//日期十位
case 5: Write_ds1302_CE(7,0x00);
Write_ds1302_CE(1,SmgTmp[1]<<4|SmgTmp[0]);
Write_ds1302_CE(2,SmgTmp[3]<<4|SmgTmp[2]);
Write_ds1302_CE(3,SmgTmp[5]<<4|SmgTmp[4]);
Write_ds1302_CE(4,SmgTmp[7]<<4|SmgTmp[6]);
Write_ds1302_CE(7,0x80);
flg0 = 0;
default:break;
}
if(flg0!=0)
{
if(set1!=backup1)
{
backup1 = set1;
if(set1==0)
{
switch(flg0)
{
case 1: Tmp[0]=(SmgTmp[1]*10)+SmgTmp[0];Tmp[0]++;if(Tmp[0]>=60)Tmp[0]=0;SmgTmp[0]=Tmp[0]%10;SmgTmp[1]=Tmp[0]/10;break;
case 2: Tmp[1]=(SmgTmp[3]*10)+SmgTmp[2];Tmp[1]++;if(Tmp[1]>=24)Tmp[1]=0;SmgTmp[2]=Tmp[1]%10;SmgTmp[3]=Tmp[1]/10;break;
case 3: Tmp[2]=(SmgTmp[5]*10)+SmgTmp[4];Tmp[2]++;if(Tmp[2]>=31)Tmp[2]=0;SmgTmp[4]=Tmp[2]%10;SmgTmp[5]=Tmp[2]/10;break;
case 4: Tmp[3]=(SmgTmp[7]*10)+SmgTmp[6];Tmp[3]++;if(Tmp[3]>=12)Tmp[3]=0;SmgTmp[6]=Tmp[3]%10;SmgTmp[7]=Tmp[3]/10;break;
default:break;
}
}
}
}
}
void interruptTime() interrupt 1 //定时器0
{
static unsigned int i;
TH0=T0RH;
TL0=T0RL;
i++;
if(i==6000)
{
i=0;
flg=~flg;
}
if(flg0==0)
{
if(flg == 1)
{
if(gb==0)
{
display(SmgTmp[0],SmgTmp[1],SmgTmp[2],SmgTmp[3]);
}
else
{
displayI(SmgTmp[0],SmgTmp[1],SmgTmp[2],SmgTmp[3]);
}
}
else
{
display(SmgTmp[4],SmgTmp[5],SmgTmp[6],SmgTmp[7]);
}
}
keycan();
}
void interruptUART() interrupt 4 //串口
{
static unsigned char i;
if(RI)
{
RI = 0;
i = SBUF;
SBUF = SmgTmp[i];
}
if(TI)
{
TI = 0;
}
}
复制代码
作者:
heart请问
时间:
2018-3-5 16:24
按键扫描或者数码管显示时间,,,,找一找
作者:
创太#铭
时间:
2018-3-5 17:43
第一:数码管调节时间一个暗一个亮的 这句话是什么意思? 是你调节的时候一个数码管亮,一个数码管暗。还是调节的时候闪烁。
第二 :是不是在调节的时候就会这样,其他使用的时候会吗?
硬件如果没有问题, 就查找延时 可是我没发现
格式我就不多说了
unsigned char flg = 1;//决定显示日期还是时间
这个是什么意思 !
主程序最好设置轮询机制不然, 万一卡死怎么办。
作者:
lele4090039
时间:
2018-3-6 13:11
创太#铭 发表于 2018-3-5 17:43
第一:数码管调节时间一个暗一个亮的 这句话是什么意思? 是你调节的时候一个数码管亮,一个数码管暗。还 ...
初学者,抱歉。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1