[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口 |
A1 | PB2 |
A2 | PB3 |
A3 | PB4 |
A4 | PB5 |
a | PE0 |
b | PE1 |
c | PE2 |
d | PE3 |
e | PE4 |
f | PE5 |
g | PE6 |
dp | PC13 |
通过上述电路图可知,数码管为共阳极数码管,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引脚 |
KEY1 | PC0 |
KEY2 | PC1 |
KEY3 | PC2 |
KEY4 | PC3 |
KEY5 | PC4 |
接下来依据任务要求完成代码:
按键初始化:
/********************************************
函数名称: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学习]定时器实现码表(数码管显示)的主要内容,如果未能解决你的问题,请参考以下文章