基于51单片机+74LS138译码器+8位共阴数码管时钟设计—按键修改时间
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于51单片机+74LS138译码器+8位共阴数码管时钟设计—按键修改时间相关的知识,希望对你有一定的参考价值。
基于51单片机+74LS138译码器+8位数码管时钟设计—按键修改时间
通过74LS138译码器+8位共阴数码管配合实现时钟设计
为什么强调8位的数码管一定要是共阴的,因为,如果是采用共阳的8数码管是没法实现对数码管的每一个位进行控制的,这是由于74LS138输出特性所决定的。
- 采用74LS138译码器可以节省4个IO的出来,除了节省IO口还有另外一个重要的原因就是单片机的驱动能力有限,在设计的过程当中,最好是单片机只负责运算和信号处理,驱动的事情交给其他专业的协同芯片来完成,不同芯片都有自己的专攻领地。
- 配合74HC245缓存器来使用效果,至于为什么还需采用外围的芯片驱动,请看上面的信息。
程序代码:
#include<reg51.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//按键定义
sbit key_stop = P2^0;
sbit key_star = P2^1;
sbit key_fen = P2^2;
sbit key_shi = P2^3;
//0~9的十六进制数码
//uchar code num[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 0~9 7SegCA共阳数码管
//1100 0000,1001 1111,
unsigned char code num[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//共阴0-F段码,加code是存在rom里面
//秒、分、时标志
uchar miao = 0, fen = 0, shi = 0;
//秒、分、时高位低位
uchar miao_L, miao_H, fen_L, fen_H, shi_L, shi_H;
//计数
uint counter = 0;
void delay(uint x){ //毫秒延时函数
unsigned int i=0,j=0;
for(i=0;i<x;i++)
for(j=0;j<123;j++);
;
}//delay
void key_delay(int xms){ //按键延时函数 x ms
unsigned int i, j;
for(i=0; i<xms; ++i)
for(j=0; j<110; ++j)
;
}//key_delay
void T0_Init(){ //定时器初始化
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
EA = 1; //开总中断
ET0 = 1;
TR0 = 1;
}//T0_Init
void display(){ //显示函数
//P1 = 0x20; //0010 0000共阳数码管
//P1 =0xdf; //1101 1111共阴数码管
P1=5; //这是采用74LS138来实现控制的
P0 = 0x40; //段选显示-
delay(2);
// P1 = 0x04; //位选0000 0100
// P1 =0xfb; //1111 1011
P1 = 2;
P0 = 0x40;//段选显示-
delay(2);
//P1 = 0x40; // 1000 0000
//P1=0X7F; //0111 1111
P1 = 7;
P0 = num[miao_L];
delay(2);
// P1 = 0x80; // 0100 0000
// P1=0XBF; //1011 1111
P1 = 6;
P0 = num[miao_H];
delay(2);
// P1 = 0x08; // 0001 0000
// P1=0XEF; //1110 1111
P1 = 4;
P0 = num[fen_L];
delay(2);
// P1 = 0x10; // 0000 1000
// P1=0XF7; //1111 0111
P1 = 3;
P0 = num[fen_H];
delay(2);
// P1 = 0x01; // 0000 0010
// P1=0XFD; //1111 1101
P1 = 1;
P0 = num[shi_L];
delay(5);
// P1 = 0x02; // 0000 0001
// P1=0XFE; //1111 1110
P1 = 0;
P0 = num[shi_H];
delay(5);
}//display
void keyscan(){ //按键函数
if(key_stop == 0){
key_delay(10);
if(key_stop == 0){
EA = 0; //关总中断,即停止
while(!key_stop);
}
}//key_stop
if(key_star == 0){
key_delay(10);
if(key_star == 0){
EA = 1; //开总中断
while(!key_star);
}
}//key_star
if(key_fen == 0){
key_delay(10);
if(key_fen == 0){
fen++;
while(!key_fen);
}
}//key_fen++
if(key_shi == 0){
key_delay(10);
if(key_shi == 0){
shi++;
while(!key_shi);
}
}//key_shi++
}
void main(){
T0_Init();
while(1){
display();
keyscan();
}
}
void timer0_Init() interrupt 1
{ //中断函数
TL0 =(65536-50000)%256;//50ms预装载值
TH0 =(65536-50000)/256;
counter++;
//1秒钟=50ms*20=1000ms,20次计数为1秒钟
if(counter == 20){
counter = 0;
miao++; //i = 100
if(miao == 60){
miao = 0;
fen++;
if(fen == 60){
fen = 0;
shi++;
if(shi == 24){
shi = 0;
fen = 0;
miao = 0;
}
}
}
miao_L = miao%10;
miao_H = miao/10;
fen_L = fen%10;
fen_H = fen/10;
shi_L = shi%10;
shi_H = shi/10;
}
}//timer0_Init
对位选代码进行封装优化后的代码
//#include<reg51.h>
#include <STC89C5xRC.H>
typedef unsigned char uchar;
typedef unsigned int uint;
//按键定义
sbit key_stop = P2^0;
sbit key_star = P2^1;
sbit key_fen = P2^2;
sbit key_shi = P2^3;
//0~9的十六进制数码
//uchar code num[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 0~9 7SegCA共阳数码管
//1100 0000,1001 1111,
unsigned char code num[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//共阴0-F段码,加code是存在rom里面
//秒、分、时标志
uchar miao = 0, fen = 0, shi = 0;
//秒、分、时高位低位
uchar miao_L, miao_H, fen_L, fen_H, shi_L, shi_H;
//计数
uint counter = 0;
void Nixie(unsigned char Location);
void delay(uint x) { //毫秒延时函数
unsigned int i=0,j=0;
for(i=0; i<x; i++)
for(j=0; j<123; j++);
;
}//delay
void key_delay(int xms) { //按键延时函数 x ms
unsigned int i, j;
for(i=0; i<xms; ++i)
for(j=0; j<110; ++j)
;
}//key_delay
void T0_Init() { //定时器初始化
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
EA = 1; //开总中断
ET0 = 1;
TR0 = 1;
}//T0_Init
void display() { //显示函数
//P1 = 0x20; //0010 0000共阳数码管
//P1 =0xdf; //1101 1111共阴数码管
// P1=5; //这是采用74LS138来实现控制的
Nixie(5);
P0 = 0x40; //段选显示-
delay(2);
// P1 = 0x04; //位选0000 0100
// P1 =0xfb; //1111 1011
// P1 = 2;
Nixie(2);
P0 = 0x40;//段选显示-
delay(2);
//P1 = 0x40; // 1000 0000
//P1=0X7F; //0111 1111
// P1 = 7;
Nixie(7);
P0 = num[miao_L];
delay(2);
// P1 = 0x80; // 0100 0000
// P1=0XBF; //1011 1111
// P1 = 6;
Nixie(6);
P0 = num[miao_H];
delay(2);
// P1 = 0x08; // 0001 0000
// P1=0XEF; //1110 1111
// P1 = 4;
Nixie(4);
P0 = num[fen_L];
delay(2);
// P1 = 0x10; // 0000 1000
// P1=0XF7; //1111 0111
// P1 = 3;
Nixie(3);
P0 = num[fen_H];
delay(2);
// P1 = 0x01; // 0000 0010
// P1=0XFD; //1111 1101
// P1 = 1;
Nixie(1);
P0 = num[shi_L];
delay(5);
// P1 = 0x02; // 0000 0001
// P1=0XFE; //1111 1110
// P1 = 0;
Nixie(0);
P0 = num[shi_H];
delay(5);
}//display
void keyscan() { //按键函数
if(key_stop == 0) {
key_delay(10);
if(key_stop == 0) {
EA = 0; //关总中断,即停止
while(!key_stop);
}
}//key_stop
if(key_star == 0) {
key_delay(10);
if(key_star == 0) {
EA = 1; //开总中断
while(!key_star);
}
}//key_star
if(key_fen == 0) {
key_delay(10);
if(key_fen == 0) {
fen++;
while(!key_fen);
}
}//key_fen++
if(key_shi == 0) {
key_delay(10);
if(key_shi == 0) {
shi++;
while(!key_shi);
}
}//key_shi++
}
void main() {
T0_Init();
while(1) {
display();
keyscan();
}
}
void timer0_Init() interrupt 1 { //中断函数
TL0 =(65536-50000)%256;//50ms预装载值
TH0 =(65536-50000)/256;
counter++;
//1秒钟=50ms*20=1000ms,20次计数为1秒钟
if(counter == 20) {
counter = 0;
miao++; //i = 100
if(miao == 60) {
miao = 0;
fen++;
if(fen == 60) {
fen = 0;
shi++;
if(shi == 24) {
shi = 0;
fen = 0;
miao = 0;
}
}
}
miao_L = miao%10;
miao_H = miao/10;
fen_L = fen%10;
fen_H = fen/10;
shi_L = shi%10;
shi_H = shi/10;
}
}//timer0_Init
void Nixie(unsigned char Location){
switch(Location) {
case 0 ://秒低位,Y0=0
P10=0x00;
P11=0x00;
P12=0x00;
break;
case 1 ://时低位,Y1
P10=0x01;
P11=0x00;
P12=0x00;
break;
case 2 ://时分间隔位-
P10=0x00;
P11=0x01;
P12=0x00;
break;
case 3 ://分高位,Y3
P10=0x01;
P11=0x01;
P12=0x00;
break;
case 4 ://分低位,Y4
P10=0x00;
P11=0x00;
P12=0x01;
break;
case 5 ://秒分间隔位-
P10=0x01;
P11=0x00;
P12=0x01;
break;
case 6 ://秒高位,Y6
P10=0x00;
P11=0x01;
P12=0x01;
break;
case 7 ://秒低位,Y7
P10=0x01;
P11=0x01;
P12=0x01;
break;
}
}
以上是关于基于51单片机+74LS138译码器+8位共阴数码管时钟设计—按键修改时间的主要内容,如果未能解决你的问题,请参考以下文章
51单片机+DS1302+MAX7219驱动8位共阴数码管显示时间