一、实验目的和要求
1、进一步熟练Keil uVision3的项目文件创建、编译、运行和软件仿真的基本操作方法;
2、巩固程序调试的方法;
3、熟悉定时器0的定时功能的设计方法,掌握单片机实验箱中数码管显示的电路工作原理。
4、初步熟悉单片机c语言开发方法;
5、用c语言编程实现以下功能:同时驱动8位数码管显示数字时钟,并能动态改变,每隔1s自动加1,要有时分秒。
二、实验仪器和设备
单片机编译软件Keil uVision3,计算机,USB下载线,CT107D单片机综合开发平台
三、实验过程
在本实验的开发平台中,采用了2只四位共阳数码管,根据前面的实验,控制口都是由P0口执行,所以用到了2片74HC573锁存器U7、U8。
开发平台中,均采用了8位数码管动态扫描显示(见图1)。它将所有数码管的8个段线相应地并接在一起,并接到 AT89S52的锁存器U7的Q端,由P0口控制字段(要显示什么数字)输出。而各位数码管的共阳极由也是P0口控制锁存器U8来实现8位数码管的位输出控制。
这样,对于一组数码管动态扫描显示需要由两组信号来控制:一组是字段输出口输出的字形代码,用来控制显示的字形,称为段码;另一组是位输出口输出的控制信号,用来选择第几位数码管工作,称为位码。
由于各位数码管的段线并联,段码的输出对各位数码管来说都是相同的。因此,在同一时刻如果各位数码管的位选线都处于选通状态的话,8位数码管将显示相同的字符。若要各位数码管能够显示出与本位相应的字符,就必须采用扫描显示方式。即在某一时刻,只让某一位的位选线处于导通状态,而其它各位的位选线处于关闭状态。同时,段线上输出相应位要显示字符的字型码。这样在同一时刻,只有选通的那一位显示出字符,而其它各位则是熄灭的,如此循环下去,就可以使各位数码管显示出将要显示的字符。
虽然这些字符是在不同时刻出现的,而且同一时刻,只有一位显示,其它各位熄灭,但由于数码管具有余辉特性和人眼有视觉暂留现象,只要每位数码管显示间隔足够短,给人眼的视觉印象就会是连续稳定地显示。
数码管不同位显示的时间间隔可以通过调整延时程序的延时长短来完成。数码管显示的时间间隔也能够确定数码管显示时的亮度,若显示的时间间隔长,显示时数码管的亮度将亮些,若显示的时间间隔短,显示时数码管的亮度将暗些。若显示的时间间隔过长的话,数码管显示时将产生闪烁现象。所以,在调整显示的时间间隔时,即要考虑到显示时数码管的亮度,又要数码管显示时不产生闪烁现象。
数码管是由7个条形的LED和右下方一个圆形的LED组成,这样一共有8个段线,恰好适用于8位的并行系统。数码管有共阴极和共阳极两种,共阴极数码管的公共阴极接地,当各段阳极上的电平为“1”时,该段点亮,电平为“0”时,该段熄灭;
在c语言中,我们在flash中(code关键词)可以定义以下字形代码,这是段码:
Unsigned char code DuanMa[]={0xc0(0),0xf9(1),0xa4(2),0xb0(3),0x99(4),0x92(5),0x82(6),0xf8(7),0x80(8),0x90(9),0xbf(-),0xff(消隐)}; //共阳
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
- #define uchar unsigned char
- #define uint unsigned int
- sbit buzz=P0^6;//蜂鸣器
- sbit relay=P0^4;//继电器
- // 0 1 2 3 4 5 6 7 8 9 - 消隐
- unsigned char code DuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //共阳
- unsigned char code WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码
- uchar disData[8]={11,11,11,11,11,11,0,0};
- uchar times=0;
- uchar hour,minute,second;
- //函数声明
- void delay_50us(uint t);
- void display(uchar *point);
- void SEG_Latch(void); //段码锁存子程序
- void BIT_Latch(void); //位码锁存子程序
- void ULN2003_Latch(void);
- //P2.7~P2.5=111段码锁存
- //P2.7~P2.5=110位码锁存
- main()
- {
- buzz=0;//关蜂鸣器
- relay=0;//关继电器
- ULN2003_Latch();
- TMOD |=0x01;//T0 16位定时器
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ET0=1;
- TR0=1;
- EA=1;
- while(1)
- {
- if(second == 60 )
- {
- second = 0;
- minute++;
- if(minute == 60)
- {
- minute=0;
- hour++;
- if(hour==24)
- {
- hour=0;
- }
- }
- }
- disData[6]=second/10;
- disData[7]=second%10;
- disData[5]=10;
- disData[3]=minute/10;
- disData[4]=minute%10;
- disData[2]=10;
- disData[0]=hour/10;
- disData[1]=hour%10;
- display(disData);
- }
- }
- void ISR_Timer0(void) interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- times++;
- if (times == 20)
- {
- second++;
- times=0;
- }
- }
- void delay_50us(uint t) //50us 延时
- {
- uchar j;
- for(;t>0;t--)
- for(j=19;j>0;j--)
- ;
- }
- void SEG_Latch(void) //段码锁存子程序
- {
- P2 &= 0x1f;//清P2.7~P2.5
- P2 |= 0xe0;//P2.7~P2.5=111,Y7=0,Y7C=1,即U7的LE=1,段码数据选通
- _nop_();
- P2 &= 0x1f;//P2.7~P2.5=000,Y7=1,Y7C=0,即U7的LE=0,段码数据被锁存
- }
- void BIT_Latch(void) //位码锁存子程序
- {
- P2 &= 0x1f;//清P2.7~P2.5
- P2 |= 0xC0; //P2.7~P2.5=110,Y6=0,Y6C=1,即U8的LE=1,位码数据选通
- _nop_();
- P2 &= 0x1f; //P2.7~P2.5=000,Y6=1,Y6C=0,即U8的LE=0,位码数据被锁存
- }
- void display(uchar *point)
- {
- unsigned char i=0;
- for(i=0;i<8;i++)
- {
- DataPort=WeiMa[i]; //取位码
- BIT_Latch(); //数据锁存
- DataPort=DuanMa[*(point+i)]; //取显示数据,段码
- SEG_Latch(); //数据锁存
- delay_50us(20); // 扫描间隙延时,时间太长会闪烁,太短不亮
- DataPort=0xff; //关显示,消除重影
- SEG_Latch(); //数据锁存
-
- }
- }
- void ULN2003_Latch(void) // ULN2003锁存子程序
- {
- P2 &= 0x1f;//清P2.7~P2.5
- P2 |= 0xa0;//P2.7~P2.5=101,Y5=0,Y5C=1,即U9的LE=1,数据选通
- _nop_();
- P2 &= 0x1f;//P2.7~P2.5=000,Y5=1,Y5C=0,即U9的LE=0,数据被锁存
- }
复制代码
所有资料51hei提供下载:
test4参考改.zip
(14.34 KB, 下载次数: 16)
|