原画图讲解 本教程使用是(光明谷SUN_STM32mini开发板) 首先了硬件连接原理,STM32F103RCT6开发板是mini最小系统板,板子在没并有按键。需要自行用面包板搭建。 硬件连接: PC10 -> KEY1 (MCU内部上拉) --> GND (低电平有效) PC11 -> KEY2(MCU内部上拉) --> GMD (低电平有效) 程序设计 有两种方法: 方法1、不断检测引脚(PC10, PC11)电平, 当检测到引脚(PC10, PC11)为低电平时,则有按键按下; 方法2、中断检测,设置引脚(PC10, PC11)下降沿触中断,在中断函数里,判断是哪个引脚发生的中断。 现在我们用方法1,编写代码。下集我们用中断方法。 编写代码
- 复制上节工程文件夹打开(这个方法比较方便)
- 新建源文件key.c,添加key.c到BSP(Grounp),并编辑
/**********************************************************************************
* 文件名 :key.c
* 描述 :按键扫描(系统滴答时钟SysTick实现扫描延时)
* 实验平台:Sun_STM32Min系统板
* 硬件连接: PC10 -> KEY1 --> GND
* PC11 -> KEY2 --> GMD
* 库版本 :ST_v3.5
* Version Date Auther Reversed History
----------------------------------------------------------------------------
V1.0.0 2021-11-07 Lojam Fan Fisrt Created
* (C) Sunshine Silicon Corporation
* Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
* E-Mail : fan@sunsili.com
**********************************************************************************/
#include "key.h"
#include "SysTick.h"
/*******************************************************************************
* 函数名 : Key_GPIO_Config
* 描述 : KEY IO配置
* 输入 : 无
* 输出 : 无
* 返回 : 无
* 说明 : KEY(1~2)的IO口分别是:PC10,PC11
*******************************************************************************/
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体
RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE); //使能GPIOA的外设时钟
GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2; //选择要初始化的GPIOA引脚(PA15,PA14)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置引脚工作模式为上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚输出最大速率为50MHz
GPIO_Init(KEY_PORT, &GPIO_InitStructure); //调用库函数中的GPIO初始化函数,初始化GPIOA中的PA15,PA14引脚
}
/*******************************************************************************
* 函数名 : Key_Detection
* 描述 : 按键按下检测
* 输入 : GPIOx:按键对应的GPIO,GPIO_Pin:对应按键端口
* 输出 : 无
* 返回 : KEY_DOWN(0):对应按键按下,KEY_UP(1):对应按键没按下
* 说明 : KEY(1~2)的IO口分别是:PC10,PC11
*******************************************************************************/
u8 Key_Down_Detection(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
{
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN) //检测是否有按键按下
{
Delay_nMs(10); //延时消抖
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN) //检测是否有按键按下
{
while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN); //等待按键释放
return KEY_DOWN;
}
else
{
return KEY_UP;
}
}
else
{
return KEY_UP;
}
}
/*******************************************************************************
* 函数名 : Key_Down_Scan
* 描述 : 按键按下扫描
* 输入 : 无
* 输出 : 0:没有按键按下,
1:按键按下
* 返回 : 无
* 说明 : KEY(1~2)的IO口分别是:PC10,PC11
*******************************************************************************/
u8 Key_Down_Scan(void)
{
u16 downflag=0;
u8 value=0;
downflag=GPIO_ReadInputData(KEY_PORT);
if((downflag & 0x0c00) != 0x0c00) //检测是否有按键按下
{
Delay_nMs(10); //延时消抖
downflag = GPIO_ReadInputData(KEY_PORT) & 0x0c00;
if(downflag != 0x0c00 ) //检测是否有按键按下
{
if((downflag & 0x0400) == 0) value |= 0x01;
if((downflag & 0x0800) == 0) value |= 0x02;
}
}
return value;
}
/******************* (C) COPYRIGHT SUNSHINE SILICON **************************
******************** END OF FILE key.c *******************/
- 新建源文件key.h,并编辑
/**********************************************************************************
* 文件名 :led.c
* 描述 :led 应用函数库
* 实验平台:Sun_STM32Min系统板
* 硬件连接: PA5 -> LED1 板子上没有 要用杜绑线外接
* PA6 -> LED2 板子上没有 要用杜绑线外接
* PA7 -> LED3 板子上没有 要用杜绑线外接
* PA8 -> LED4 板子有直接观察
* GPIO置低电平亮LED
* 库版本 :ST_v3.5
* Version Date Auther Reversed History
----------------------------------------------------------------------------
V1.0.0 2021-11-07 Lojam Fan Fisrt Created
* (C) Sunshine Silicon Corporation
* Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
* E-Mail : fan@sunsili.com
**********************************************************************************/
#include "Led.h"
/*******************************************************************************
* 函数名 : LED_GPIO_Config
* 描述 : LED IO配置
* 输入 : 无
* 输出 : 无
* 返回 : 无
* 说明 : LED(1~4)的IO口分别是:PB5,PB6,PB7,PB8
*******************************************************************************/
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体
RCC_APB2PeriphClockCmd(LED_RCC, ENABLE); //使能GPIOB的外设时钟
GPIO_InitStructure.GPIO_Pin = LED_ALL; //选择要初始化的GPIOB引脚(PB5,PB6,PB7,PB8)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚工作模式为通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚输出最大速率为50MHz
GPIO_Init(LED_PORT, &GPIO_InitStructure); //调用库函数中的GPIO初始化函数,初始化GPIOB中的PB5,PB6,PB7,PB8引脚
LED_ALL_OFF(); //关闭ALL_LED
}
/*点亮LED1.PA5*/
void LED1_ON(void)
{
GPIO_ResetBits(LED_PORT,LED1);
}
/*关闭LED1.PA5*/
void LED1_OFF(void)
{
GPIO_SetBits(LED_PORT,LED1);
}
/*点亮LED2.PA6*/
void LED2_ON(void)
{
GPIO_ResetBits(LED_PORT,LED2);
}
/*关闭LED2.PA6*/
void LED2_OFF(void)
{
GPIO_SetBits(LED_PORT,LED2);
}
/*点亮LED3.PA7*/
void LED3_ON(void)
{
GPIO_ResetBits(LED_PORT,LED3);
}
/*关闭LED3.PA7*/
void LED3_OFF(void)
{
GPIO_SetBits(LED_PORT,LED3);
}
/*点亮LED4.PA8*/
void LED4_ON(void)
{
GPIO_ResetBits(LED_PORT,LED4);
}
/*关闭LED4.PA8*/
void LED4_OFF(void)
{
GPIO_SetBits(LED_PORT,LED4);
}
/*点亮ALL_LED*/
void LED_ALL_ON(void)
{
GPIO_ResetBits(LED_PORT,LED_ALL);
}
/*关闭ALL_LED*/
void LED_ALL_OFF(void)
{
GPIO_SetBits(LED_PORT,LED_ALL);
}
/******************* (C) COPYRIGHT SUNSHINE SILICON **************************
******************** END OF FILE led.c *******************/
- 编辑main.c
/**********************************************************************************
* Sun STM32 mini Demo
* Description
Uart Demo
* Version Date Auther Reversed History
----------------------------------------------------------------------------
V1.0.0 2021-11-07 Lojam Fan Fisrt Created
* (C) Sunshine Silicon Corporation
* Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
* E-Mail : fan@sunsili.com
**********************************************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include <stdio.h>
extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN]; //串口1数据接收缓冲区
extern vu8 Usart1_R_State; //串口1接收状态
extern vu16 Usart1_R_Count; //当前接收数据的字节数
/*******************************************************************************
* 函数名 : main
* 描述 : 主函数,用户程序从main函数开始运行
* 输入 : 无
* 输出 : 无
* 返回值 : int:返回值为一个16位整形数
* 说明 : 无
*******************************************************************************/
int main(void)
{
u8 keyVal;
SysTick_Init_Config();
USART1_Init_Config(115200);//USART1初始化配置
LED_GPIO_Config();
Key_GPIO_Config();
printf ("*===================================================*\n");
printf ("* * Name: Sun STM32 mini Demo Code. *************\n");
printf ("* * (C) Sunshine Silicon Corporation *************\n");
printf ("* * Website: http://www.sunsili.com *************\n");
printf ("* * E-Mail : fan@sunsili.com *************\n");
printf ("*===================================================*\n");
printf ("* Sun STM32 mini Key Demo code .*\n");
while (1)
{
keyVal = Key_Down_Scan();
if(Usart1_R_State == 1)//一帧数据接收完成
{
USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count); //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
Usart1_R_State =0;
Usart1_R_Count =0;
}
if(keyVal)
{
printf("KeyVal:%d\r", keyVal);
if(keyVal & 0x01) LED3_ON();
else if(keyVal & 0x02) LED4_ON();
}
else LED_ALL_OFF();
}
}
/******************* (C) COPYRIGHT SUNSHINE SILICON **************************
******************** END OF FILE main.c *******************/
- 编译调试
方法不再重复,经过前两节练习,大家应该是会了. 连接串口打印,输出按键值。按下按键对应灯会亮。 查看原文,可以下载工程源码 |