文章目录
前言
提示:这里可以添加本文要记录的大概内容:
课程需要:
提示:以下是本篇文章正文内容,下面案例可供参考
一、看原理图
确定要用哪个引脚?
确定用第一个图: 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