用89C51单片机设计一个可以让串口控制两个数码管正常工作,补充电路图。并写出能让两位数码管重0到99显示

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-29
用AT89C51单片机控制LED数码管能够显示时间和日期,求电路图和程序代码

这是一个朋友做的,你可以参考一下:

#include #define uchar unsigned char#define uint unsigned intsbit db=P2^7;char i,sec,min,h,date,month,year,flag;uchar j,k,m,n,o,p;sbit dula=P2^0;sbit wela1=P2^1;sbit wela2=P2^2;sbit key_ch=P3^5;sbit key_add=P3^6;sbit key_minus=P3^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void init();void delay(uint);void second_display();void minute_display();void hour_display();void date_display();void month_display();void year_display();void control();void time();void main(){ init(); while(1) { second_display(); minute_display(); hour_display(); date_display(); month_display(); year_display(); control(); }}void init(){ db=0; i=0; sec=0; min=0; h=0; date=1; month=1; year=1; flag=0; wela1=0; wela2=0; EA=1; ET0=1; TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1;}void delay(uint z){ uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--);}void second_display(){ int sec_shi,sec_ge; sec_shi=sec/10; sec_ge=sec%10;
if(flag==1&&j!=1) j++; else { j=0; dula=1; P0=~table[sec_ge]; dula=0; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x20; wela2=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[sec_shi]; dula=0; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x10; wela2=0; delay(1); dula=1; P0=0xff; dula=0; }}void minute_display(){ int min_shi,min_ge; min_shi=min/10; min_ge=min%10; if(flag==2&&k!=1) k++; else { k=0; dula=1; P0=~table[min_ge]; dula=0; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x08; wela2=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[min_shi]; dula=0; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x04; wela2=0; delay(1); dula=1; P0=0xff; dula=0; }}void hour_display(){ int h_shi,h_ge; h_shi=h/10; h_ge=h%10; if(flag==3&&m!=1) m++; else { m=0; dula=1; P0=~table[h_ge]; dula=0; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x02; wela2=0; delay(1); dula=1; P0=0xff; dula=0; delay(1); dula=1; P0=~table[h_shi]; dula=0; wela1=1; P1=0x00; wela1=1; P1=0x00; wela1=0; wela2=1; P1=0x01; wela2=0; delay(1); dula=1; P0=0xff; dula=0; wela2=0; delay(1); } }void date_display(){ int date_shi,date_ge; date_shi=date/10; date_ge=date%10;
if(flag==4&&n!=1) n++; else { n=0; dula=1; P0=~table[date_ge]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x80; wela1=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[date_shi]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x40; wela1=0; delay(1); dula=1; P0=0xff; dula=0; }}void month_display(){ int month_shi,month_ge; month_shi=month/10; month_ge=month%10;
if(flag==5&&o!=1) o++; else { o=0; dula=1; P0=~table[month_ge]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x20; wela1=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[month_shi]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x10; wela1=0; delay(1); dula=1; P0=0xff; dula=0; }}void year_display(){ int year_qian,year_bai,year_shi,year_ge; year_qian=year/1000; year_bai=year%1000/100; year_shi=year%1000%100/10; year_ge=year%10;
if(flag==6&&p!=1) p++; else { p=0; dula=1; P0=~table[year_ge]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x08; wela1=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[year_shi]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x04; wela1=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[year_bai]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x02; wela1=0; delay(1); dula=1; P0=0xff; dula=0; dula=1; P0=~table[2]; dula=0; wela2=1; P1=0x00; wela2=0; wela1=1; P1=0x01; wela1=0; delay(1); dula=1; P0=0xff; dula=0; wela1=0; }}void control(){ if(!key_ch) { delay(5); if(!key_ch) { flag++; if(flag==7) flag=0; } } while(!key_ch); if(flag==1&&key_add==0) { while(!key_add); sec++; if(sec==60) sec=0; } if(flag==1&&key_minus==0) { while(!key_minus); sec--; if(sec==-1) sec=59; }
if(flag==2&&key_add==0) { while(!key_add); min++; if(min==60) min=0; } if(flag==2&&key_minus==0) { while(!key_minus); min--; if(min==-1) min=59; }
if(flag==3&&key_add==0) { while(!key_add); h++; if(h==24) h=0; } if(flag==3&&key_minus==0) { while(!key_minus); h--; if(h==-1) h=23; }
if(flag==4&&key_add==0) { while(!key_add); date++; if(date==29) if((year%4!=0)&&(month==2)) date=1; if(date==30) if((year%4==0)&&(month==2)) date=1; if(date==31) if((month==4)||(month==6)||(month==9)||(month==11)) date=1; if(date==32) if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)) date=1; }
if(flag==5&&key_add==0) { while(!key_add); month++; if(month==13) month=1; } if(flag==5&&key_minus==0) { while(!key_minus); month--; if(month==0) month=12; }
if(flag==6&&key_add==0) { while(!key_add); year++; if(year==99) year=1; } if(flag==6&&key_minus==0) { while(!key_minus); year--; if(year==0) year=99; } }
void T0_rpt() interrupt 1{ TH0=(65536-50000)/256; TL0=(65536-50000)%256; i++; time();}
void time(){ if(i==20) { i=0; sec++; if(sec==60) { sec=0; min++; if(min==60) { min=0; h++; if(h==24) { h=0; min=0; sec=0; date++; if(date==29) if((year%4!=0)&&(month==2)) { date=1; month++; if(month==13) { month=1; year++; } } if(date==30) if((year%4==0)&&(month==2)) { date=1; month++; if(month==13) { month=1; year++; } } if(date==31) if((month==4)||(month==6)||(month==9)||(month==11)) { date=1; month++; if(month==13) { month=1; year++; } } if(date==32) if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)) { date=1; month++; if(month==13) { month=1; year++; } } } } } } }

这个我仿真过了 是有用的,,,是从00开始显示 到了99会从新开始从00开始加
#include
#define uchar unsigned char
#define uint unsigned int
uchar code disp[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code bit_tab[]={0xfe,0xfd};
uchar disp_buf[2];
uchar shu;
uchar count;
void delay(uchar x)
{
uchar i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void conv(uchar flag)
{
disp_buf[0]=flag/10;
disp_buf[1]=flag%10;
}
void display()
{
uchar tem,wei;
P2=bit_tab[wei];
tem=disp_buf[wei];
P0=disp[tem];
wei++;
if(wei==2)
wei=0;
}
void time0(void) interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(++count==40)
{
count=0;
shu++;
if(shu==99)
shu=0;
}
}
void time1(void) interrupt 3
{
TH1=(65536-5000)/256;
TL1=(65536-5000)%256;
display();
}
void init()
{
TMOD=0x11;
EA=1;
ET0=1;
ET1=1;
TR1=1;
TR0=1;
}
main()
{
init();
while(1)
{
conv(shu);
}
}

帮你分析一下:
该题是用单片机的串口,传送数据送给2位数码管显示,串口要选择工作在方式0,即做同步移位寄存器使用,工作在发送状态,用RXD做数据线,TXD做同步时钟使用。
然后可以编程,发送如上数据为11111110B,测试数码管a段是否正常能亮。
程序就不帮你写了,做为学生要自己动手,考试题要自己答才行。有了上面的编程思路,这道题你是可以做出来的,加油吧。

这是一个动态数码管扫描的程序,,用串口控制自己写。只要让程序判断RXD是否等于
11111110B也就是十六进制0xfe。如果等于就让数码管段A打开。

#include<stc.h>
#define ur unsigned char
#define ut unsigned int
ur code shz[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00};
sbit d0=P1^0;
sbit d1=P1^1;
sbit d2=P1^2;
sbit d3=P1^3;
sbit d4=P1^4;
sbit d5=P1^5;
sbit d6=P1^6;
sbit d7=P1^7; //数码管的7个段选
ut y; //全局变量
void ys(ut); //延时声明
void smg(ut); //数码动态显示程序声明
void main()
{

TMOD=0x01; //中断工作方式
TH0=(65536-50000)/256; //给寄存器高8位设置初值
TL0=(65536-50000)%256; //给寄存器低8位设置初值
EA=1; //开总中断
ET0=1; //打开T0中断
TR0=1; //启动T0中断

while(1)
{

smg(y);
}
}

void smg(ut i)
{
ut a,t1,t2,t3,t4,t5; //定义了四个变量,这四个变量分别存放个位、十位、百位、千位的数值。

t1=i/10000; //T1存放万位
t2=i%10000/1000; //T2存放千位
t3=i%1000/100; //T3存放百位
t4=i%100/10; //T4存放十位
t5=i%10; //T5存放个位

P1=0; //关闭数码管所有的位选
P0=shz[t5]; //把万位送给P0
d0=1; //打开万的位选
ys(5000); //延时
d0=0; //关闭位选

if(y>=10) //判断只有定时变量Y,大于等于10时在执行十位的动态扫描 这样就可以关闭等待的数码管
{
P0=shz[t4]; //把千位送给P0
d1=1; //打开千的位选
ys(5000); //延时
d1=0; //关闭位选
}
if(y>=100) //判断只有定时变量Y,大于等于100时在执行百位的动态扫描
{
P0=shz[t3]; //如上
d2=1;
ys(5000);
d2=0;
}

if(y>=1000) //判断只有定时变量Y,大于等于1000时在执行千位的动态扫描
{
P0=shz[t2]; //如上
d3=1;
ys(5000);
d3=0;
}
if(y>=10000) //判断只有定时变量Y,大于等于10000时在执行万位的动态扫描
{
P0=shz[t1]; //如上
d4=1;
ys(5000);
d4=0;
}
}

/*-----延时程序-----*/
void ys(ut z)
{
ut x,y;
fou(x=z;x>0;x--)
fou(y=110;y>0;y--);
}
/*------中断程序------*/
void shzd() interrupt 1
{
ut x;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
x++;
if(x==20)
{
y++;
if(y<10000)y=0;
x=0;

}
}

  • 用89C51单片机设计一个可以让串口控制两个数码管正常工作,补充电路图...
    答:帮你分析一下:该题是用单片机的串口,传送数据送给2位数码管显示,串口要选择工作在方式0,即做同步移位寄存器使用,工作在发送状态,用RXD做数据线,TXD做同步时钟使用。然后可以编程,发送如上数据为11111110B,测试数码管a段是否正常能亮。程序就不帮你写了,做为学生要自己动手,考试题要自己答才行...
  • 请问用89c51单片机设计交通灯可以将发光二级管串联电阻后直接接到P口...
    答:可以 电阻150欧姆或者200欧姆
  • 单片机89C51串行口有几种工作方式?工作方式帧格式如何?
    答:通过设置SCON可以设置串行口的工作方式,相应设置位是SM0,SM1,共有四种方式\x0d\x0a方式0:为同步移位寄存器的输入输出方式,一般用于扩展I/O口,数据位为8位,无起始停止位\x0d\x0a方式1:波特率可调的异步通信方式,数据位为10位,1位起始位,8位数据位,1位停止位\x0d\x0a方式2:波特...
  • 89c51单片机串口通信方式1波特率由什么决定,怎样实现波特率可变?_百度知...
    答:In the 89C51, the baud rates in Modes 1 and 3 are determined by the Timer 1 overflow rate.在89C51系列中,串口通信方式1和3的可变波特率,是由定时器1的溢出速率决定的。通过调整定时器1初值,即可改变定时器1溢出时间、从而改变波特率。
  • 89C51系列单片机串口通信的四种方式极其特点
    答:89C51单片机串口通信 串行窗口,是看不见敲进去的字符的。 要想看见,须再用一个串行窗口。简述MCS-51单片机串口通信的四种方式及其特点 方式 0 :这种工作方式比较特殊,与常见的微型计算机的串行口不同,它又叫同步移位寄存器输出方式。在这种方式下,数据从 RXD 端串行输出或输入,同步信号从 TXD...
  • 89C51串行通信中,单片机如何自动调节波特率,望高手指点!(最好有详细...
    答:指令来达到目的的,因为每条指令为1-3个指令周期,可即是通过若干个指令周期来进行延时的,单片机常用11.0592M的的晶振,现在我要告诉你这个奇怪数字的来历。用此频率则每个指令周期 的时间为(12/11.0592)us,那么波特率为9600BPS每位要间融多少个指令周期呢?指令周期s=(1000000/9600)/(12/11.0592)...
  • 两个89C51单片机串行通信应如何连接
    答:1号单片机的TXD(发射)接2号单片机的RXD(接收)。1号单片机的RXD接2号单片机的TXD。共地。
  • 89C51单片机驱动一只红色LED需要串联多大的电阻
    答:普通3mm红色LED,如果想低功耗,5.1K就可以亮,但不是很亮,如果功耗无所谓,可以用2K或1K的都可以,1/4W足够了。亮度太高了,寿命会有降低。蜂鸣器有很多种,要不要串电阻?看蜂鸣器了。
  • 89c51单片机程序设计!!!
    答:题目的要求可以理解为,将电压的变化以二进制数字的形式表示出来(即用发光 二极管来表示二进制数)。硬件需要单片机、发光二极管、ad转化器(如TLC549)下面提供一个例子。/ 文件名 : TLC549.c 描述 : TLC549是一个新型的AD转换器,具有8位的分辨率,具有控制简单,体积小的优点。/ include<re...
  • c语言编一段小程序,在液晶屏上实现显示"ABCD1234".用单片机AT 89c51
    答:unsigned char code string[ ]={"ABCD1234"}; //字符串数组,存储待显示的字符串 / 函数功能:延时1ms (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒 / void delay1ms(){ unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);} / 函数功能:延时若干毫秒 入口...