7.DSP学习记录之数码管
基于 TI 28335
- 一、数码管驱动简介
- 1.数码管简介
- 2.驱动芯片74HC164
- 二、点亮实验
- 1.电路连接
- 2.软件实现
- 三、28335数码管倒计时秒表
一、数码管驱动简介
1.数码管简介

一位数码管由8个LED组成,数码管的显示,就是简单的高低电平输出
其连接方式有共阳极和共阴极两种,共阳极连接在数码管的连接端直接拉低电平即可,而共阴极接法需要使用驱动芯片进行驱动LED管使其导通
显示方式有动态显示和静态显示两种,静态显示即直接给LED电平,动态显示的原理主要是通过将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示

数码管的编码:
如图,数码管由8个LED组成,分别为:ABCDEFGH和dp符号位,将该8位进行二进制编码,以数字0为例,若采用共阴极接法,则需要导通ABCDEF,即0011 1111,化为16进制位为:0x3F,其他数字编码为 :

2.驱动芯片74HC164
74HC164芯片,该芯片是一种8位串并转换控制芯片,主要用于数字电路和LED显示控制电路应用,只需要2个单片机IO口就可以扩展出8个控制口,可通过此8个输出口控制数码管段选,对于4根位选(指的是选择哪一个数码管进行点亮)控制线可直接使用IO 口控制。

上图中:绿色为两个输入,黄色为8个输出

该芯片的驱动方式类似SPI通信
74HC164是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA
或DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空
时钟(CP)每次由低变高时,数据右移一位,输入到Q0,Q0是两个数据输入端(DSA或DSB)的逻辑与(若要保持数据有效则要将一条线一直高电平),它将上升时钟沿之前保持一个建立时间的长度。
主复位(MR)输入端上的一个低电平将使其它所有输入端都无效,同时非同步地清除寄存器,强制所有的输出为低电平。
总结:当CLK 上升沿到来时数据输入端(A或B)数据传输进去,要将一个段码数据传输出去可循环8次逐位发送
二、点亮实验
1.电路连接



从上图:
数码管的驱动输入IO为:GPIO54、GPIO55
时钟线为:GPIO56
数码管段选IO为:GPIO70~~GPIO73
2.软件实现
实现效果:数码管循环显示 1314 和 520
数码管SMG.c配置文件:
#include "SMG.h"
#include "led.h"unsigned char SMG_Table[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7F,0x6F};//数码管初始化
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;
}//数码管显示函数
void SMG_DisplayInt(Uint16 num){unsigned char buf[4];unsigned char i=0;buf[0] = SMG_Table[num/1000]; //取千位buf[1] = SMG_Table[num%1000/100]; //取百位buf[2] = SMG_Table[num%1000%100/10]; //取十位buf[3] = SMG_Table[num%1000%100%10]; //取个位//高位为0检测,本人屎山水平,请勿喷。。。if((num/1000) == 0){buf[0] = 0x00;if((num%1000/100) == 0){buf[1] = 0x00;if((num%1000%100/10) == 0){buf[2] = 0x00;}}}for(i=0;i<4;i++){HC164SendData(buf[i]);switch(i){case 0:SEG1_H;SEG2_L;SEG3_L;SEG4_L;break;case 1:SEG1_L;SEG2_H;SEG3_L;SEG4_L;break;case 2:SEG1_L;SEG2_L;SEG3_H;SEG4_L;break;case 3:SEG1_L;SEG2_L;SEG3_L;SEG4_H;break;}DELAY_US(5000);}}//74HC164数据发送函数
//dat:所要发送的数据
void HC164SendData(unsigned char dat){char i=0;for(i=0;i<8;i++){CLK_L;if(dat & 0x80){SPI_SIMOA_H;}else{SPI_SIMOA_L;}CLK_H; //SPI总线在脉冲上升延传输数据dat<<=1; //数据左移一位}}
SMG.h文件:
/** SMG.h** Created on: 2025年10月13日* Author: dzg*/#ifndef HARDWARE_SMG_H_
#define HARDWARE_SMG_H_#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File#include "beep.h"//数码管段选宏定义
#define SEG1_H (GpioDataRegs.GPCSET.bit.GPIO70=1)
#define SEG1_L (GpioDataRegs.GPCCLEAR.bit.GPIO70=1)#define SEG2_H (GpioDataRegs.GPCSET.bit.GPIO71=1)
#define SEG2_L (GpioDataRegs.GPCCLEAR.bit.GPIO71=1)#define SEG3_H (GpioDataRegs.GPCSET.bit.GPIO72=1)
#define SEG3_L (GpioDataRegs.GPCCLEAR.bit.GPIO72=1)#define SEG4_H (GpioDataRegs.GPCSET.bit.GPIO73=1)
#define SEG4_L (GpioDataRegs.GPCCLEAR.bit.GPIO73=1)//驱动芯片宏定义
#define CLK_H (GpioDataRegs.GPBSET.bit.GPIO56=1)
#define CLK_L (GpioDataRegs.GPBCLEAR.bit.GPIO56=1)#define SPI_SIMOA_H (GpioDataRegs.GPBSET.bit.GPIO54=1)
#define SPI_SIMOA_L (GpioDataRegs.GPBCLEAR.bit.GPIO54=1)void SMG_Init(void);
void SMG_DisplayInt(Uint16 num);
void HC164SendData(unsigned char dat);#endif /* HARDWARE_SMG_H_ */
主函数:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "beep.h"
#include "Key.h"
#include "led.h"
#include "Interrupt.h"
#include "SMG.h"
void main()
{InitSysCtrl();Led_Init();SMG_Init();int i;while(1){i = 100;while(i--)//i = 0时跳出循环{SMG_DisplayInt(1314);}i = 100;while(i--){SMG_DisplayInt(520);}}
}
三、28335数码管倒计时秒表
注意要将Count声明为全局变量
一个小倒计时秒表,可以通过按键调节计时时间,计时到0后停止
main.c:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "beep.h"
#include "Key.h"
#include "led.h"
#include "Interrupt.h"
#include "SMG.h"
void main()
{InitSysCtrl();InitPieCtrl();IER=0x0000;IFR=0x0000;InitPieVectTable();Key_Init();Led_Init();SMG_Init();while(1){switch(Key_Scan(0)){case 1:Count++;break;case 2:Count--;break;case 3:Tim0_Init(150,1000000);;break;}SMG_DisplayInt(Count);}
}
定时器配置:
#include "Interrupt.h"
#include "led.h"unsigned char Count = 10;interrupt void TIM0_IRQn(void)
{EALLOW;Count = Count - 1;if(Count == 0){InitPieCtrl();IER=0x0000;IFR=0x0000;InitPieVectTable();}PieCtrlRegs.PIEACK.bit.ACK1=1;EDIS;
}void Tim0_Init(float Freq, float Period)
{//1.时钟初始化EALLOW;SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;EDIS;//2.初始化定时器参数CpuTimer0.RegsAddr=&CpuTimer0Regs;//指向定时器0的寄存器地址CpuTimer0Regs.PRD.all =0xFFFFFFFF; //设置定时器0的周期寄存器值CpuTimer0Regs.TPR.all =0;//设置定时器预定标计数器值为0CpuTimer0Regs.TPRH.all=0;CpuTimer0Regs.TCR.bit.TSS=1; //确保定时器0为停止状态CpuTimer0Regs.TCR.bit.TRB=1; //重载使能CpuTimer0.InterruptCount=0; //Resetinterruptcounters://3.定时器定时周期以及设置定时器的控制寄存器等ConfigCpuTimer(&CpuTimer0,Freq,Period);//4.设置定时器0的中断入口地址为中断向量表的INT0EALLOW;PieVectTable.TINT0=&TIM0_IRQn;EDIS;//5.开启定时器中断功能,并使能定时器CpuTimer0Regs.TCR.bit.TSS=0; //开始定时器功能PieCtrlRegs.PIEIER1.bit.INTx7=1;//PIE级中断使能,第一组中断的第7个小中断,即定时器0//使能CPU总中断IER|=M_INT1;EINT;ERTM;
}
数码管配置同上
