北京交通大学2019年校内电子设计竞赛单片机部分——STM32F103正点原子开发板实现
2020-07-13 05:23
148 查看
因为在学STM32,所以闲着无事找了找有没有什么简单的利于上手开工的小项目,恰巧碰到了“北京交通大学2019年校内电子设计竞赛单片机部分”。想着练一下手也不错。
首先来看一下题目:
要求很简单,“单击、双击、长按”三个动作对应三种不同的响应,可以用状态机来完成。
这里一个一个分解每个要求:
- 单击按键
单击按键要求实现四档亮度“灭-低亮度-中亮度-高亮度”,这个很简单,我们可以通过PWM波来实现。这里我就直接贴代码上来了。不难读懂,直接利用了STM32库函数的TIM_SetCompare2()
实现。
int ValueBright[4] = { 1,3,5,0 }; void Single_Press(void) { if(stateNow == StateSinglePress) TIM_SetCompare2(TIM3,ValueBright[valueIndex]*100); if(stateNow == StateNotPressed) { TIM_SetCompare2(TIM3,0); } }
- 双击按键
双击按键要求进入呼吸灯状态,这个如果是跟我一样学正点原子的STM32的话是自然不陌生的,我也不多说了,直接使用PWM波完成。上代码。
void Double_Press(void) { if(stateNow == StateDoublePress) { delay_ms(10); if(flagPwm) valuePwm += 2; else valuePwm -= 2; if(valuePwm > 500) flagPwm = 0; if(valuePwm == 0) flagPwm = 1; TIM_SetCompare2(TIM3,valuePwm); } }
- 长按按键
长按按键有点不同,因为这个地方要求实现LED以50%的占空比循环亮灭,并且整个周期的时间是根据自己的按键时长来决定的。所以这里给我们提出的要求就是:使用PWM波实现50%占空比和使用定时器记录按键时长
因此这个地方就不能像上面两个那样定义一个普通函数来完成响应动作,而应该通过TIM的中断处理函数来实现这个功能。这里解释一下:
通过设置TIM4每10ms触发一次中断,在中断处理函数内累加timePressed
来记录长按时间,如果长按时间大于预设的阈值TimeLongPress
那我们就认为进入长按状态了。但是进入了长按状态之后我们不能马上就开始响应动作,因为这个时候如果还没有抬起按键就会出错的。所以通过一句if(valueBefore == 1 && valueNow == 0)
来判断是否抬起按键了。
void TIM4_IRQHandler(void) { case StatePressed: timePressed++; if(valueBefore == 1 && valueNow == 0) { if(timePressed >= TimeLongPress) stateNow = StateLongPress; else stateNow = StateNextState; } break; case StateLongPress: cnt++; if(cnt <= timePressed/2) TIM_SetCompare2(TIM3,450); else if(cnt >= timePressed/2) TIM_SetCompare2(TIM3,0); if(cnt >= timePressed) cnt = 0; break; }
- 单击按键退出当前工作模式
这个地方需要我们在进行相应动作的时候能根据按键退出当前的响应动作,所以我选用了简单的外部中断处理。这里我就直接上代码了。
void EXTI4_IRQHandler(void) { delay_ms(50); if(isIntHappen == 0 && GPIO_ReadInputDataBit(KEY_PORT,KEY_PIN) == 0) { isIntHappen = 1; if(stateNow == StateSinglePress) { valueIndex++; if(valueIndex == 3) { EXTIX_Disable();//关闭外部按键中断 TIM_SetCompare2(TIM3,0); CLEAR_ALL_PARA();//还原所有数据至初始状态 TIM_Cmd(TIM4, ENABLE);//开启TIM4中断 flagQuit = 1; } } else if(stateNow == StateDoublePress) { EXTIX_Disable();//关闭外部按键中断 TIM_SetCompare2(TIM3,0); CLEAR_ALL_PARA();//还原所有数据至初始状态 TIM_Cmd(TIM4, ENABLE);//开启TIM4中断 flagQuit = 1; } else if(stateNow == StateLongPress) { EXTIX_Disable();//关闭外部按键中断 stateNow = StateNotPressed; TIM_SetCompare2(TIM3,0); CLEAR_ALL_PARA();//还原所有数据至初始状态 GPIO_ResetBits(GPIOE,GPIO_Pin_5); } isIntHappen = 0; } EXTI_ClearITPendingBit(EXTI_Line4); }
其实功能很简单,就是检测到外部按键中断后进入外部中断处理函数
EXTI4_IRQHandler(void)中,在这个中断处理函数里面把工作状态还原到最初的工作状态,然后清除掉那些临时变量的值,然后关闭外部中断(后面说明为什么要关闭外部中断)。
最后把上面的代码合并一次,构思一下整体。在上面的代码中,我用到了外部中断
EXTI4_IRQHandler(void),用到了定时器中断处理函数
TIM4_IRQHandler(void),用到了PWM波
TIM_SetCompare2()函数。所以这里我们需要使用两个TIM,一个用来做普通的计时检测按键状态,一个用来专门PWM相关。
所以整体的系统工作为:
- 通过
TIM4
实现按键状态的检测,通过改变stateNow
这个变量来记录现在的工作状态。提前设置了下面几种工作状态:
#define StateNotPressed 0x11//空闲 #define StatePressed 0x22//被按下了 #define StateLongPress 0x33//长按状态 #define StateDoublePress 0x44//双击状态 #define StateSinglePress 0x55//单击状态 #define StateNextState 0x66//被按下后抬起等待是否会双击状态
- 当进入某一工作状态后进行相应的响应动作,这个时候激活外部中断
EXTI4
检测是否有外部中断触发中断处理函数退出工作状态 - 当退出工作状态时要再次使失活外部中断
EXTI4
,防止下次按键被读取为外部中断。
最后的最后放个链接,整个工程写的比较仓促,用了很多正点原子的代码,有些也没有细改了,如果发现有些地方名字和实际不和还以实际情况为主(只是我偷懒没改)。大家多多包容,新手上路。欢迎交流
链接:https://pan.baidu.com/s/1asVjmNFozLC1_etJ4pBYKw
提取码:ux7f
相关文章推荐
- 对于(不是正点原子配套的)蓝牙模块HC-05实现手机蓝牙串口APP与STM32F103ZET6开发板的通信的注意事项
- 2011大学生电子设计竞赛E题——数字锁相环实现
- STM32控制TM1638模块——基于正点原子精英STM32F103ZET6开发板
- 正点原子精英版stm32f103zet6开发板,实惠开卖
- 2019年全国大学生电子设计竞赛仪器设备和主要元器件清单(配图/整理)【本科组】
- 2019年TI杯电子设计竞赛感悟
- 终于把RSA电子签章实现了一小部分(高兴啊~!)
- 修改正点原子SPI例程——实现软件模拟读写SPI
- 用GCC开发STM32,正点原子开发板的一个库函数版本例程示例
- 《模式——工程化实现及扩展》(设计模式C# 版)《重新研读C#语言》——“自我检验" 参考答案:配置访问部分
- 2014年湖北省TI杯大学生电子设计竞赛论文格式
- 正点原子2.8寸TFTLCD接到stm32f103zet6最小系统板上显示失败解决方法
- 急求 电子设计大赛设计详细方案 用单片机的 必有重谢
- 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》
- 10-开发板接入小五物联实现远程控制(Wi-Fi模块+单片机)
- 2014年TI杯大学生电子设计竞赛地区赛使用仪器及器件、设备
- 电子设计竞赛前的点点滴滴
- 数据结构(严蔚敏)第二章部分算法设计题的实现
- 生产制造企业中电子工艺看板设计与实现
- 2016大学生电子设计竞赛赛题分析