STM32引脚输入


前言

提示:这里可以添加本文要记录的大概内容:

课程需要:


提示:以下是本篇文章正文内容,下面案例可供参考

一、看原理图

确定要用哪个引脚?

在这里插入图片描述
确定用第一个图: PA0 上拉输入

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、开始编程

1.开启时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2.配置GPIOA.0 上拉输入

在这里插入图片描述

在这里插入图片描述

代码如下(示例):

	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	GPIO_SetBits( GPIOA, GPIO_Pin_0);//ODR 寄存器要输出1

3.读取 GPIOA.0 引脚 GPIOA_IDR 0位上是1(按键松开),输入就是高电平,否则就是低电平(按键按下)

代码如下(示例):

		temp=GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_0);
		
		if(temp==0) {
		
		  //led  亮
			GPIO_SetBits( GPIOA, GPIO_Pin_1);
			
		}
		else{
			
			//led  灭
			GPIO_ResetBits(GPIOA, GPIO_Pin_1);
			
		}

三、完整程序

#include<stm32f10x.h>

int main()
{
	u8 temp;
	GPIO_InitTypeDef GPIO_InitStruct; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
//LED 指示用

	
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
	while(1)
	{
		
		
	
		temp=GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_0);
		
		if(temp==0) {
		
		  //led  亮
			GPIO_SetBits( GPIOA, GPIO_Pin_1);
			
		}
		else{
			
			//led  灭
			GPIO_ResetBits(GPIOA, GPIO_Pin_1);
			
		}
		
	}
}









































//#include <stm32f10x.h>

//#define BIT(n)     (1<<n)

//int main()
//{
//     //PC1  配置为推挽输出
//	*((unsigned int*)(0x40021000+0x18)) |=  0X00000010;
//	
	RCC->APB2ENR |=  0X00000010;
//	RCC->APB2ENR |=  0X00000020;
//	
	GPIOC->CRL &= 1111 1111 1111 1111 1111 1111 1111 0000 1111   0X FFFF FF0F
//	GPIOC->CRL &=  0XFFFFFF0F;
	GPIOC->CRL &= 0000 0000 0000 0000 0000 0000 0011 0000   0X 0000 0030	
//	GPIOC->CRL |= 0X00000030;
//	
//	GPIOD->CRL &=  0XFF0FFFFF;	
//	GPIOD->CRL |=  0X00300000;
//	
//	
//	
//	while(1)
//	{
//		
		GPIOC->ODR  |= 0X00000002;  //给高电平的
		GPIOC->ODR  &=~ 0X00000002;  //给低电平的
		GPIOC->ODR  &= 0XFFFFFFFD;  //给低电平的
//		
//		
		GPIOC->ODR  |= 1<<1;  //给高电平的   PC1 
        GPIOC->ODR  &= ~(1<<1);  //给高电平的   PC1 
		
//		
//		GPIOC->ODR  |=  BIT(1);  //给高电平的   PC1 
//        GPIOC->ODR  &= ~BIT(1);  //给高电平的   PC1 
//		
//		GPIOD->ODR  |=  BIT(5);  //给高电平的   PD1 
//        GPIOD->ODR  &= ~BIT(5);  //给高电平的   PD1 
//		
//		
//	}
//	
//}


四 测试效果

在这里插入图片描述

按键输入2024-09-26 09-58-45-909

五、参考别人的按键代码连续和不连续触发功能

#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键0
#define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键1
#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键2 
 

#define KEY0_PRES	1		//KEY0  
#define KEY1_PRES	2		//KEY1 
#define WKUP_PRES	3		//WK_UP  
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//返回值:
//0,没有任何按键按下
//KEY0_PRES,KEY0按下
//KEY1_PRES,KEY1按下
//WKUP_PRES,WK_UP按下 
//注意此函数有响应优先级,KEY0>KEY1>WK_UP!!
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(KEY0==0)return KEY0_PRES;
		else if(KEY1==0)return KEY1_PRES;
		else if(WK_UP==1)return WKUP_PRES; 
	}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; 	     
	return 0;// 无按键按下
}

六 生成自己的 .c .文件

6.1 key.c



//PC5

#include <key.h>

void key_init()
{
		GPIO_InitTypeDef GPIO_InitStruct; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	
	
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_15;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPD;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	

}


//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//返回值:
//0,没有任何按键按下
//KEY0_PRES,KEY0按下
//KEY1_PRES,KEY1按下
//WKUP_PRES,WK_UP按下 
//注意此函数有响应优先级,KEY0>KEY1>WK_UP!!
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
	{
		//delay_ms(10);//去抖动 
		key_up=0;
		if(KEY0==0)return KEY0_PRES;
		else if(KEY1==0)return KEY1_PRES;
		else if(WK_UP==1)return WKUP_PRES; 
	}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; 	     
	return 0;// 无按键按下
}





6.2 key.h

#ifndef __KEY_H
#define __KEY_H

#include<stm32f10x.h>


#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键0
#define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键2 
 

#define KEY0_PRES	1		//KEY0  
#define KEY1_PRES	2		//KEY1 
#define WKUP_PRES	3		//WK_UP  

void key_init();

u8 KEY_Scan(u8 mode);

#endif /* __KEY_H */




6.3 延时函数 delay.c



#include <delay.h>
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 



6.4 延时函数delay.h

#ifndef __DEALAY_H
#define __DEALAY_H


#include "stm32f10x.h"

void Delay_us(uint32_t xus);

void Delay_ms(uint32_t xms);

void Delay_s(uint32_t xs);

#endif /* __DEALAY_H */



6.5 完整代码

#include<stm32f10x.h>


#include <key.h>



void led_init()
{

//LED 指示用
  GPIO_InitTypeDef GPIO_InitStruct; 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

}





int main()
{
	u8 temp;
	
	led_init();
	key_init();
//	GPIO_InitTypeDef GPIO_InitStruct; 
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
//	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_5;
//	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;
//	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
//	GPIO_Init(GPIOC, &GPIO_InitStruct);
//	
LED 指示用

//	
//	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_1;
//	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
//	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
	while(1)
	{
			
	
//		temp=GPIO_ReadInputDataBit( GPIOC, GPIO_Pin_5);
//		
//		if(temp==0) {
//		
//		  //led  亮
//			GPIO_SetBits( GPIOA, GPIO_Pin_1);
//			
//		}
//		else{
//			
//			//led  灭
//			
//			
//		}
		
		temp=KEY_Scan(1);
		if(temp==0)
		{
				GPIO_SetBits( GPIOA, GPIO_Pin_1);
		}
		
		
	}
}









//#include <stm32f10x.h>

//#define BIT(n)     (1<<n)

//int main()
//{
//     //PC1  配置为推挽输出
//	*((unsigned int*)(0x40021000+0x18)) |=  0X00000010;
//	
	RCC->APB2ENR |=  0X00000010;
//	RCC->APB2ENR |=  0X00000020;
//	
	GPIOC->CRL &= 1111 1111 1111 1111 1111 1111 1111 0000 1111   0X FFFF FF0F
//	GPIOC->CRL &=  0XFFFFFF0F;
	GPIOC->CRL &= 0000 0000 0000 0000 0000 0000 0011 0000   0X 0000 0030	
//	GPIOC->CRL |= 0X00000030;
//	
//	GPIOD->CRL &=  0XFF0FFFFF;	
//	GPIOD->CRL |=  0X00300000;
//	
//	
//	
//	while(1)
//	{
//		
		GPIOC->ODR  |= 0X00000002;  //给高电平的
		GPIOC->ODR  &=~ 0X00000002;  //给低电平的
		GPIOC->ODR  &= 0XFFFFFFFD;  //给低电平的
//		
//		
		GPIOC->ODR  |= 1<<1;  //给高电平的   PC1 
        GPIOC->ODR  &= ~(1<<1);  //给高电平的   PC1 
		
//		
//		GPIOC->ODR  |=  BIT(1);  //给高电平的   PC1 
//        GPIOC->ODR  &= ~BIT(1);  //给高电平的   PC1 
//		
//		GPIOD->ODR  |=  BIT(5);  //给高电平的   PD1 
//        GPIOD->ODR  &= ~BIT(5);  //给高电平的   PD1 
//		
//		
//	}
//	
//}

6.6 测试

在这里插入图片描述

有按键按下

在这里插入图片描述

6.6 手把手视频

建立自己模块化工程 2024-09-26

总结

123

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值