共阳数码管 LED指示灯共阳
W1-位1-P2.4
W2-位2-P2.7
W3-位3-P2.6
W4-位4-P2.5
数码管段:P0口
LED指示灯阴极;P1口+P2.0--P2.3口
K1 P3.2
K2 P3.3
共阳是码管顺序:由上至下顺时针 W1 a f W2 W3 b---W4 g c dp d e
制作出来的实物图如下:
单片机源程序如下:
/***************************************************************************
数码管的显示 LED 个性时钟
单片机:STC12C5A60S2或STC89C52RC
调时间时按键有连发功能
******************************************************************************/
//头文件:
#include "reg52.h"
#define yes 1
#define no 0
#define keyon 0 //按键开
#define keyoff 1 //按键关
#define uchar unsigned char
#define uint unsigned int
//变量定义:
unsigned char qian,bai,shi,ge;
unsigned char hour,minute,secont;
unsigned int count;
unsigned char miaocount;
code unsigned char table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管
code unsigned char table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//表:共阳带点数码管 0-9
code unsigned char led[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xf7,
0xfb,0xfd,0xfe};//LED显示数组
#define hidden 0xff;
//引脚定义:
sbit SMG_q=P2^4; //定义数码管阳级控制脚(千位)
sbit SMG_b=P2^7; //定义数码管阳级控制脚(百位)
sbit SMG_s=P2^6; //定义数码管阳级控制脚(十位)
sbit SMG_g=P2^5; //定义数码管阳级控制脚(个位)
//KEY 调整
sbit key1=P3^2;
sbit key2=P3^3;
bit IS5ms; //5ms 标志位
bit IS10ms;//10ms标志位
uchar w;//定义数码管位变量
uchar preset=100;//预设置用来调整时间的精度
/***********************************************/
void init()
{
hour=0;
minute=0; //初始时间设置
TMOD=0x11;//16位定时器0和定时器1的工作方式
TH0=(65536-10027)/256;
TL0=(65566-10027)%256; //10ms 细调
EA=1; //总中断允许
ET0=1; //允许TMR0中断
TR0=1; //启动定时器
TH1=(65536-5000)/256;
TL1=(65566-5000)%256; //5ms
ET1=1;//允许TMR1中断
TR1=1;//启动TMR1
}
/***************************************************/
//显示函数,参数为显示内容
void display()
{
qian=hour/10; //显示时间的千位
bai=hour%10; //显示时间的百位
shi=minute/10; //显示时间的十位
ge=minute%10; //显示时间的个位
if((w==1)&&(qian==0))
{
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=hidden; //千位是0的话进行消隐不显示
}else
{
SMG_q=0;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=table[qian]; //输出显示内容
}
if(w==2) //百位
{
SMG_q=1;
SMG_b=0;
SMG_s=1;
SMG_g=1;
P0=table1[bai]; //输出显示内容
}
if(w==3) //十位
{
SMG_q=1;
SMG_b=1;
SMG_s=0;
SMG_g=1;
P0=table[shi]; //输出显示内容
}
if(w==4) //个位
{
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=0;
P0=table[ge]; //输出显示内容
}
w++; //位循环显示
if(w>4)
{
w=1;
}
}
/*******************************/
/******************************/
void timer0() interrupt 1 //定时器0中断
{
static uchar timecount,num=0;
TH0=(65536-10027)/256;
TL0=(65566-10027)%256; //10ms
timecount++; //10MS*100=1000ms时间计数
if(timecount>=preset) //预置值
{
timecount=0; //清0时间计数
++num; //LED位数+
if(num<=8) //P1口的8位显示
{ P2=0xff;
P1=led[num];
}else if((num>=9)&&(num<=12)) //P2口的4位显示
{
P1=0xff;
P2=led[num];
if(num==12)
{
num=0;
}
}
if(++secont>59) //如果59秒到
{
secont=0;
minute++; //分钟+
if(minute>59) //如果59分到
{
minute=0;
hour++; //时+
if(hour>23) //如果时间大于23点
{
hour=0; //重回到0
}
}
}
}
}
/***********************/
void timer1(void) interrupt 3
{
static uchar count;
TH1=(65536-5000)/256;
TL1=(65566-5000)%256; //5ms,用来进行数码管扫描
IS5ms=yes;
count++;
if(count==2) // 每到10MS进行一次键盘扫描
{
count=0;
IS10ms=yes; //10MS到的标志
}
}
/********************************/
uchar GetKey() //按键扫描函数
{
uchar keyRetu=0; //返回的按键值
static uchar s_keyState=0,keyTime=0; //按键状态,按键按下的时间计数器
switch (s_keyState)
{
case 0:
if(key1==keyon) //检测到有按键按下,转到状态1,相当于是消抖过程
{
s_keyState=1;
}
if(key2==keyon)
{
s_keyState=4;
}
break;
case 1:
if(key1==keyon) //再次检测到有按键,转到状态2
{
s_keyState=2;
keyTime=0; //清零按键时间计数器
}
else
{
s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
}
break;
case 2:
if(key1==keyoff) //检测到按键松开
{
s_keyState=0; //状态转到状态0
keyRetu=1; //输出1
}
else
{
if(++keyTime>=25) //按下时间>0.5s
{
s_keyState=3; //转到状态3
keyTime=0; //清零按键时间计数器
keyRetu=1; // 输出1
}
}
break;
case 3:
if(key1==keyoff) //检测到按键松开
{
s_keyState=0; //状态转到状态0
}
else
{
if(++keyTime>=10) //按下时间>0.2s
{
keyTime=0; //清零按键时间计数器
keyRetu=1; // 输出1
}
}
break;
case 4:
if(key2==keyon) //再次检测到有按键,转到状态5
{
s_keyState=5;
keyTime=0; //清零按键时间计数器
}
else
{
s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
}
break;
//
case 5:
if(key2==keyoff) //检测到按键松开
{
s_keyState=0; //状态转到状态0
keyRetu=2; //输出2
}
else
{
if(++keyTime>=25) //按下时间>0.5s
{
s_keyState=6; //转到状态6
keyTime=0; //清零按键时间计数器
keyRetu=2; // 输出2
}
}
break;
//
case 6:
if(key2==keyoff) //检测到按键松开
{
s_keyState=0; //状态转到状态0
}
else
{
if(++keyTime>=10) //按下时间>0.2s
{
keyTime=0; //清零按键时间计数器
keyRetu=2; // 输出2
}
}
break;
}
return keyRetu; //返回键值
}
/**********************************************/
//主函数,C语言的入口函数:
void main()
{
init(); //端口及定时器初始化
while(1)
//死循环
{
if(IS5ms==yes) //5MS到的标志
{
IS5ms=no;
display(); //调用显示函数
}
if(IS10ms==yes) //10MS到的标志
{
IS10ms=no;
switch(GetKey()) //扫描按键得到键值
{
case 1: //键值处理
hour++;
if(hour>23)
{
hour=0;
}
break;
case 2: //键值处理
minute++;
if(minute>59)
{
minute=0;
}
break;
}
}
}
}
|