[资料分享] MSP430单片机实例10-8位数码管显示时钟

火辣西米秀   2020-4-8 20:52 楼主

      单片机的P4端口控制8位一体数码管的段码,采用8个共阴极的LED数码管。单片机的P5端口作为位扫描控制端口,P5.0~P5.7分别与LED0~LED7的公共端COM引脚连接。

     与静态方式的数码管驱动电路相比,下图所示的电路中占用了16个I/O端口线,8个数码管动态显示只需要两个8位端口,其中P4控制段码,P5控制位选线。动态扫描的原理:由P5端口向每个位轮流输出扫描信号,使每一瞬间只有一个数码管被选通(共阴极低电平选通,共阳极高电平选通),然后由P4端口送入该位要显示的字形码,点亮该位字形段显示的字形。这样在P4送出的段码和P5送出的位选线配合控制下,就可以使各数码管轮流点亮显示各自的字符。虽然显示器的几位数码管是依次被点亮的,但只要每位点亮时间超过1ms,隔一段时间使之再显示一遍,如此不断重复扫描,只要扫描频率足够快(大于50Hz),由于人的视觉暂存,看不出闪烁。动态扫描一般用软件实现,可以采用软件延时或者定时器延时来实现。

基于Proteus的MSP430单片机仿真实例10-8位数码管显示时钟

程序设计
//main.c

#include "msp430f247.h"

#include "stdlib.h"

#include "string.h"

/*****************************************软件延时,主频1M*******************/

#define CPU_F1 ((double)1000000)

#define delay_us1M(x) __delay_cycles((long)(CPU_F1*(double)x/1000000.0))

#define delay_ms1M(x) __delay_cycles((long)(CPU_F1*(double)x/1000.0))

/****************************************************************************/

//共阳极数码管段码表

unsigned char const Led_Tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,

0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

//共阴极数码管段码表

unsigned char const Led_Tab2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,

0x6f,0x40};

unsigned char time_counter;//1S计数器

unsigned char time[3];//时、分、秒计数

unsigned char dis_buff[8];//显示缓冲区,存放要显示的6个字符的段码值和两个分隔符

void display(void);//扫描显示函数

void time_to_disbuffer(void);//时间值送显示缓冲区函数

/************************************************

函数名称:主函数

函数功能:8位一体数码管动态显示时钟

入口参数:无

出口参数:无

************************************************/

main()

{

_EINT();//打开中断,响应按键

WDTCTL = WDTPW + WDTHOLD;//关看门狗

P4DIR=0xff;//段码端口初始化

P5DIR=0xff;//位选端口初始化

time[2]=22;//时间初值

time[1]=51;

time[0]=55;

time_to_disbuffer();

dis_buff[2]=10;//

dis_buff[5]=10;//

while(1)

{

display();//显示扫描

if(++time_counter>=40)//更新时间

{

time_counter=0;

if(++time[0]>=60)

{

time[0]=0;

if(++time[1]>=60)

{

time[1]=0;

if(++time[2]>=24) time[2]=0;

}

}

time_to_disbuffer();//修改显示缓冲区

}

}

}

void display(void)

{

static char i;

P5OUT=0xff;

P4OUT=80;

P4OUT=Led_Tab2[dis_buff[i]];//时间值送显示缓冲区函数

P5OUT=~(1<<i);//位选端口选择

if(++i==8) i=0;

delay_ms1M(2);

}

void time_to_disbuffer(void)

{

dis_buff[0]=time[2]/10;//小时

dis_buff[1]=time[2]%10;

dis_buff[3]=time[1]/10;//分钟

dis_buff[4]=time[1]%10;

dis_buff[6]=time[0]/10;//秒

dis_buff[7]=time[0]%10;

//dis_buff[2]=0x04;//

//dis_buff[5]=0x04;//

}

程序说明
根据硬件电路可以看出,在任何一个时刻,P5.0~P5.7中只能有一个I/O端口输出低电平,即只有一位数码管亮,同时P4端口要输出该位相应的段码值。即时显示的内容没有变化,也要不停地进行循环扫描处理。

软件的设计应保证从外表看数码管显示的效果要连续,亮度均匀,同时没有拖尾现象。单片机为了保证各数码管显示的效果不产生闪烁情况,让数码管看起来好像全部点亮,就首先必须在1S内循环扫描8个数码管的次数应大于25次,这里是利用的人眼的视觉暂存效应。第二要考虑的是,在25ms时间间隔中,要逐一轮流点亮8个数码管,那么每个数码管点亮的持续时间要相同,这样亮度才能均匀。第三个要考虑的是每个数码管点亮的持续时间,这个时间长一些的话,数码管的亮度高一些,反之则暗一些。通常,每个数码管点亮的持续时间为1~2ms。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复