四位共阳极数码管显示函数_新手求助四位共阳数码管显示函数

这个程序展示了如何使用C语言控制四位共阳极数码管显示时分秒、年月日星期,并实现按键修改时间的功能。通过DS1302实时时钟获取时间数据,使用数码管共阳极码表转换数字到段码,同时包含闪烁效果和整点报时。程序中定义了显示模式、闪烁计时和按键处理函数。
摘要由CSDN通过智能技术生成

#include

#include "DS1302.H"

sbit K_S = P1^0;    //显示模式sbit K_M = P1^1;    //修改sbit K_I = P1^2;    //加sbit K_D = P1^3;    //减

sbit Spk = P1^7;    //蜂鸣器

//共阳码表unsigned char code TABLE[]={

0xC0,/*0*/

0xF9,/*1*/

0xA4,/*2*/

0xB0,/*3*/

0x99,/*4*/

0x92,/*5*/

0x82,/*6*/

0xF8,/*7*/

0x80,/*8*/

0x90,/*9*/

0xBF,/*-*/

};

unsigned char SEG[6];                   //6位数码管对应缓冲区unsigned char state = 0;                //显示模式位unsigned char modify = 0;               //修改模式位

#define MC_H    25                      //修改状态下闪烁频率,越大闪烁越慢unsigned char mc = 0;                   //闪烁计时

//延时函数,每单位1msvoid Delay(unsigned int t)

{

unsigned int a,b;

for (a=0; a

for (b=0; b<122; b++)

;

}

//6位数码管显示函数void Display(void)

{

unsigned char i;

SYSTEMTIME T;

DS1302_GetTime_ALL(&T);                     //读时间数据

if (modify == 0 && T.Minute == 0 && T.Second < 2)

{                                           //整点报时,修改模式下不报,只响2秒        Spk = 0;

} else {

Spk = 1;

}

if (state == 0)                             //显示时分秒    {

SEG[0] = TABLE[T.Hour / 10];            //时十位        SEG[1] = TABLE[T.Hour % 10] & 0x7F;     //时个位,小数点点亮做分隔        SEG[2] = TABLE[T.Minute / 10];          //分十位        SEG[3] = TABLE[T.Minute % 10] & 0x7F;   //分个位,小数点点亮做分隔        SEG[4] = TABLE[T.Second / 10];          //秒十位        SEG[5] = TABLE[T.Second % 10] & 0x7F;   //秒个位,小数点点亮做分隔    } else if (state == 1)                      //显示年份    {

SEG[0] = 0xFF;                          //不显示        SEG[1] = TABLE[T.tYear / 10];           //年千位        SEG[2] = TABLE[T.tYear % 10];           //年百位        SEG[3] = TABLE[T.Year / 10];            //年十位        SEG[4] = TABLE[T.Year % 10];            //年个位        SEG[5] = 0xFF;                          //不显示    } else if (state == 2)                      //显示月日星期    {

SEG[0] = TABLE[T.Month / 10];           //月十位        SEG[1] = TABLE[T.Month % 10] & 0x7F;    //月个位,小数点点亮做分隔        SEG[2] = TABLE[T.Day / 10];             //日十位        SEG[3] = TABLE[T.Day % 10];             //日个位        SEG[4] = TABLE[10];                     //符号‘-’做分隔        SEG[5] = TABLE[T.Week - 1];                 //星期    }

if (modify && (mc > MC_H)) {        //修改状态下,对应位闪烁,        switch (modify)                 //通过查询当前修改状态确定闪烁位。        {

case 1:                         //时闪烁            SEG[0] = SEG[1] = 0xFF;     //对于共阳管,段码写0xFF即关闭不显示,得到闪烁效果            break;

case 2:                         //分闪烁            SEG[2] = SEG[3] = 0xFF;

break;

case 3:                         //秒闪烁            SEG[4] = SEG[5] = 0xFF;

break;

case 4:                         //年高两位闪烁            SEG[1] = SEG[2] = 0xFF;

break;

case 5:                         //年低两位闪烁            SEG[3] = SEG[4] = 0xFF;

break;

case 7:                         //月闪烁            SEG[0] = SEG[1] = 0xFF;

break;

case 8:                         //日闪烁            SEG[2] = SEG[3] = 0xFF;

break;

case 9:                         //星期闪烁            SEG[5] = 0xFF;

break;

}

}

for (i=0; i<6; i++)                 //数码管动态扫描    {

P0 = SEG[ i ];                    //送段码        P2 = ~(0x20 >> i);              //送位码        Delay(1);

P2 = 0xFF;                      //消影    }

if (++mc > 2 * MC_H)

mc = 0;

}

//按键处理函数void Key(void)

{

unsigned char t;

P1 |= 0x0F;

if (!K_S)                                       //按键按下    {

Delay(10);                                  //延时消抖        if (!K_S)                                   //按键确实按下        {

if (!modify)                            //非修改模式下用于切换显示模式            {

if (++state > 2)

state = 0;

}

if (modify)                             //如果在修改模式下,            {

modify = 0;                         //就退出修改模式,                DS1302_WriteData(0x8e,0x80);        //并打开写保护            }

}

while (!K_S)                                //等待按键释放            Display();

}

if (!K_M)

{

Delay(10);

if (!K_M)

{

if (modify == 0)                        //进入修改模式,            {

modify = 3 * state + 1;             //根据显示模式确定modify初值,时分秒123,年45,月日星期789                DS1302_WriteData(0x8e,0x00);        //关闭写保护            } else {

modify++;

switch (state)                      //根据显示模式确定modify初值                {

case 0:

case 2:

if (modify > (3 * state + 3))   //时分秒,日星期模式下每个是3位                    {

modify = 0;

DS1302_WriteData(0x8e,0x80);//打开写保护                    }

break;

case 1:

if (modify > (3 * state + 2))   //年模式下是2位                    {

modify = 0;

DS1302_WriteData(0x8e,0x80);//打开写保护                    }

break;

}

}

}

while (!K_M)

Display();

}

if (!K_I)

{

Delay(10);

if (!K_I)

{

switch (modify)                         //根据当前修改状态确定修改什么值            {

case 0:

break;

case 1:                                 //小时                t = BCD2DEC(DS1302_ReadData(DS1302_HOUR + 1));

if (++t > 23)                       //不能超过23                    t = 0;

DS1302_WriteData(DS1302_HOUR, DEC2BCD(t));

break;

case 2:                                 //分                t = BCD2DEC(DS1302_ReadData(DS1302_MINUTE + 1));

if (++t > 59)                       //不能超过59                    t = 0;

DS1302_WriteData(DS1302_MINUTE, DEC2BCD(t));

break;

case 3:                                 //秒                t = BCD2DEC(DS1302_ReadData(DS1302_SECOND + 1));

if (++t > 59)

t = 0;

DS1302_WriteData(DS1302_SECOND, DEC2BCD(t));

break;

case 4:                                 //年高两位                t = BCD2DEC(DS1302_ReadData(DS1302_TYEAR + 1));

if (++t > 29)                       //不能超过29,最小19                    t = 19;

DS1302_WriteData(DS1302_TYEAR, DEC2BCD(t));

break;

case 5:                                 //年低两位                t = BCD2DEC(DS1302_ReadData(DS1302_YEAR + 1));

if (++t > 99)                       //不能超过99                    t = 0;

DS1302_WriteData(DS1302_YEAR, DEC2BCD(t));

break;

case 7:                                 //不能超过12                t = BCD2DEC(DS1302_ReadData(DS1302_MONTH + 1));

if (++t > 12)

t = 1;

DS1302_WriteData(DS1302_MONTH, DEC2BCD(t));

break;

case 8:                                 //日                t = BCD2DEC(DS1302_ReadData(DS1302_DAY + 1));

if (++t > DS1302_GetTheDay())       //最大日期不能超过当月最大值                    t = 1;

DS1302_WriteData(DS1302_DAY, DEC2BCD(t));

break;

case 9:                                 //星期                t = BCD2DEC(DS1302_ReadData(DS1302_WEEK + 1));

if (++t > 7)                        //不能超过7                    t = 1;

DS1302_WriteData(DS1302_WEEK, DEC2BCD(t));

break;

}

}

while (!K_I)

Display();

}

if (!K_D)       //减    {

Delay(10);

if (!K_D)

{

switch (modify)

{

case 0:

break;

case 1:     //小时                t = BCD2DEC(DS1302_ReadData(DS1302_HOUR + 1));

if (t > 0)

t--;

else

t = 23;

DS1302_WriteData(DS1302_HOUR, DEC2BCD(t));

break;

case 2:     //分                t = BCD2DEC(DS1302_ReadData(DS1302_MINUTE + 1));

if (t > 0)

t--;

else

t = 59;

DS1302_WriteData(DS1302_MINUTE, DEC2BCD(t));

break;

case 3:     //秒                t = BCD2DEC(DS1302_ReadData(DS1302_SECOND + 1));

if (t > 0)

t--;

else

t = 59;

DS1302_WriteData(DS1302_SECOND, DEC2BCD(t));

break;

case 4:     //年高两位                t = BCD2DEC(DS1302_ReadData(DS1302_TYEAR + 1));

if (t > 19)

t--;

else

t = 29;

DS1302_WriteData(DS1302_TYEAR, DEC2BCD(t));

break;

case 5:     //年低两位                t = BCD2DEC(DS1302_ReadData(DS1302_YEAR + 1));

if (t > 0)

t--;

else

t = 99;

DS1302_WriteData(DS1302_YEAR, DEC2BCD(t));

break;

case 7:     //月                t = BCD2DEC(DS1302_ReadData(DS1302_MONTH + 1));

if (t > 1)

t--;

else

t = 12;

DS1302_WriteData(DS1302_MONTH, DEC2BCD(t));

break;

case 8:     //日                t = BCD2DEC(DS1302_ReadData(DS1302_DAY + 1));

if (t > 1)

t--;

else

t = DS1302_GetTheDay();

DS1302_WriteData(DS1302_DAY, DEC2BCD(t));

break;

case 9:     //星期                t = BCD2DEC(DS1302_ReadData(DS1302_WEEK + 1));

if (t > 1)

t--;

else

t = 7;

DS1302_WriteData(DS1302_WEEK, DEC2BCD(t));

break;

}

}

while (!K_D)

Display();

}

}

//主函数void main(void)

{

Spk = 1;                        //关蜂鸣器

DS1302_Init();                  //1302初始化

while (1)                       //主循环    {

Display();                  //显示        Key();                      //按键处理

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值