凌乱的DSP笔记(7)-数码管

1. 数码管介绍

1.1 简介

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),使用这个小数点可以更方便地表示想要显示的内容;按能显示多少个(8)可分为1位、2位、3位、4位、5位、6位、7位等数码管。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。

image

image

共阴段码:

段码 字符 段码 字符 段码 字符 段码 字符
0x3f 0 0x6d 5 0x77 A 0x71 F
0x06 1 0x7d 6 0x7c B 0x00 无显示
0x5b 2 0x07 7 0x39 C    
0x4f 3 0x7f 8 0x5e D    
0x66 4 0x6f 9 0x79 E    

1.2 动态显示原理

LED数码管显示器工作方式有两种:静态显示方式和动态显示方式。
静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优点是占用CPU时间少,显示便于监测和控制。缺点是硬件电路比较复杂,成本较高,比如使用4个静态数码管,那么就需要32个IO来控制。
动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人感觉各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。

2. 74HC164

74HC164是高速硅门CMOS器件,与TTL器件的引脚兼容。74HC164是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA或DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。时钟(CP)每次由低变高时,数据右移一位,输入到Q0,Q0是两个数据输入端(DSA或DSB)的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。
工作电压范围:2.0V-6.0V

image

image

image

3. 硬件设计

image

image

image

4. 软件设计

4.1 smg.c

/*
 * smg.c
 *
 *  Created on: 2020-4-9
 *      Author: Administrator
 */

#include "smg.h"


unsigned char smgduan[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
             0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};//0~F 数码管段选数据

void SMG_Init(void)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
    //SMG数据控制端口配置
    GpioCtrlRegs.GPBMUX2.bit.GPIO56=0;
    GpioCtrlRegs.GPBDIR.bit.GPIO56=1;
    GpioCtrlRegs.GPBPUD.bit.GPIO56=0;

    GpioCtrlRegs.GPBMUX2.bit.GPIO54=0;
    GpioCtrlRegs.GPBDIR.bit.GPIO54=1;
    GpioCtrlRegs.GPBPUD.bit.GPIO54=0;

    GpioCtrlRegs.GPCMUX1.bit.GPIO70=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO70=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO70=0;

    GpioCtrlRegs.GPCMUX1.bit.GPIO71=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO71=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO71=0;

    GpioCtrlRegs.GPCMUX1.bit.GPIO72=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO72=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO72=0;

    GpioCtrlRegs.GPCMUX1.bit.GPIO73=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO73=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO73=0;

    EDIS;

    GpioDataRegs.GPCCLEAR.bit.GPIO70=1;
    GpioDataRegs.GPCCLEAR.bit.GPIO71=1;
    GpioDataRegs.GPCCLEAR.bit.GPIO72=1;
    GpioDataRegs.GPCCLEAR.bit.GPIO73=1;

}

//74HC164数据发送函数
//dat:所要发送的数据
void HC164SendData(unsigned char dat)
{
    char i=0;

    for(i=0;i<8;i++)
    {
        SPICLKA_SETL;
        if(dat&0x80)
            SPISIMOA_SETH;
        else
            SPISIMOA_SETL;
        SPICLKA_SETH;
        dat<<=1;
    }
}

//数码管显示整数函数
//num:整数
void SMG_DisplayInt(Uint16 num)
{
    unsigned char buf[4];
    unsigned char i=0;

    buf[0]=smgduan[num/1000];//千位
    buf[1]=smgduan[num%1000/100];//百位
    buf[2]=smgduan[num%100/10];//十位
    buf[3]=smgduan[num%10];//个位

    for(i=0;i<4;i++)
    {
        HC164SendData(buf[i]);
        switch(i)
        {
            case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
            case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
            case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
            case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
        }
        DELAY_US(5000);
    }
}

//数码管显示小数函数
//num:小数
//dotnum:小数点后面有效位数(最大3)
void SMG_DisplayFloat(float num,unsigned char dotnum)
{
    unsigned char buf[4];
    unsigned char i;
    Uint16 value=0;

    if(dotnum==1)
    {
        value=num*10;
        buf[0]=smgduan[value/1000];
        buf[1]=smgduan[value%1000/100];
        buf[2]=smgduan[value%100/10]|0x80;
        buf[3]=smgduan[value%10];
    }
    else if(dotnum==2)
    {
        value=num*100;
        buf[0]=smgduan[value/1000];
        buf[1]=smgduan[value%1000/100]|0x80;
        buf[2]=smgduan[value%100/10];
        buf[3]=smgduan[value%10];
    }
    else if(dotnum==3)
    {
        value=num*1000;
        buf[0]=smgduan[value/1000]|0x80;
        buf[1]=smgduan[value%1000/100];
        buf[2]=smgduan[value%100/10];
        buf[3]=smgduan[value%10];
    }

    for(i=0;i<4;i++)
    {
        HC164SendData(buf[i]);
        switch(i)
        {
            case 0: SEG1_SETH;SEG2_SETL;SEG3_SETL;SEG4_SETL;break;
            case 1: SEG1_SETL;SEG2_SETH;SEG3_SETL;SEG4_SETL;break;
            case 2: SEG1_SETL;SEG2_SETL;SEG3_SETH;SEG4_SETL;break;
            case 3: SEG1_SETL;SEG2_SETL;SEG3_SETL;SEG4_SETH;break;
        }
        DELAY_US(5000);
    }
}

4.2 smg.h

/*
 * smg.h
 *
 *  Created on: 2020-4-9
 *      Author: Administrator
 */

#ifndef SMG_H_
#define SMG_H_


#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

//数码管位选信号线管脚定义
#define SEG1_SETH            (GpioDataRegs.GPCSET.bit.GPIO70=1)
#define SEG1_SETL            (GpioDataRegs.GPCCLEAR.bit.GPIO70=1)
#define SEG2_SETH            (GpioDataRegs.GPCSET.bit.GPIO71=1)
#define SEG2_SETL            (GpioDataRegs.GPCCLEAR.bit.GPIO71=1)
#define SEG3_SETH            (GpioDataRegs.GPCSET.bit.GPIO72=1)
#define SEG3_SETL            (GpioDataRegs.GPCCLEAR.bit.GPIO72=1)
#define SEG4_SETH            (GpioDataRegs.GPCSET.bit.GPIO73=1)
#define SEG4_SETL            (GpioDataRegs.GPCCLEAR.bit.GPIO73=1)

//74HC164时钟管脚定义
#define SPICLKA_SETH            (GpioDataRegs.GPBSET.bit.GPIO56=1)
#define SPICLKA_SETL            (GpioDataRegs.GPBCLEAR.bit.GPIO56=1)
//74HC164数据管脚定义
#define SPISIMOA_SETH            (GpioDataRegs.GPBSET.bit.GPIO54=1)
#define SPISIMOA_SETL            (GpioDataRegs.GPBCLEAR.bit.GPIO54=1)


void SMG_Init(void);
void SMG_DisplayInt(Uint16 num);
void SMG_DisplayFloat(float num,unsigned char dotnum);


#endif /* SMG_H_ */

4.3 main.c

10s计时。

/*
 * main.c
 *
 *  Created on: 2020年4月8日
 *      Author: lenovo
 */

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "smg.h"

/*******************************************************************************
* 函 数 名         : main
* 函数功能           : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
    InitSysCtrl();
    SMG_Init();
    float i=0.0;
    char n;
    while(1)
    {
        for(n=0;n<5;n++)
        {
            SMG_DisplayFloat(i,1);
        }
        if(i>9.9)
            i=0.0;
        else
            i+=0.1;
    }
}

5. 效果

 

posted @ 2020-04-09 10:33  叮叮当当sunny  阅读(2221)  评论(2编辑  收藏  举报