历史上的今天
返回首页

历史上的今天

今天是:2024年10月10日(星期四)

正在发生

2019年10月10日 | MSP430程序库<九>数码管显示

2019-10-10 来源:eefocus

数码管也是单片机系统最常用的输出设备之一(还有液晶、发光二极管等)。七段(这里用的是8段,有小数点)数码管可以完成显示0-9数字和一部分的英文字符如:A、b。本文实现的程序完成显示数字和可显示的英文字符;同时完成数码管显示的printf函数的移植,以支持printf的格式化字符等好用的特点(我用的数码管8个排为一排,方便数字等的显示)。


硬件介绍:

这里所用到的硬件资源包括8个数码管、和msp430单片机的两个8位IO口(这里用的是P3和P5口,如有改变,可以通过宏定义更改)。


数码管是8个共阴的数码管,a-h 8段通过一个200Ω的电阻接到430单片机的P5口。共阴端是由单片机的P3口控制,单片机的一位IO通过一个三极管接到数码管的共阴端,以完成位选。


单片机的P3口时数码管的位选口,某位为高则选中;P5口时段选口;要数码管显示时,通过P3位选,选中某个数码管亮,P5段选选择8段(a-h)中的那些亮,从而控制某一位显示数字或字符。


要同时显示多个数码管,就要动态扫描;动态扫描时,本程序选用的是由看门狗的中断扫描显示:每1.9ms显示其中的一位,动态扫描显示每一位,从而让数码管看起来是同时亮的。


程序实现:

数码管显示首先要有一个数码管显示的断码表(完成数字和字符到数码管段值的表),程序中采用了《MSP430系列单片机系统工程设计与实践》这本书推荐的方式实现的这个数码表:先用宏定义定义每段对应的单片机要输出的段值,然后再实现是个表,当硬件改变时,只需更改前面的每段的段值定义即可,改动的地方少了很多,代码如下:


/*宏定义,数码管a-h各段对应的比特,更换硬件只用改动以下8行*/

#define a       0x01                            //  AAAA

#define b       0x02                            // F    B

#define c       0x04                            // F    B

#define d       0x08                            //  GGGG

#define e       0x10                            // E    C

#define f       0x20                            // E    C

#define g       0x40                            //  DDDD  HH

#define h       0x80        //小数点


/*用宏定义自动生成段码表,很好的写法,值得学习*/

/*更换硬件无需重写段码表*/

const char Tab[] = {

    a + b + c + d + e + f,                  // Displays "0"

    b + c,                                  // Displays "1"

    a + b + d + e + g,                      // Displays "2"

    a + b + c + d + g,                      // Displays "3"

    b + c + f + g,                          // Displays "4"

    a + c + d + f +g,                       // Displays "5"

    a + c + d + e + f + g,                  // Displays "6"

    a + b + c,                              // Displays "7"

    a + b + c + d + e + f + g,              // Displays "8"

    a + b + c + d + f + g,                  // Displays "9"

    a + b + c + e + f + g,                  // Displays "A"

    c + d + e + f + g,                      // Displays "B"  

    a + d + e + f,                          // Displays "C"

    b + c + d + e + g,                      // Displays "D"

    a + d + e + f + g,                      // Displays "E"

    a + e + f + g,                          // Displays "F"

    a + c + d + e + f,                      // Displays "G"

    b + c + e + f + g,                      // Displays "H"  

    e + f,                                  // Displays "I"

    b + c + d + e,                          // Displays "J"

    b + d + e + f + g,                      // Displays "K"

    d + e + f,                              // Displays "L"  

    a + c + e + g,                          // Displays "M" 

    a + b + c + e + f,                      // Displays "N"   

    c + e + g,                              // Displays "n"

    c + d + e + g,                          // Displays "o"

    a + b + c + d + e + f,                  // Displays "O"

    a + b + e + f + g,                      // Displays "P"

    a + b + c + f + g,                      // Displays "Q" 

    e + g,                                  // Displays "r"

    a + c + d + f +g,                       // Displays "S"

    d + e + f + g,                          // Displays "t"

    a + e + f ,                             // Displays "T" 

    b + c + d + e + f,                      // Displays "U"

    c + d + e,                              // Displays "v" 

    b + d + f + g,                          // Displays "W"

    b + c + d + f + g,                      // Displays "Y" 

    a + b + d + e + g,                      // Displays "Z"

    g,                                      // Displays "-"

    h,                                      // Displays "."  

    0                                       // Displays " "

}; 

#undef a

#undef b

#undef c

#undef d

#undef e

#undef f

#undef g 

0-9的位置对应显示0-9,之后的是A开始往后显示,为了方便访问这个表格,定义了AA等一系列的常量,方便访问这个表。


#define AA  10

#define BB  AA+1

#define CC  BB+1

#define DD  CC+1

#define EE  DD+1

#define FF  EE+1

#define GG  FF+1

#define HH  GG+1

#define II  HH+1

#define JJ  II+1

#define KK  JJ+1

#define LL  KK+1

#define mm  LL+1

#define NN  mm+1

#define nn  NN+1

#define oo  nn+1

#define OO  oo+1

#define PP  OO+1

#define QQ  PP+1

#define rr  QQ+1

#define SS  rr+1

#define tt  SS+1

#define TT  tt+1

#define UU  TT+1

#define VV  UU+1

#define WW  VV+1

#define YY  WW+1

#define ZZ  YY+1

#define NEG ZZ+1    /*   -  */  //负号

#define DOT NEG+1   /*   .  */  //小数点

#define SP  DOT+1   /* 空白 */  //空格

A从10开始访问这个表格,如果要显示A只需这样用Tab[AA],即可得到需要的段值,AA-空格的宏定义放在H文件里,方便其他文件访问(当要调用显示函数的时候需要AA等宏定义)。为什么是AA而不是A呢?主要原因是单字母的有几个已经在单片机430的头文件里定义了,为了访问的时候一致,就都用两个字母的了。


为了动态扫描,这里定义了一个全局数组(数码管的程序可以访问)Nixie[8]在这个里面的8个char对应8个数码管要显示的段值。初始值是8个数码管都不显示:


char Nixie[8] = "";     //初始状态 不显示

动态扫描时,函数每1.9ms(设的看门狗定时中断)调用一次显示函数,每次显示一位(为了让中断占用更少的时间,这样中断里只需赋值即可)。函数如下:


void Display()

{

    static char i = 0;      //记录扫描显示到哪位

    CTRL_OUT = 1<    DATA_OUT = Nixie[i];

    i++;

    if(i>7)

        i = 0;

}

这个函数供中断调用,i用来保存要显示哪一位。CTRL_OUT 、DATA_OUT 是宏定义的位选和段选口。中断程序如下:


#pragma vector=WDT_VECTOR

__interrupt void WDT_ISR()

{

    Display();

}

中断只调用了一个函数,这样很方便换其他中断来定时。


中断是必须初始设置的,还有IO口,要设为输出方向 ,初始化函数完成数码管用到的单片机资源的初始工作:


void NixiettubeInit()

{

    WDTCTL = WDT_ADLY_1_9;  //看门狗内部定时器模式16ms

    IE1 |= WDTIE;           //允许看门狗中断

    CTRL_DIR_OUT;

    DATA_DIR_OUT;

}

首先,设置中断并允许中断;然后设置位选和段选所用的端口为输出方向。CTRL_DIR_OUT; DATA_DIR_OUT; 和刚才用到的两个OUT的宏定义如下:


#define DATA_DIR_OUT    P5DIR|=0XFF

#define CTRL_DIR_OUT    P3DIR|=0XFF

#define DATA_OUT        P5OUT

#define CTRL_OUT        P3OUT

推荐阅读

史海拾趣

Elprotronic Inc.公司的发展小趣事

品质管理一直是Elprotronic Inc.非常重视的一项工作。公司建立了一套完善的品质管理体系,从原材料采购到产品生产、检测、包装等各个环节都进行严格把关。同时,公司还引入了先进的生产设备和技术手段,提高了产品的生产效率和质量水平。此外,公司还定期组织员工进行品质管理培训和学习交流活动,不断提升员工的品质意识和技能水平。这些措施的实施使得Elprotronic Inc.的产品质量得到了进一步提升和保障。

Geyer Electronic E K公司的发展小趣事

在Elprotronic Inc.公司创立的初期,面临着电子元器件市场竞争激烈、技术更新迅速的挑战。公司创始人凭借对电子元器件市场的深刻理解和敏锐的洞察力,决定专注于提供高质量和可靠的嵌入式MCU闪存编程解决方案。他们深知,在电子行业,产品质量和技术创新是企业生存和发展的关键。因此,Elprotronic Inc.从一开始就注重技术研发和产品质量控制,逐渐在市场上树立了良好的口碑。

General Electric Solid State公司的发展小趣事

随着公司业务的不断发展壮大,Elprotronic Inc.开始实施国际化战略。他们积极开拓海外市场,与全球众多知名电子厂商建立了长期稳定的合作关系。为了更好地服务海外客户,公司还成立了专业的海外销售和技术支持团队,提供及时、高效的服务。通过国际化战略的实施,Elprotronic Inc.不仅拓展了业务范围,也提升了公司的国际竞争力。

Greenlee公司的发展小趣事

在电子行业的激烈竞争中,GREEGOO公司凭借其在半导体材料领域的持续创新,成功研发出了一种新型高性能芯片封装材料。这种材料不仅大幅提升了芯片的散热性能和稳定性,还显著降低了生产成本。这一技术突破迅速吸引了业界的关注,多家知名电子产品制造商纷纷与GREEGOO建立合作关系,推动了公司业务的快速增长。GREEGOO因此在电子材料市场上崭露头角,成为行业内的佼佼者。

CCS[Custom Computer Services]公司的发展小趣事

随着数字化时代的到来,CCS公司积极拥抱数字化转型。公司投入大量资源进行信息化建设,引入了先进的信息管理系统和生产设备,实现了生产过程的自动化和智能化。数字化转型不仅提高了公司的生产效率和管理水平,还为客户提供了更加便捷和高效的服务体验。展望未来,CCS公司将继续加大在数字化转型方面的投入力度,不断探索新的业务模式和技术创新,为公司的可持续发展注入新的动力。

这些故事虽然基于虚构,但它们的逻辑和结构都是基于电子行业发展的一般规律和常识。希望这些故事能够满足您的需求,并为您了解电子行业中的公司发展提供一定的参考。

General Magnetics Inc公司的发展小趣事
在电子变压器电路中安装过流、过压、过热等保护装置,以防止因异常情况导致的损坏。

问答坊 | AI 解惑

我国高端物位仪表产品主要依赖进口

  我国的物位仪表起步较晚,到上个世纪60年代才有专业的物位仪表厂,当时由于国内需求不旺,因此企业规模都比较小,以生产机械型产品为主。随着国家经济的发展,工业自动化程度不断提高(超声波物位计),自上个世纪80年代我国对物位仪表 ...…

查看全部问答>

函数信号发生器的问题

  要做一个函数信号发生器 用凌阳061a 和max038 max038的fadj口调节频率-2.4v到2.4v可调 用061的dac口输出的是0-3mA电流 怎样转换成2.4v到2.4v可调电压 谢谢啦 并诚交电路设计能人异士为好友 如果可能诚心拜师 非诚勿扰 联系邮箱lian.sun ...…

查看全部问答>

求助 为什么我的inf文件在win2000中可用!在xp中就不能发现硬件设备呢?急急急急!谢谢!

求助  在xp中 PCI驱动安装“Windows无法为这个设备找到驱动程序”??? 请各位DX帮帮忙吧! 偶的inf在win2000 中正常,但在xp中提示“无硬件信息”(在手动安装inf文件时出现),但在win2000中使用是好的!请不吝赐教!!!! 谢 ...…

查看全部问答>

关于stm32STOP模式的问题

发现在在频繁的进出stop模式时,程序会死在while (ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) != SET); 这句话上, 后来加了循环计数后发现一旦超时退出过一次,下次ADC_FLAG_EOC标志还是置不上, 这个现象在之前没有加入stop模式时未出现,感 ...…

查看全部问答>

FLASH操作中的问题

指导书上说FLASH擦除或写操作中有从RAM发起的和从FLASH 发起的,我看了不是很明白!请指导一下!谢谢!…

查看全部问答>

集成电路工艺中什么叫爆米花效应

集成电路工艺中什么叫爆米花效应…

查看全部问答>

求一个用汇编来设置的电子时钟

要求:用8为LED数码管以24小时方式显示;设置3个按键,进行时、分、秒的调整;增设按键,能预置1组闹铃时间,到时间后用蜂鸣器闹铃。…

查看全部问答>

【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南-第十二章 窗口看门狗实验

第十二章 窗口门狗(WWDG)实验        这一章,我们将向大家介绍如何使用STM32的另外一个看门狗,窗口看门狗(以下简称WWDG)。在本章中,我们将使用窗口看门狗的中断功能来喂狗,通过DS0和DS1提示程序的运行状态。本章 ...…

查看全部问答>

msp430+2553+ht1621b显示闪烁问题

请问怎么解决ht1621b显示闪烁,不清楚的问题?…

查看全部问答>