目录
概要
1.实验名称:按键控制LED
2.实验环境:STM32F103C8T6最小系统板
3.实验内容:两个按键分别控制两个LED的亮灭
4.作者;abai
5.实验时间:2025-2-18
技术实现
1.硬件接线图
2.引脚定义
3.代码实现
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h" //延时函数
#include "LED.h" //LED模块函数
#include "Key.h"
uint8_t Key_Num;
int main(void)
{
LED_Init();
Key_Init();
while(1)
{
Key_Num = Key_GetNum();
if(Key_Num == 1)
{
LED1_Turn();
}
if(Key_Num == 2)
{
LED2_Turn();
}
}
}
LED.h
#ifndef __LED_H__
#define __LED_H__
#include "stm32f10x.h" // Device header
#include "Delay.h"
void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED2_ON(void);
void LED2_OFF(void);
void LED1_Turn(void);
void LED2_Turn(void);
#endif
LED.c
#include "LED.h"
/**
* @brief 设置高速总线APB2外围时钟
* 初始化GPIO
* 将LED置为熄灭状态
* @param None
* @retval None
*/
void LED_Init(void)
{
/*
高速总线外围时钟设置
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*
配置端口
*/
GPIO_InitTypeDef GPIO_InitStruct; //定义结构体
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; //选择PA1和PA2引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
/*
默认将LED熄灭
*/
GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
}
/**
* @brief 打开LED1
* @param None
* @retval None
*/
void LED1_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
/**
* @brief 关闭LED1
* @param None
* @retval None
*/
void LED1_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
/**
* @brief 打开LED2
* @param None
* @retval None
*/
void LED2_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
/**
* @brief 关闭LED2
* @param None
* @retval None
*/
void LED2_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
/**
* @brief 将LED1的状态取反
* @param None
* @retval None
*/
void LED1_Turn(void)
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)) //读取数据输出寄存器中PA1引脚的状态
{
LED1_ON();
}
else
{
LED1_OFF();
}
}
/**
* @brief 将LED2的状态取反
* @param None
* @retval None
*/
void LED2_Turn(void)
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)) //读取数据输出寄存器中PA2引脚的状态
{
LED2_ON();
}
else
{
LED2_OFF();
}
}
Key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32f10x.h" // Device header
#include "Delay.h"
void Key_Init(void);
uint8_t Key_GetNum(void);
#endif
Key.c
#include "Key.h"
/**
* @brief 设置高速总线APB2外围时钟
* 配置GPIO端口
* @param None
* @retval None
*/
void Key_Init(void)
{
/*
高速总线APB2外围时钟设置
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*
配置端口
*/
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //选择上拉输入模式
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
/**
* @brief 读取按键的值
* @param None
* @retval 按键的值
*/
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1))
{
Delay_ms(20);
while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1));
Delay_ms(20);
KeyNum = 1;
}
if(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11))
{
Delay_ms(20);
while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11));
Delay_ms(20);
KeyNum = 2;
}
return KeyNum;
}
Delay.h
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
Delay.c
#include "stm32f10x.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);
}
}
实验要点
1.使用函数uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)用于读取数据输入寄存器中的某一位。该函数的返回值为uint8_t型,即unsigned char型,但在STM32中使用typedef声明的别名。该函数同时接收两个形参,第一个形参为要设置的外围设备,第二个参数为要读取的端口。
2.输入模式选择:GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU,程序中选择了上拉输入模式,在默认状态下,输入引脚默认为高电平,当按键按下后,该输入引脚被拉低。
问题总结
无