凌亂的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. 效果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM