这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » TI » 【MSP焕新大作战】课程2+任务1__定时器中断实现数码管倒数

共4条 1/1 1 跳转至

【MSP焕新大作战】课程2+任务1__定时器中断实现数码管倒数

菜鸟
2024-05-03 18:08:55     打赏

一、功能需求


    使用定时器中断,实现数码管显示数值的递减
    时间范围:10~0
    递减步长:1000ms


二、数码管驱动原理


    数码管显示的工作原理,其实不难,只要了解数码管的结构是由8个小的LED组成的。如下图所示,每一个数码(带1个小数点)管,都由8个led组成一个8字行,通过控制这些小灯的ON/OFF,就能组合成0-9各个数字。

image.png


    而显示什么数字,其对应的8个灯管on/off的输出次序,就是编码表,如下图所示

image.png


    这里就有一个问题:显示1个数字就要控制8个LED,如果用8个GPIO来控制,那每位数字8个IO口,显示8位数字就需要64个针脚,mcu哪有那么多针脚给数码管使用? 能不能用少数几个针脚,就能驱动多个数码管?


    这就需要 74HC595 这个驱动芯片出场了。手册上对它的一句话描述:8位带有输出锁存功能的移位寄存器。该器件具有串行输入、移位功能,和带锁存器的并行输出功能。串行的输入移位,由移位时钟控制;并行的锁存输出,由输出时钟控制:两个时钟相互独立。


    有了这个芯片,我们就可以通过一个GPIO引脚,每次输入1个LED灯的ON/Off状态,在移位时钟的驱动下每次移位1位;连续8个时钟,就将8个led的状态缓存在寄存器中。紧接着需要一次性输出的时候,检测到输出时钟上升沿,就将8个状态一次性通过锁存器输出,这样8位段数码管就能够一次收到8个led的控制信号,输出不同的数字。简单的说:一个个串行移入值,一次性并行输出值。所需的GPIO引脚也只有3个,1个数据针,2个时钟针。


image.png

    多个数码管要连在一起显示,如上图8个数码管,如何驱动所有这8个管子?设计制造的时候,8个管子各有一个片选引脚CS,只有CS引脚本选中时,数码管才接受8个针脚高低电平的控制信号。这样,我们可以将2个74HC595芯片串联起来,1片的8针脚同时输出控制数据,另一片的8针脚输出8个片选信号,任何时候只有一个数码管被选中。通过单片机对8个数码管依次选中和输出控制信号,实现同时点亮8个数码管输出的功能。


三、数码管驱动封装


    理解了8个数码管同时显示的驱动原理,我们可以将数码管外设的功能实现,并封装成*.h/.c文件,方便后续调用。


    硬件接线上,使用3个GPIO口作为输出,1个数据位输出,2个为时钟输出(因为时钟和锁存输出时钟)。供电使用开发板上的3v3,共5根线其接法如下图

image.png

对3个GPIO输出,SysConfig工具中配置如下:

image.png


保存后编译无误。接着开始写代码封装 8个数码管的驱动显示函数,先看码表的定义:

//dat -- PA27 : 串行数据输入
//SCLK-- PA26 :移位时钟
//RCLK-- PA13 :并行寄存器锁存时钟
//                        0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   A,   b,   C,   d,   E,   F
uint8_t Disp_DX[ 16 ]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //段显
uint8_t Disp_PX[  8 ]={1,2,3,4,5,6,7,8};   //片选

两个数组分别为 段选和片选,输入0-9的下标,可以获得要显示此数字需要的编码值;


紧接着,输出时候需要 输出时钟有一个上升沿,为了使用方便,定义一个函数 Display_Out()

//锁存输出到 并行寄存器
void Display_Out()
{
	HC595_RCK(0);
	//delay_cycles(DELAYCYCLES);
	HC595_RCK(1);
}


串行输入的时候,按照码表的值,一次GPIO针脚输出字节中的1位,然后移位时钟上升沿时完成移位,紧接着针脚输出第2位,等待移位上升沿。。。直到8个bit都移位完成。注意这里是大端模式,即首先引入字节的最高位。代码如下:

//串行写入一个字节,注意:大端模式
void HC595_WriteByte(uint8_t data)
{
    for(int i=0; i<8; i++)
	{
		if( data&0x80 )  //最高位为1
		{
			HC595_DAT(1);
		}else{
			HC595_DAT(0);
		}
		//左移一位
		data<<=1;
		
		//产生移位脉冲
		HC595_CLK(0);
		HC595_CLK(1);

	}
}


两个595芯片,一个输出8位的片选信号,另一个同时输出8位的led控制信号,所以点亮一个灯管的数码,其代码如下:

//发送一个数字(0-9)到指定位的数码管
//dis_num  发送的数字(0-9)
//dis_bit  发送到第几个数码管,即:片选(0-7)
void  HC595_SEND_DATA(uint8_t dis_num, uint8_t dis_bit)
{
	
	HC595_WriteByte( dis_num );  //写数据
	HC595_WriteByte( 1<<dis_bit );  //写片选

	Display_Out();  //锁存、输出
}


一个数码管能显示,8个数码管循环扫描8次,就全点亮了。封装代码如下:

//数码管同时显示8位数字
void Disp_8Num(uint16_t hiData, uint16_t loData)
{
	uint16_t tmpH,tmpL;
	uint8_t  num_q, num_b, num_s, num_g;  	//千、百、十、个位 数字
	
	//显示高4位
	tmpH = hiData;
	num_q = tmpH / 1000;
	num_b = tmpH / 100 % 10;
	num_s = tmpH / 10 % 10;
	num_g = tmpH % 10;
	HC595_SEND_DATA(Disp_DX[num_q],7);
	HC595_SEND_DATA(Disp_DX[num_b],6);
	HC595_SEND_DATA(Disp_DX[num_s],5);
	HC595_SEND_DATA(Disp_DX[num_g],4);
		
	//显示低4位
	tmpL = loData;
	num_q = tmpL / 1000;
	num_b = tmpL / 100 % 10;
	num_s = tmpL / 10 % 10;
	num_g = tmpL % 10;
	HC595_SEND_DATA(Disp_DX[num_q],3);
	HC595_SEND_DATA(Disp_DX[num_b],2);
	HC595_SEND_DATA(Disp_DX[num_s],1);
	HC595_SEND_DATA(Disp_DX[num_g],0);
	
}

同理,可以封装只显示最低4位数码管的函数 Disp_4Num(), 以及只显示最低2个数码管的函数Disp_2Num().  


     将以上所有函数封装到 HC595.h 头文件中,方便后面调用。


四、定时器实现

      定时器可以通过SysConfig工具方便的配置。其需要配置的过程,先要选择时钟源,倍频除数,以及预分频系数PreScale,就得到了计数器的基频率。计数器的计数值设定后,又需要选择向上计数/向下计数还是同时计数。

      要列算式估计比较复杂,还好有SysConfig工具。我们设置使用TimerG第一个计数器,32M的系统时钟源,倍频除数1,预分频256, 这样基频率就是 32M/256=125K,取倒数周期为8us。定时器如果设定为10ms,也即频率为100Hz,那么计数值就得取1250向下计数,也即每1250个基频率脉冲输出一次定时器中断。配置如下:

image.png


五、代码实现

    Sysconfig工具自动生成了定时器的初始化代码,其中enable了 Tim0的中断。但是在代码中,还需要将Tim0 的全局中断在NVIC管理器中使能。其代码如下:

image.png

之后就会按固定的10ms一次,系统自动运行中断处理函数。我们需要将业务逻辑实现在中断处理函数中:

image.png

中断处理函数的名字是固定的,sysconfig产生的文件中已经重新define了函数名;函数的结构也是模板式的,先用switch细分是什么中断类型,然后各自处理不同的业务逻辑。图中方框里是真正的业务逻辑,因为是10ms周期,所以需要100次计数才是1秒的周期。每一秒只需要显示值减一,如果显示值小于0了则重新装载最大值MaxNum=10即可。 

    而最终的数码管显示代码,放在main中的while循环中,只有一句话,调用 Disp_2Num() 将递减的值显示出来即可。

六、下载验证

    下载测试没有问题,b站视频如下:

https://www.bilibili.com/video/BV1vt421c76c?p=3

image.png


高工
2024-05-03 21:10:49     打赏
2楼

谢谢分享


工程师
2024-05-08 08:41:13     打赏
3楼

谢谢分享。学习了。


助工
2024-05-10 11:46:22     打赏
4楼

感谢分享


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]