按键与中断

目录

按键LED

main.c

led.h

led.c

按键串口

按键封装

main.c

key.h

key.c

usart.h

usart.c

cpu_delay.h

cpu_delay.c


没按下时KEY1连接R16到3V3,所以没按下时是高电平,按下时导通到GND,按下是低电平

按键是输入,

按键对应的GPIO这个不需要设置上拉和下拉

cpp 复制代码
#include <stdint.h>
#include "stm32f4xx.h"

int main(void)
{		
		// KEY1 PA0 KEY2 PC4 KEY3 PC5
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
		
		GPIO_InitTypeDef GPIO_InitStruct;
		GPIO_StructInit(&GPIO_InitStruct);
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; //输入
		GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed=GPIO_Medium_Speed;
	
		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
		GPIO_Init(GPIOA,&GPIO_InitStruct);

		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
		GPIO_Init(GPIOC,&GPIO_InitStruct);
	
	
	  while(1)
		{
				uint8_t key1=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
				if(key1==Bit_RESET)
				{
						//按键被按下
						for(int i=0;i<100;i++);
				}
		}
}

按键LED

main.c

cpp 复制代码
#include <stdint.h>
#include "stm32f4xx.h"
#include "led.h"

int main(void)
{		
		// KEY1 PA0 KEY2 PC4 KEY3 PC5
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
		
		//开启LED灯时钟
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
		
		GPIO_InitTypeDef GPIO_InitStruct;
		GPIO_StructInit(&GPIO_InitStruct);
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; //输入
		GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed=GPIO_Medium_Speed;
	
		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
		GPIO_Init(GPIOA,&GPIO_InitStruct);

		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
		GPIO_Init(GPIOC,&GPIO_InitStruct);
	
		led_init();
	
	
	  while(1)
		{
				led_all_off();
			
				uint8_t key1=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
				if(key1==Bit_RESET)
				{
						led_on(1);
				}
				uint8_t key2=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4);
				if(key2==Bit_RESET)
				{
						led_on(2);
				}
				uint8_t key3=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5);
				if(key3==Bit_RESET)
				{
						led_on(3);
				}
		}
}

led.h

cpp 复制代码
#ifndef __LED_H__
#define __LED_H__

#include <stdbool.h>
#include <stdint.h>

void led_init(void);
void led_set(uint8_t idx, bool onoff);
void led_on(uint8_t idx);
void led_off(uint8_t idx);
void led_all_off(void);

#endif /* __LED_H__ */

led.c

cpp 复制代码
#include <stdbool.h>
#include "stm32f4xx.h"

// LED1: PE9
// LED2: PB1
// LED3: PB0

#define LED1_PORT   GPIOE
#define LED1_PIN    GPIO_Pin_9
#define LED2_PORT   GPIOB
#define LED2_PIN    GPIO_Pin_1
#define LED3_PORT   GPIOB
#define LED3_PIN    GPIO_Pin_0

void led_init(void)
{
	
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    
    GPIO_InitStructure.GPIO_Pin = LED1_PIN;
    GPIO_Init(LED1_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = LED2_PIN;
    GPIO_Init(LED2_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = LED3_PIN;
    GPIO_Init(LED3_PORT, &GPIO_InitStructure);
}

void led_set(uint8_t idx, bool onoff)
{
    switch (idx)
    {
        case 1:
            GPIO_WriteBit(LED1_PORT, LED1_PIN, onoff ? Bit_RESET : Bit_SET);
            break;
        case 2:
            GPIO_WriteBit(LED2_PORT, LED2_PIN, onoff ? Bit_RESET : Bit_SET);
            break;
        case 3:
            GPIO_WriteBit(LED3_PORT, LED3_PIN, onoff ? Bit_RESET : Bit_SET);
            break;
        default:
            break;
    }
}

void led_on(uint8_t idx)
{
    led_set(idx, true);
}

void led_off(uint8_t idx)
{
    led_set(idx, false);
}

void led_all_off(void)
{
    led_set(1, false);
    led_set(2, false);
    led_set(3, false);
}

按键串口

cpp 复制代码
#include <stdint.h>
#include <string.h>
#include "stm32f4xx.h"


static void usart_init(void)
{
		//初始化GPIO的引脚 TX GPIOA9 RX GPIOA10
		GPIO_InitTypeDef GPIO_InitStructure;
		GPIO_StructInit(&GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
		GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
		//初始化串口
	  USART_InitTypeDef USART_InitStructure;
		USART_StructInit(&USART_InitStructure);
	
		USART_InitStructure.USART_BaudRate=115200u;
		USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
		USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
		USART_InitStructure.USART_Parity=USART_Parity_No; //校验位
		USART_InitStructure.USART_StopBits=USART_StopBits_1;
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
		USART_Init(USART1,&USART_InitStructure);
		
			
		USART_Cmd(USART1, ENABLE);
}
//单片机发送
static void usart_write(const char str[])
{
		int len=strlen(str);
		for(int i=0;i<len;i++)
		{
				// 等待发送寄存器为空,再写入字符
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
				USART_SendData(USART1,(uint16_t) str[i]);
				// 等待字符完全发送完成
				while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
		}
}

int main(void)
{		
		// KEY1 PA0 KEY2 PC4 KEY3 PC5
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
		
		
		//开启串口时钟 另外串口的PA9和PA10的GPIOA时钟上面已经开启过
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
		GPIO_InitTypeDef GPIO_InitStruct;
		GPIO_StructInit(&GPIO_InitStruct);
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; //输入
		GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed=GPIO_Medium_Speed;
	
		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
		GPIO_Init(GPIOA,&GPIO_InitStruct);

		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
		GPIO_Init(GPIOC,&GPIO_InitStruct);
	
	
		usart_init();
	
	  while(1)
		{

			
				uint8_t key1=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
				if(key1==Bit_RESET)
				{
						usart_write("key1 pressed\r\n");
						while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET);
				}
				
				uint8_t key2=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4);
				if(key2==Bit_RESET)
				{
						usart_write("key2 pressed\r\n");
						while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4)==Bit_RESET);
				}
				
				uint8_t key3=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5);
				if(key3==Bit_RESET)
				{
						usart_write("key3 pressed\r\n");
						while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==Bit_RESET);
				}
		}
}

按键封装

main.c

按键1我加了消抖,消抖就是延迟再判断一下

按键2和按键3没有消抖,由于板子按键原理图加了电容滤波,发现加不加消抖没什么区别

cpp 复制代码
#include <stdint.h>
#include <string.h>
#include "stm32f4xx.h"
#include "key.h"
#include "usart.h"
#include "cpu_delay.h"

#define delay(ms) cpu_delay((ms)*100)

int main(void)
{		
		// KEY1 PA0 KEY2 PC4 KEY3 PC5
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
		
		
		//开启串口时钟 另外串口的PA9和PA10的GPIOA时钟上面已经开启过
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
		GPIO_InitTypeDef GPIO_InitStruct;
		GPIO_StructInit(&GPIO_InitStruct);
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; //输入
		GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
		GPIO_InitStruct.GPIO_Speed=GPIO_Medium_Speed;
	
		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
		GPIO_Init(GPIOA,&GPIO_InitStruct);

		GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
		GPIO_Init(GPIOC,&GPIO_InitStruct);
	
		key_init();
		usart_init();
	
	  while(1)
		{

				
				if(key_read(1))
				{
						//加消抖的
						delay(10);
						if(key_read(1))
						{
								usart_write("key1 pressed\r\n");
								while(key_read(1));
								delay(10);
						}
					
				}
				
				//不加消抖的
				if(key_read(2))
				{
						usart_write("key2 pressed\r\n");
						while(key_read(2));
				}
				
				//不加消抖的
				if(key_read(3))
				{
						usart_write("key3 pressed\r\n");
						while(key_read(3));
				}
		}
}

key.h

cpp 复制代码
#ifndef __KEY_H__
#define __KEY_H__

#include <stdbool.h>
#include <stdint.h>

void key_init(void);
bool key_read(uint8_t idx);

#endif /* __KEY_H__ */

key.c

cpp 复制代码
#include <stdbool.h>
#include "stm32f4xx.h"

// KEY1: PA0
// KEY2: PC4
// KEY3: PC5

#define KEY1_PORT   GPIOA
#define KEY1_PIN    GPIO_Pin_0
#define KEY2_PORT   GPIOC
#define KEY2_PIN    GPIO_Pin_4
#define KEY3_PORT   GPIOC
#define KEY3_PIN    GPIO_Pin_5

void key_init(void)
{
	
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit(&GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入
		GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
		GPIO_InitStructure.GPIO_Speed=GPIO_Medium_Speed;
    
    GPIO_InitStructure.GPIO_Pin = KEY1_PIN;
    GPIO_Init(KEY1_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = KEY2_PIN;
    GPIO_Init(KEY2_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = KEY3_PIN;
    GPIO_Init(KEY3_PORT, &GPIO_InitStructure);
}

bool key_read(uint8_t idx)
{
    switch (idx)
    {
        case 1:
            return GPIO_ReadInputDataBit(KEY1_PORT, KEY1_PIN)==Bit_RESET;
        case 2:
            return GPIO_ReadInputDataBit(KEY2_PORT, KEY2_PIN)==Bit_RESET;
        case 3:
            return GPIO_ReadInputDataBit(KEY3_PORT, KEY3_PIN)==Bit_RESET;
        default:
            return false;
    }
}

usart.h

cpp 复制代码
#ifndef __USART_H__
#define __USART_H__


void usart_init(void);
void usart_write(const char str[]);

#endif /* __USART_H__ */

usart.c

cpp 复制代码
#include <stdint.h>
#include <string.h>
#include "stm32f4xx.h"


void usart_init(void)
{
		//初始化GPIO的引脚 TX GPIOA9 RX GPIOA10
		GPIO_InitTypeDef GPIO_InitStructure;
		GPIO_StructInit(&GPIO_InitStructure);
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
		GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
		//初始化串口
	  USART_InitTypeDef USART_InitStructure;
		USART_StructInit(&USART_InitStructure);
	
		USART_InitStructure.USART_BaudRate=115200u;
		USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
		USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
		USART_InitStructure.USART_Parity=USART_Parity_No; //校验位
		USART_InitStructure.USART_StopBits=USART_StopBits_1;
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
		USART_Init(USART1,&USART_InitStructure);
		
			
		USART_Cmd(USART1, ENABLE);
}
//单片机发送
void usart_write(const char str[])
{
		int len=strlen(str);
		for(int i=0;i<len;i++)
		{
				// 等待发送寄存器为空,再写入字符
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
				USART_SendData(USART1,(uint16_t) str[i]);
				// 等待字符完全发送完成
				while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
		}
}

cpu_delay.h

cpp 复制代码
#ifndef __CPU_DELAY_H__
#define __CPU_DELAY_H__
#include <stdint.h>

void cpu_delay(uint32_t us);

#endif /* __CPU_DELAY_H__ */

cpu_delay.c

cpp 复制代码
#include "stm32f4xx.h"



void cpu_delay(uint32_t us)
{
	//上面处理ms
	while(us>1000)
	{
			//每次循环等待1ms
			SysTick->LOAD=SystemCoreClock/1000;
			SysTick->VAL=0; //当前计数器清0
			SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
			while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);//等待延迟结束
			SysTick->CTRL = ~SysTick_CTRL_ENABLE_Msk;//关闭
			us-=1000;
	}
	//下面处理us
	if(us>0)
	{
			SysTick->LOAD=(SystemCoreClock/1000/1000)*us-1;//自动转载值 系统主频
			SysTick->VAL=0; //当前计数器清0
			SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
			while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);//等待延迟结束
			SysTick->CTRL = ~SysTick_CTRL_ENABLE_Msk;//关闭
	}

}
相关推荐
曾浩轩2 小时前
跟着江协科技学STM32之4-2OLED显示屏
c语言·stm32·单片机·嵌入式硬件·学习
QK_0011 小时前
STM32--ADC
stm32·单片机·嵌入式硬件
一路往蓝-Anbo13 小时前
STM32单线串口通讯实战(五):RTOS架构 —— 线程安全与零拷贝设计
c语言·开发语言·stm32·单片机·嵌入式硬件·观察者模式·链表
向阳逐梦16 小时前
电路结构分析之半桥驱动、自举电路
单片机·嵌入式硬件
不染尘.17 小时前
操作系统发展史和常见习题汇总
arm开发·嵌入式硬件·draw.io
清风66666618 小时前
基于单片机的智能感应式汽车雨刮器控制系统设计
单片机·嵌入式硬件·汽车·毕业设计·课程设计·期末大作业
普中科技19 小时前
【普中51单片机开发攻略--基于普中-2&普中-3&普中-4】-- 第 15 章 IO 扩展(串转并)-74HC595
单片机·嵌入式硬件·51单片机·开发板·74hc595·普中科技
RaLi和夕20 小时前
硬件电路设计学习笔记3.比较器
笔记·嵌入式硬件·学习
Source.Liu21 小时前
【ESP32】 Arduino 全面介绍
单片机·物联网
manduic21 小时前
雅特力科技AT32WB415实现高性能MCU设计
科技·单片机·嵌入式硬件·雅特力