完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本文展示了STM32 按键Systick 扫描 识别操作
内容涉及 IO口输入输出,枚举建立 按键按下有效,松开有效,长按有效,长按松开有效 Systicks 扫描方法 一、 编程要点 按键: 1. 使能 GPIO 端口时钟; 2. 初始化 GPIO 目标引脚为输入模式(浮空输入); 3. 编写简单测试程序,检测按键的状态,实现按键控制 LED 灯。 Systicks: 1、设置重装载寄存器的值 2、清除当前数值寄存器的值 3、配置控制与状态寄存器 二、使用步骤 1.理解原理图 代码如下: : STM32F103ZET6 输出口为PB5低电平点有效 : STM32F103ZET6 Key检测脚为PA8 2.建立Systicks输出的 头文件 Systick_book.h 代码如下(示例): #ifndef __SYSTIC_BOOK_H_ #define __SYSTIC_BOOK_H_ #include "stm32f10x.h" #include "Key_book.h" typedef enum { _Systick_us = 1, _Systick_ms = 2, _Systick_s = 3, } Systick_time_state_t; void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t); void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t); void fn_SysTick_delay_decrement(void); void SysTick_Handler(void); #endif 3.建立Systicks输出的 头文件 Systick_book.c 代码如下(示例): #include "Systick_book.h" /************************************************************ * @brief * void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t){ * @param * @retval *************************************************************/ void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t){ uint32_t i; if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);} if(_Systick_time_state_t == _Systick_ms){ SysTick_Config(SystemCoreClock/1000); } else{SysTick_Config(SystemCoreClock);} for( i=0;i<_Delay_time ; i++){ while(!((SysTick->CTRL)&(1<<16))); } SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; } /************************************************************ * @brief * void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , * Systick_time_state_t _Systick_time_state_t){ * @param * @retval *************************************************************/ static uint32_t _SysTick_delay = 0 ; void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t){ if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);} if(_Systick_time_state_t == _Systick_ms){ SysTick_Config(SystemCoreClock/1000); } else{SysTick_Config(SystemCoreClock);} _SysTick_delay = _Delay_ms ; } /************************************************************ * @brief * void fn_SysTick_delay_decrement(void) * @param * @retval *************************************************************/ static uint32_t SysTick_delay = 0 ; void fn_SysTick_delay_decrement(void){ if(SysTick_delay++ > _SysTick_delay){ SysTick_delay = 0; bkey_10ms = 1; } } /************************************************************ * @brief * void SysTick_Handler(void) * @param * @retval *************************************************************/ void SysTick_Handler(void){ fn_SysTick_delay_decrement(); } 4.建立Key采集的 头文件 Key_book.h 代码如下(示例): #ifndef __KEY_BOOK_H_ #define __KEY_BOOK_H_ #include "stm32f10x.h" #include "Led_book.h" #define KEY_IN_GPIO_Port GPIOA #define KEY_IN_GPIO_Clock RCC_APB2Periph_GPIOA #define KEY_IN_GPIO_Pin GPIO_Pin_0 #define KEY_IN_GPIO_Pin_Bit 0 #define Key_IN_GPIO_Modle GPIO_Mode_IN_FLOATING //浮空输入 typedef union { struct{ unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1; unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1; //unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1; //unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1; }DATA_BIT; uint8_t DATA_BYTE; }Per_key_type; extern volatile Per_key_type key_flag; #define bkey_10ms key_flag.DATA_BIT.BIT0 #define bkey_judge key_flag.DATA_BIT.BIT1 #define bkey_judge_long key_flag.DATA_BIT.BIT2 #define bkey_Effect key_flag.DATA_BIT.BIT3 #define bkey_LongEffect key_flag.DATA_BIT.BIT4 #define bkey_Effect_Lose key_flag.DATA_BIT.BIT5 #define bkey_Effect_LLose key_flag.DATA_BIT.BIT6 void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ); void fn_Key_Init(void); void fn_key_judge(void); void fn_key_Effect(void); void fn_key_Check(void); #endif 5.建立Key采集的 头文件 Key_book.c 代码如下(示例): #include "Key_book.h" volatile Per_key_type key_flag; /************************************************************** * @brief * void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , * uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ); * @param * @retval *************************************************************/ void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ){ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef; GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x; RCC_APB2PeriphClockCmd(_GPIO_Clock,ENABLE); GPIO_Init(_GPIO_x , &GPIO_InitStruct); } /************************************************************** * @brief * void fn_Key_Init(void); * @param * @retval *************************************************************/ void fn_Key_Init(void){ fn_Key_GPIO_Config(KEY_IN_GPIO_Port,KEY_IN_GPIO_Clock,KEY_IN_GPIO_Pin,Key_IN_GPIO_Modle); } /************************************************************ * @brief * void fn_key_judge(void); * @param * @retval **************************************************************/ #define _LONG_key 30 static uint16_t count_key ; void fn_key_judge(void){ if(!bkey_10ms){return;} bkey_10ms = 0; if(GPIO_ReadInputDataBit(KEY_IN_GPIO_Port,KEY_IN_GPIO_Pin)){ if(count_key++<3){return;} if(!bkey_judge){ bkey_judge = 1; bkey_Effect = 1; }else{ if(count_key>_LONG_key){ bkey_judge_long = 1; bkey_LongEffect = 1; } } } else{ count_key = 0; if(bkey_judge){ bkey_judge = 0; if(bkey_judge_long){ bkey_judge_long = 0; bkey_Effect_LLose = 1; }else{ bkey_judge_long = 0; bkey_Effect_Lose = 1; } }else{ bkey_judge = 0; } } } /************************************************************ * @brief * void fn_key_Effect(void); * @param * @retval *************************************************************/ void fn_key_Effect(void){ if(bkey_Effect){ bkey_Effect = 0; fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle); } } /************************************************************** * @brief * void fn_key_Check(void); * @param * @retval *************************************************************/ void fn_key_Check(void){ fn_key_judge(); fn_key_Effect(); } 6.利用之前的LED输出的 头文件 Led_book.h 代码如下(示例): #ifndef __LED_BOOK_H_ #define __LED_BOOK_H_ #include "stm32f10x.h" #define LED_OUT_GPIO_Port GPIOB //GPIO Point #define LED_OUT_GPIO_Clock RCC_APB2Periph_GPIOB //GPIO clock #define LED_OUT_GPIO_Pin GPIO_Pin_5 #define LED_OUT_GPIO_Pin_Bit 5 #define LED_OUT_GPIO_Modle GPIO_Mode_Out_PP typedef enum { LED_Corporate_On = 1, LED_Corporate_OFF = 2, LED_Corporate_Toggle = 3, } LED_Corporate_state_t; void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef); void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , LED_Corporate_state_t _LED_Corporate_state_t ); #endif 7.利用之前的LED输出的 头文件 Led_book.c 代码如下(示例): #include "Led_book.h" #define LED_GPIO_Speed GPIO_Speed_10MHz void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef){ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef; GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x; GPIO_InitStruct.GPIO_Speed = LED_GPIO_Speed; RCC_APB2PeriphClockCmd(_GPIO_Clock ,ENABLE); GPIO_Init(_GPIO_x , &GPIO_InitStruct) ; } void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , LED_Corporate_state_t _LED_Corporate_state_t ){ switch(_LED_Corporate_state_t){ case LED_Corporate_On : GPIO_SetBits(_GPIO_x,_GPIO_Pin_x); break; case LED_Corporate_OFF: GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x); break; case LED_Corporate_Toggle: GPIO_ReadOutputDataBit(_GPIO_x,_GPIO_Pin_x)?GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x):GPIO_SetBits(_GPIO_x,_GPIO_Pin_x); break; } } //practice //fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_OUT_GPIO_Pin,LED_OUT_GPIO_Modle); // while(1){ // delay(10000); // fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle); // } 8.建立Systicks Key输出的 主程序 main.c 代码如下(示例): /** ****************************************************************************** * @file GPIO/JTAG_Remap/main.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main program body ****************************************************************************** * @attention * * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "PROJ_book.h" /* Private functions ---------------------------------------------------------*/ /** * @brief Main program. * @param None * @retval None */ void delay(int x); void fn_Main_Init(void); int main(void) { // fn_HRCC_SetSystic(RCC_PLLMul_9 ); // fn_IRCC_SetSystic(RCC_PLLMul_9 ); // fn_MCO_GPIO_Config(); fn_Led_Init(); fn_Key_Init(); fn_Main_Init(); fn_Systick_Delay_Handler_set(10,_Systick_ms); while(1){ fn_key_Check(); } } void fn_Main_Init(void){ uint16_t count_Init = 2; while(count_Init-->0){ __LED_OUT__; fn_Systick_Delay(500,_Systick_ms); __LED_OUT__; fn_Systick_Delay(100,_Systick_ms); __LED_OUT__; fn_Systick_Delay(100,_Systick_ms); __LED_OUT__; fn_Systick_Delay(500,_Systick_ms); } } void delay(int x){ int y = 0xFFFFF; while((x--)>0){ while((y--)>0){ __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } } } /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ STM32 Systick 笔记 STM32 RCC – RCC 程序 STM32 RCC – LED 程序 STM32 RCC – 主程序 09 _STM32f103 时钟树 RCC 总结 SysTick简介: 系统定时器,24位,只能递减,存在于内核,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。 counter在时钟的驱动下,从reload初值开始往下递减计数到0: 产生中断和置位COUNTFLAG标志。 然后又从reload值开始重新递减计数,如此循环。 1-t:一个计数循环的时间,跟reload和CLK有关 2-CLK:72M或者9M,由CTRL寄存器配置 3-RELOAD:24位,用户自己配置 t = reload * ( 1/clk ) Clk = 72M时,t = (72) *(1/ 72 M )= 1US Clk = 72M时,t = (72000) *(1/ 72 M )= 1MS 时间单位换算: 1s = 1000ms = 1000 000 us = 1000 000 000ns |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:14 , Processed in 1.141384 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号