[STM32学习]定时器实现码表(数码管显示)

Posted 小材大用

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[STM32学习]定时器实现码表(数码管显示)相关的知识,希望对你有一定的参考价值。

实验:要求完成码表,具体要求如下:

要求:显示格式XX.YY。
    按键1 可控制计数暂停还是启动
    按键2 清零(必需在暂停后才可以操作
    按键3 存储当前码表的时间,存储成功后显示y(必需在暂停后才可以操作
    按键4 显示存储的码表时间(必需在暂停后才可以操作
    按键5 记录的码表时间向下翻页(必需在暂停后才可以操作

简单分析:

      码表,其实就是显示秒的下一个单位,电子手表上一般都有码表的功能,秒到分钟一般是59秒进行,而码表的下一个单位,则要计到99上才能进位到1秒,所以需要修改定时器,将定时器修改成10ms溢出中断一次,这样记录100次后就达到了1秒。

Tim4Init(719, 999);		//	定时10ms 720*1000/72000000 = 1/100

我们在完成实验之前一定要搞清楚它的硬件电路,分析好引脚所对应的IO口,下图为数码管硬件设计图,完全可以按照电路图设计。

由上图可以知道,该数码管为四位八段数码管,引脚分析如下

数码管电路STM32的IO口
A1PB2
A2PB3
A3PB4
A4PB5
aPE0
bPE1
cPE2
dPE3
ePE4
fPE5
gPE6
dpPC13

通过上述电路图可知,数码管为共阳极数码管,PB2-PB5低电平选中数码管,其中,注意:PB3和PB3引脚默认状态下不是普通的IO口,所以需要用到其复用功能:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);		//	开启服用引脚时钟,保证引脚第二功能正常使用
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关闭JTAG,使能SWD

数码管为共阳极数码管,其编码为:

//	共阳极编码 0-9 a- f
unsigned char seg[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e;

接下来是按键的截下图,如下:

 引脚对应关系:

按键STM32 的IO引脚
KEY1PC0
KEY2PC1
KEY3PC2
KEY4PC3
KEY5PC4

接下来依据任务要求完成代码:

按键初始化:

/********************************************
函数名称:void KeyInit(void)
函数参数:无参,返回值为空
函数功能:实现按键功能初始化
作者:***
时间:2022.3.8
修改作者:
修改实现:
修改说明:
*********************************************/
void KeyInit(void)

	// KEY接在PC0-PC4上,一共5个按键
	//初始化步骤
	/**
		1.开启所对应的时钟
		2.选择所需要的IO口
		3.设置IO口的工作模式
		4.初始化上述配置
	**/
	GPIO_InitTypeDef GPIO_InitStruct;											//	结构体变量申明
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//	开启时钟
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3
								|GPIO_Pin_4;	//  选择PC0-PC4口
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;			//	浮空输入模式
	
	GPIO_Init(GPIOC,&GPIO_InitStruct);													//	配置初始化
	

数码管初始化:

/********************************************
函数名称:void SegInit(void)
函数参数:无参,返回值为空
函数功能:实现数码管初始化
作者:***
时间:2022.3.17
修改作者:
修改实现:
修改说明:
*********************************************/
void SegInit(void)

	//初始化步骤
	/**
		1.开启所对应的时钟
		2.选择所需要的IO口
		3.设置IO口的工作模式
		4.设置IO的输出速率(当IO口设置成输出模式才需要)
		5.初始化上述配置
		6.初始化IO的初值
	**/
	GPIO_InitTypeDef GPIO_InitStruct;											//	结构体变量申明
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	//	开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//	开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);	//	开启时钟
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);		//	开启服用引脚时钟,保证引脚第二功能正常使用

	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关闭JTAG,使能SWD

	//	设置片选引脚
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;	//  选择PB2-PB5口
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;								//	推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;							//	设置输出速率50MHz
	GPIO_Init(GPIOB,&GPIO_InitStruct);													//	配置初始化
	
	//	设置七段引脚
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3
								|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;	//  选择PE0-PE6口
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;								//	推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;							//	设置输出速率50MHz
	GPIO_Init(GPIOE,&GPIO_InitStruct);													//	配置初始化
	
	//	设置DP(小数点)引脚
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;	//  选择PE0-PE6口
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;								//	推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;							//	设置输出速率50MHz
	GPIO_Init(GPIOC,&GPIO_InitStruct);													//	配置初始化
	
	GPIO_Write(GPIOE, 0X007F);		//	设置七段引脚为高电平   0111 1111
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);		//	小数点
	GPIO_WriteBit(GPIOB,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5,Bit_SET);		//	设置片选引脚为高电平
	

定时器中断服务函数:

/********************************************
函数名称:TIM4_IRQHandler(void)
函数参数:
				无参,无返回参数
函数功能:定时器定时10ms
作者:***
时间:2022.5.19
修改作者:
修改时间:
修改说明:
修改作者:
修改时间:
修改说明:
*********************************************/
void TIM4_IRQHandler(void)

	if(TIM_GetITStatus(TIM4, TIM_IT_Update) == 1)		//	标志计数溢出中断产生
	
		tim4Cnt++;			//	秒统计
		if(tim4Cnt>9999)		//	99:99			99*100+99
		
			tim4Cnt = 0;
		
	
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);	

按键功能实现:

/********************************************
函数名称:int KeyScan6(void)
函数参数:无
函数功能:要求:显示格式XX.YY。
				按键1可控制计数暂停还是启动
				按键2 清零(必需在暂停后才可以操作)
				按键3 存储当前码表的时间,存储成功后显示y
				按键4 显示存储的码表时间
				按键5 记录的码表时间向下翻页
作者:***
时间:2022.5.19
修改作者:
修改实现:
修改说明:
*********************************************/
void KeyScan6(void)

	if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) == 0	)			//	判断按键是否按下
	
		delay_ms(10);	//	消抖
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) == 0	)
		
			flag = -1*flag;	//	-1和1跳转
		
		while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) == 0);
	
	if(1 == flag)	//	计数
	
		TIM_Cmd(TIM4,ENABLE);
	
	if(-1 == flag) //	暂停
	
		TIM_Cmd(TIM4,DISABLE);		//	关闭定时器
		
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1) == 0	)			//	判断按键是否按下
		
			delay_ms(10);	//	消抖
			if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1) == 0	)
			
				tim4Cnt = 0;		//	在暂停的条件下实现码表清0 
			
			while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1) == 0);
		
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0	)			//	判断按键是否按下
		
			delay_ms(10);	//	消抖
			if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0	)
			
				saveTime[key3Cnt] = tim4Cnt;
				key3Cnt++;			//	按键按下次数统计
				if(key3Cnt>9)
				
					key3Cnt = 0;			//	计数归0
				
				//SegDis10();			//	显示y
			
			while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0)		//	按键松开检查
			
				SegDis10();			//	显示y
			
		
		
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) == 0	)			//	判断按键是否按下
		
			delay_ms(10);	//	消抖
			if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) == 0	)
					
				tim4Cnt = saveTime[0];
			
			while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) == 0);		//	按键松开检查
		
		
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4) == 0	)			//	判断按键是否按下
		
			delay_ms(10);	//	消抖
			if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4) == 0	)
			
				key5Cnt++;    					//	按键按下计数 
				if(key5Cnt>9)
				
					key5Cnt = 0;		//	归0
				
				tim4Cnt = saveTime[key5Cnt];
			
			while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4) == 0);		//	按键松开检查
				
	
	
	SegDis9();

数码管功能实现:


/********************************************
函数名称:void SegDis9(int value)
函数参数:无参,返回值为空
函数功能:
					要求:显示格式XX.YY。
作者:***
时间:2022.5.17
修改作者:
修改实现:
修改说明:
*********************************************/
void SegDis9(void)

		
	//	数码管a
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, seg[tim4Cnt/1000]);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管b
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, seg[tim4Cnt/100%10]);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管c
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, seg[tim4Cnt/10%10]);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管d
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_RESET);	//	
	GPIO_Write(GPIOE, seg[tim4Cnt%10]);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);


/********************************************
函数名称:void SegDis10(int value)
函数参数:无参,返回值为空
函数功能:
					要求:y。
					共阳极编码y的值:0X91
作者:***
时间:2022.5.17
修改作者:
修改实现:
修改说明:
*********************************************/
void SegDis10(void)

	//	数码管a
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, 0X91);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管b
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, 0X91);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管c
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_RESET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);	//	
	GPIO_Write(GPIOE, 0X91);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);
	//	数码管d
	GPIO_WriteBit(GPIOB,GPIO_Pin_2,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET);		//	
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_RESET);	//	
	GPIO_Write(GPIOE, 0X91);								//	可以实现多位写入
	GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);	//	小数点不需要显示
	delay_ms(5);

实现效果:

源码下载地址:定时器实现码表(数码管显示)-C文档类资源-CSDN文库

以上是关于[STM32学习]定时器实现码表(数码管显示)的主要内容,如果未能解决你的问题,请参考以下文章

STM32 学习12 库函数实现静态数码管显示

STM32 学习12 库函数实现静态数码管显示

嵌入式 LAB 3:自行车码表

嵌入式 LAB 3:自行车码表

嵌入式 LAB 3:自行车码表

自行车码表