历史上的今天
今天是:2024年12月11日(星期三)
2018年12月11日 | STM32_按键控制LED之轮询
2018-12-11 来源:eefocus
***************************************************************************************************************************************
开发板 :奋斗STM32
CPU :STM32F103
开发环境:keil uVsion4
****************************************************************************************************************************************
本文主要是通过轮询的方法来实现按键控制LED的亮灭,我初始化led为灭的状态,也就是一开始上电LED就是灭着的,当实现按键按下时,LEd亮,再按下按键是LEd灭。
led对应的开发板GPIO管脚如图:
我写的按键轮询功能是所要实现的功能是:按下K1,LED1亮(按键K1对应PC5管脚,LED1对应PB5管脚)
代码如下:
main.c
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "led.h"
#include "key.h"
int main(void)
{
SystemInit();
init_led_gpio();
Key_GPIO_Config();
/* turn_led(LED1,ON);
turn_led(LED2,ON);
turn_led(LED3,ON); */
while (1)
{
if (KeyScan(GPIOC,GPIO_Pin_5) == KEY_ON)
{
/* LED1反转 读取GPIOB 5端口位的值并用1减去之后再写入此位即LED1的控制位 */
GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)));
}
if (KeyScan(GPIOC,GPIO_Pin_2) == KEY_ON)
{
/* LED2反转 读取GPIOD 6端口位的值并用1减去之后再写入此位即LED2的控制位 */
GPIO_WriteBit(GPIOD, GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_6)));
}
if (KeyScan(GPIOC,GPIO_Pin_3) == KEY_ON)
{
/* LED3反转 读取GPIOD 3端口位的值并用1减去之后再写入此位即LED3的控制位 */
GPIO_WriteBit(GPIOD, GPIO_Pin_3,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_3)));
}
}
}
led.c
#include "stm32f10x.h"
#define ON 1
#define OFF 0
enum
{
LED1 = 0,
LED2,
LED3,
MAX_LED,
};
typedef struct led_gpio_s
{
int num; /* LED编号 */
GPIO_TypeDef *group; /* LED使用的GPIO在哪一组: GPIOB or GPIOD */
uint16_t pin; /* LED使用的GPIO组中的那一个pin: GPIO_Pin_x */
} led_gpio_t;
led_gpio_t leds_gpio[MAX_LED] =
{
{LED1, GPIOB, GPIO_Pin_5}, /* LED1 用的GPB5 */
{LED2, GPIOD, GPIO_Pin_6}, /* LED2 用的GPD6 */
{LED3, GPIOD, GPIO_Pin_3}, /* LED3 用的GPD3 */
};
/*LED的初始化*/
void init_led_gpio(void)
{
int i;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能PB和PD组 GPIO的时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);
/*设置 PB5(LED1), PD6(LED2), PD3(LED3)为 GPIO 输出推免模式,口线翻转速度为50MHz */
for(i=0; i { /*设置 PB5(LED1)为 GPIO 输出推免模式,口线翻转速度为50MHz */ GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure); } } /*使LED在初始化后处于全灭状态*/ void turn_led(int which, int cmd) { if(which return ; if(OFF == cmd) GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin); else GPIO_SetBits(leds_gpio[which].group, leds_gpio[which].pin); } key.c #include "stm32f10x.h" #define KEY_ON 1 #define KEY_OFF 0 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; while(i--); } } void Key_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_2 |GPIO_Pin_3; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init (GPIOC,&GPIO_InitStructure); } /* * @brief : 按键按下检测 * @param : 端口 : GPIOx 端口位 : GPIO_Pin_x * @retval : 按键的状态 : 按下 弹起 */ uint8_t KeyScan( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin_x ) { /* 检测是否有按键按下 */ if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON ) { /* 延时消抖 延时大约5ms */ delay_ms(5); if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON ) { while ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON ); /* 等待按键释放 */ return KEY_ON; } else { return KEY_OFF; } } return KEY_OFF; } 写这个程序主要是为了完成相关的配置工作: 1.初始化LED和初始化时钟 void init_led_gpio(void) { int i; GPIO_InitTypeDef GPIO_InitStructure; /* 使能PB和PD组 GPIO的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE); /*设置 PB5(LED1), PD6(LED2), PD3(LED3)为 GPIO 输出推免模式,口线翻转速度为50MHz */ for(i=0; i { /*设置 PB5(LED1)为 GPIO 输出推免模式,口线翻转速度为50MHz */ GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure); } } 由于奋斗STM32开发板有3个按键控制3个LED,为了代码的简洁和美观,本文用了一个for循环来实现LED的管脚的配置 2.配置按键以及初始化时钟 void Key_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_2 |GPIO_Pin_3; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init (GPIOC,&GPIO_InitStructure); } 3.delay_ms函数用于消抖 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; while(i--); } } 关于按键消抖: 按键消抖:按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。 ********************************************************************************************************************************************************************************************************************************************************
史海拾趣
|
常见电源问题征集帖。。。汇聚于此贴,各个击破 疑问者,把您们的问题描述出来高手者,把您们的思路敲打出来灌水者,把您的精力放在学习上 问题集中,集中问题集中解决集中的问题 有问题的请到此处呐喊吧,相信您的疑问会被更快的解决   ...… 查看全部问答> |
|
单位要用28027做电力线载波,可我英文不好,看了2个星期了,一点头绪都没有,那位能帮一下忙。 工作3年了,有单片机基础,前后用过5种单片机了(都还算是主流的牌子),要是学单片机的话,就是全英文的文档我也能对付,毕竟就是那些固定的寄存器之 ...… 查看全部问答> |
|
我用vs2008进行wince编程,想通过程序访问一个文件,并读取文件的内容,但是我把文件放在项目的DEBUG目录以及虚拟pocket pc的根目录下,老是出现错误,这是什么原因,是不是我哪个环节弄错了,那应该怎么办呢。 源文本文件: 1,校长,张三明 2,主 ...… 查看全部问答> |
|
推荐下载--Windows Embedded的微软认证技术专家(MCTS)及认证免费中文简体版备考工具包 http://topic.eeworld.net/u/20091125/21/fb074b0c-ad66-494c-aea5-c8137fe77582.html?seed=867673799&r=61440219#r_61440219 请过了的大虾们多多讲点备考 ...… 查看全部问答> |
|
我有一个access 的a.mdb 文件,通过active sync 下载到 wince 开发板 转换成 a.cdb 转换成功, 再转换回 .mdb 也没错误,没乱码,但就是执行sql查询 select * from [tabname] 时出现问题 调用查询 create table abc ( id int ); 也没问题 //里面原 ...… 查看全部问答> |
|
半导体照明与一般光伏电源配用的节能灯泡相比具有节能、长寿、安全、环保、色彩丰富、体积小、耐闪烁、可靠性高、调控方便等诸多优点。发光二极管作为一种新型照明光源正在获得越来越广泛的应用。 一、半导体照明特点 电子元件二极管中半 ...… 查看全部问答> |




