当前位置: 首页 > article >正文

STM-32:按键控制LED灯 程序详解

目录

  • 一、基本原理
  • 二、接线图
  • 三、程序思路
    • 3.1库函数
    • 3.2程序代码
  • 注:

一、基本原理

在这里插入图片描述
左边是STM322里电路每一个端口均可以配置的电路部分,右边部分是外接设备 电路图。

配置为 上拉输入模式的意思就是,VDD开关闭合,VSS开关断开。

浮空输入模式的意思就是,VDD开关断开,VSS开关断开。

下拉输入模式的意思就是,VDD开关断开,VSS开关闭合。

在 按键控制LED灯亮灭 中,必须要求配置为上拉输入模式。在按键开k1断开,及不操作的时候,上拉输入模式有VDD上拉电阻将引脚电平上拉,保证了不会出现浮动的现象。

配置好了上拉输入模式,VSS开关就已经断开了,下拉 通过K1按键开关的通断来实现的。所以在这种方式下,按下K1为低电平,松开K1位高电平。

如果外部元件如下图加上一个电阻R1(下图),就可以将端口 配置为浮空模式。R1电阻充当了上拉模式中的VDD的作用。
在这里插入图片描述

二、接线图

在这里插入图片描述

三、程序思路

3.1库函数

RCC_APB2PeriphClockCmd :使能或者失能APB2外设时钟。

GPIO_SetBits :设置指定的数据端口位。置高1。

GPIO_ResetBits :清除指定的数据端口位。置低0。

GPIO_ReadOutputDataBit :读取指定端口管脚的输出。

GPIO_ReadInputDataBit :读取指定端口管脚的输入。

3.2程序代码

LED.c

#include "stm32f10x.h"                  // Device header
void LED_Init(void)						//初始化
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2); //由于初始化后默认是为低电平,SetBits为了让端口置高。设定为了让LED开始是熄灭的状态。
}
 
void LED1_ON(void)		//LED1点亮程序
{
	GPIO_ResetBits (GPIOA, GPIO_Pin_1);
}
 
void LED1_OFF(void)		//LED1熄灭程序
{
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
 
void LED1_Turn(void)		//状态取反。实现按下送开LED亮,按下送开LED熄灭
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}
 
 
void LED2_ON(void)		//LED2点亮程序
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}
 
void LED2_OFF(void)		//LED2熄灭程序
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);
}
 
void LED2_Turn(void)		//状态取反。
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)	//读取指定端口管脚的输出。If读取的管脚(GPIO_Pin_2)输出为0。
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_2);	//就将GPIO_Pin_2置高(置1)
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);	//否则置底(置0)
	}
}

LED.h

#ifndef __LED_H
#define __LED_H
 
void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED1_Turn(void);
void LED2_ON(void);
void LED2_OFF(void);
void LED2_Turn(void);
 
#endif

Key.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
 
void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//这里需要读取按键K1,用的上拉输入。
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;	//K1按键引脚接在了,PB1和PB11两个接口上。
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
 
uint8_t Key_GetNum(void)					//右键查询:uint8_t是typedef unsigned char
{
	uint8_t KeyNum = 0;
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)	//if判断按键1按下没有松手。
	{
		Delay_ms(20);		//消抖动
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);		//还没有松手,在while里面循环。
		Delay_ms(20);		//松手,跳出while,延时消抖动。
		KeyNum = 1;	        //按键1返回1
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)   //if判断按键2按下没有松手。
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
		Delay_ms(20);
		KeyNum = 2;
	}
	
	return KeyNum;	    
}

Key.h

#ifndef __KEY_H
#define __KEY_H
 
void Key_Init(void);
uint8_t Key_GetNum(void);
 
#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
 
uint8_t KeyNum;
 
int main(void)
{
	LED_Init();
	Key_Init();
	
	while (1)
	{
		KeyNum = Key_GetNum();    //将 Key_GetNum() 返回值给KeyNum 
		if (KeyNum == 1)
		{
			LED1_Turn();
		}
		if (KeyNum == 2)
		{
			LED2_Turn();
		}
	}
}

注:

if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)

    uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);这个函数是用来读取输入寄存器(图)某一个端口的输入值的

    uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); 这个函数是用来读取整个输入寄存器的,返回值是一个16位的数据,每一位代表一个端口值

    uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 这个函数是用来读取输出寄存器(图)某一个端口的输出值的,用来看一下自己输出了什么

    uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); 这个函数是用来读取整个输出寄存器的,返回值是一个16位的数据,每一位代表一个端口值。

按下按键一端接B1端口,按键按下为低电平,if 判断 当B1端口为低电平时(按下按键),消抖之后返回值,返回1 LED1 亮起,返回2 LED2亮起。


http://www.kler.cn/a/3452.html

相关文章:

  • 2024 行远自迩,笃行不怠
  • 华为OD机试真题---战场索敌
  • NodeJs如何做API接口单元测试? --【elpis全栈项目】
  • docker 部署confluence
  • C++priority_queue模拟实现
  • 我的图形布局 组织结构图布局
  • Linux的基础知识
  • 【SSM】Spring + SpringMVC +MyBatis 框架整合
  • 【C#进阶】C# 集合类
  • C语言数据结构初阶(8)----栈与队列OJ题
  • 主线程与子线程之间相互通信(HandlerThread)
  • Gateway服务网关
  • 《硬件架构的艺术》读书笔记:Chapter 1 亚稳态的世界
  • 【pytorch】深度学习模型调参策略(一):选择架构,优化器及批大小
  • SpringBoot 整合Quartz定时任务管理【SpringBoot系列18】
  • CUDA-NVIDIA-冬令营004
  • 1.11、自动化
  • 【Java版oj】day16完全数计算、扑克牌大小
  • 国产化大趋势下学习linux的必要性
  • 【STL五】序列容器——deque容器
  • UE4 动画蓝图的优化
  • 十二届蓝桥杯省赛c++(下)
  • 如何理解IO的同步、异步、阻塞、非阻塞
  • WLAN速度突然变慢
  • 全网最火爆,Python接口自动化测试-接口依赖处理解决方案(超详细)
  • 处理数组循环中删除元素导致索引错位情况