- 说明:源代码和教程可从野火处下载,本博客为了记录学习过程
- STM32(四):STM32指南者-跑马灯实验的基础上
- 一、采用轮询方式
- 1、bsp_key.h
- 2、bsp_key.c
- 3、main.c
- 二、采用中断方式
- 1、bsp_exti.h
- 2、bsp_exti.c
- 3、stm32f10x_it.c
- 4、main.c
一、采用轮询方式
放在while(1)循环里,系统不停识别按键状态来控制彩灯
1、bsp_key.h
#ifndef __KEY_H
#define __KEY_H#include "stm32f10x.h"// 引脚定义:检测按键输入的GPIO端口、GPIO引脚号以及GPIO端口时钟封装起来;Key1:PA0;Key2:PC13(可查开发板规格书)
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_PIN GPIO_Pin_0#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_PIN GPIO_Pin_13/** 按键按下标置宏* 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0* 若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可*/
#define KEY_ON 1
#define KEY_OFF 0void Key_GPIO_Config(void);//按键初始化函数
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);#endif /* __KEY_H */
2、bsp_key.c
/********************************************************************************* @file bsp_key.c* @author fire* @version V1.0* @date 2013-xx-xx* @brief 按键应用bsp(扫描模式)******************************************************************************* @attention** 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn* 淘宝 :https://fire-stm32.taobao.com********************************************************************************/ #include "./Key/bsp_key.h" /*** @brief 配置按键用到的I/O口* @param 无* @retval 无*/
void Key_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*开启按键端口的时钟*/RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);//选择按键的引脚GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN; // 设置按键的引脚为浮空输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 由于引脚的默认电平受按键电路影响,所以设置成浮空输入。//使用结构体初始化按键GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);//选择按键的引脚GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN; //设置按键的引脚为浮空输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //使用结构体初始化按键GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);
}/** 函数名:Key_Scan* 描述 :检测是否有按键按下* 输入 :GPIOx:x 可以是 A,B,C,D或者 E* GPIO_Pin:待读取的端口位 * 输出 :KEY_OFF(没按下按键)、KEY_ON(按下按键)*/
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{ /*检测是否有按键按下 */if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) { /*等待按键释放 */while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); //一次↓↑输出一次KEY_ON,否则当只有↓没有↑的时候一直在循环不输出return KEY_ON; }elsereturn KEY_OFF;
}
/*********************************************END OF FILE**********************/
3、main.c
/********************************************************************************* @file main.c* @author fire* @version V1.0* @date 2013-xx-xx* @brief 测试led******************************************************************************* @attention** 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn* 淘宝 :https://fire-stm32.taobao.com********************************************************************************/ #include "stm32f10x.h"
#include "./Led/bsp_led.h"
#include "./Key/bsp_key.h" //#define SOFT_DELAY Delay(0x0FFFFF);//void Delay(__IO u32 nCount); /*** @brief 主函数* @param 无 * @retval 无*/
int main(void)
{ /* LED 端口初始化 */LED_GPIO_Config(); /*初始化按键*/Key_GPIO_Config();// while (1)
// {
// LED1_ON; // 亮
// SOFT_DELAY;
// LED1_OFF; // 灭// LED2_ON; // 亮
// SOFT_DELAY;
// LED2_OFF; // 灭// LED3_ON; // 亮
// SOFT_DELAY;
// LED3_OFF; // 灭 // /*轮流显示 红绿蓝黄紫青白 颜色*/
// LED_RED;
// SOFT_DELAY;
//
// LED_GREEN;
// SOFT_DELAY;
//
// LED_BLUE;
// SOFT_DELAY;
//
// LED_YELLOW;
// SOFT_DELAY;
//
// LED_PURPLE;
// SOFT_DELAY;
//
// LED_CYAN;
// SOFT_DELAY;
//
// LED_WHITE;
// SOFT_DELAY;
//
// LED_RGBOFF;
// SOFT_DELAY;
// }/* 轮询按键状态,若按键按下则反转LED */while(1) { if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON ){/*LED1反转*/LED1_TOGGLE;} if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON ){/*LED2反转*/LED2_TOGGLE;} }}//void Delay(__IO uint32_t nCount) //简单的延时函数
//{
// for(; nCount != 0; nCount--);
//}
/*********************************************END OF FILE**********************/
烧进去就OK啦!
二、采用中断方式
利用EXTI中断,按下按键(上升沿或下降沿)会触发中断
1、bsp_exti.h
#ifndef __EXTI_H
#define __EXTI_H#include "stm32f10x.h"//dym1:引脚定义
//配置key1的GPIO引脚
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)//除了开GPIO的端口时钟外,我们还打开了AFIO的时钟, 这是因为等下配置EXTI信号源的时候需要用到AFIO的外部中断控制寄存器AFIO_EXTICRx//故:使用 GPIO 之前必须开启 GPIO 端口的时钟;用到 EXTI 必须开启 AFIO 时钟。
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
//配置key1的中断
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
#define KEY1_INT_EXTI_LINE EXTI_Line0 //EXTI中断/事件线选择,可选EXTI0至EXTI19
#define KEY1_INT_EXTI_IRQ EXTI0_IRQn //配置向量控制器NVIC的中断向量//注意:Line0-4为EXTIX_IRQn,Line5-9都为EXTI9_5_IRQn,Line10-15都为EXTI15_10_IRQn#define KEY1_IRQHandler EXTI0_IRQHandler//配置key2的GPIO引脚
#define KEY2_INT_GPIO_PORT GPIOC
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_13#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13
#define KEY2_INT_EXTI_LINE EXTI_Line13
#define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn#define KEY2_IRQHandler EXTI15_10_IRQHandler//dym3:配置 IO为EXTI中断口,并设置中断优先级
void EXTI_Key_Config(void);#endif /* __EXTI_H */
2、bsp_exti.c
/********************************************************************************* @file bsp_exti.c* @author fire* @version V1.0* @date 2013-xx-xx* @brief I/O线中断应用bsp******************************************************************************* @attention** 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn* 淘宝 :https://fire-stm32.taobao.com********************************************************************************/#include "bsp_exti.h"/*** @brief dym2:配置嵌套向量中断控制器NVIC* @param 无* @retval 无*/
static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 配置NVIC为优先级组1 *//* 提示 NVIC_PriorityGroupConfig() 在整个工程只需要调用一次来配置优先级分组!!!*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中断源:按键1 */NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;/* 配置抢占优先级 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 配置子优先级 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中断通道 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* 配置中断源:按键2,其他使用上面相关配置 */ NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;NVIC_Init(&NVIC_InitStructure);
}/*** @brief dym3:配置 IO为EXTI中断口,并设置中断优先级* @param 无* @retval 无*/
void EXTI_Key_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;/*开启按键GPIO口的时钟*/RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);/* 配置 NVIC 中断*/NVIC_Configuration();/*--------------------------KEY1配置-----------------------------*//* 选择按键用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;/* 配置为浮空输入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);/* 选择EXTI的信号源 */GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;/* EXTI为中断模式 */EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 上升沿中断 */EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;/* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);/*--------------------------KEY2配置-----------------------------*//* 选择按键用到的GPIO */ GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;/* 配置为浮空输入 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);/* 选择EXTI的信号源 */GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;/* EXTI为中断模式 */EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/* 下降沿中断 */EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;/* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
}
/*********************************************END OF FILE**********************/
3、stm32f10x_it.c
/********************************************************************************* @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author MCD Application Team* @version V3.5.0* @date 08-April-2011* @brief Main Interrupt Service Routines.* This file provides template for all exceptions handler and * peripherals interrupt service routine.******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "./Led/bsp_led.h"
#include "./Key/bsp_exti.h"
/** @addtogroup STM32F10x_StdPeriph_Template* @{*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/* Cortex-M3 Processor Exceptions Handlers */
/******************************************************************************//*** @brief This function handles NMI exception.* @param None* @retval None*/
void NMI_Handler(void)
{
}/*** @brief This function handles Hard Fault exception.* @param None* @retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** @brief This function handles Memory Manage exception.* @param None* @retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** @brief This function handles Bus Fault exception.* @param None* @retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** @brief This function handles Usage Fault exception.* @param None* @retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** @brief This function handles SVCall exception.* @param None* @retval None*/
void SVC_Handler(void)
{
}/*** @brief This function handles Debug Monitor exception.* @param None* @retval None*/
void DebugMon_Handler(void)
{
}/*** @brief This function handles PendSVC exception.* @param None* @retval None*/
void PendSV_Handler(void)
{
}/*** @brief This function handles SysTick Handler.* @param None* @retval None*/
void SysTick_Handler(void)
{
}//dym4:配置中断函数!!!!!
void KEY1_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {// LED1 取反 LED1_TOGGLE;//清除中断标志位EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE); }
}void KEY2_IRQHandler(void)
{//确保是否产生了EXTI Line中断if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {// LED2 取反 LED2_TOGGLE;//清除中断标志位EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE); }
}
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handler's name please refer to the startup */
/* file (startup_stm32f10x_xx.s). */
/******************************************************************************//*** @brief This function handles PPP interrupt request.* @param None* @retval None*/
/*void PPP_IRQHandler(void)
{
}*//*** @}*/ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
4、main.c
/********************************************************************************* @file main.c* @author fire* @version V1.0* @date 2013-xx-xx* @brief 按键测试(中断模式/EXTI模式)******************************************************************************* @attention** 实验平台:野火 F103-指南者 STM32 开发板 * 论坛 :http://www.firebbs.cn* 淘宝 :https://fire-stm32.taobao.com********************************************************************************/ #include "stm32f10x.h"
#include "./Led/bsp_led.h"
#include "./Key/bsp_key.h"
#include "./Key/bsp_exti.h" /*** @brief 主函数* @param 无* @retval 无*/
int main(void)
{/* LED 端口初始化 */LED_GPIO_Config();/* 初始化EXTI中断,按下按键会触发中断,* 触发中断会进入stm32f4xx_it.c文件中的函数* KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。*/EXTI_Key_Config(); /* 等待中断,由于使用中断方式,CPU不用轮询按键 */while(1) {}
}
/*********************************************END OF FILE**********************/
烧进去就OK啦!