一、数码管驱动简介

1.数码管简介

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d6755463926c48baaff98a523ba02fef.png在这里插入图片描述
一位数码管由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;//设置定时器预定标计数器值为0
	CpuTimer0Regs.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的中断入口地址为中断向量表的INT0
	EALLOW;
	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;
}

数码管配置同上

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐