stm32之点亮LED

发布于:2024-03-28 ⋅ 阅读:(189) ⋅ 点赞:(0)

学习stm32单片机的时候,会有三种,标准库,寄存器,HAL库。这里我们统一使用HAL库,使用stm32cubemx来建工程。会方便很多简化我们编写代码的时间但其实不管是HAL库还是标准库都是操作寄存器的只是官方给我们封装好了。软件就不演示安装了 。欢迎各位指出我的错误,共同进步。

我们通过每个案例来介绍单片机的知识点,流水的单片机,铁打的LED灯。大部分来说不管是什么单片机都是以点亮LED灯为基础

目录

一分析原理图

二GPIO

 2.1 什么是GPIO?

2.2GPIO的特点

2.3GPIO的八种模式分析

三stm32cubemx配置

四代码分析


一分析原理图

 这里我们根据给的原理图,找到led的区域。

先看LED0 是和PB5引脚相连的 即PB5引脚控制着LED0的电平,上接3.3V电压,即默认是高电平,所以我们将PB5设置为低电平的时候,电路导通

(这里我们说明一下,电路导通,是需要一个高电平和一个低电平导致电流可以正常流通的。这里根据原理图发现PB5这个引脚所在的电路,是外接的有3.3V的VCC,即板子一上电就会有高电平)

所以我们想让LED0亮,就将PB5引脚设置为低电平。LED1同理。

那我们怎么设置,能否设置引脚为低电平或高电平呢?

二GPIO

 2.1 什么是GPIO?

概述:General Purpose Input Output,即通用输入输出端口,简称GPIO 作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出。

是不是很迷糊,简单来就是控制引脚使其能够达到输入和输出电平的操作。

比如我们这里的LED,我们需要将PB5设置为低电平,那是输入还是输出呢?

注意:这里的输入和输出的操作对象即主体是单片机。所以我们需要单片机去给PB5引脚输出低电平。即设置为输出模式。

2.2GPIO的特点

1,不同型号,IO口数量可能不一样,可通过选型手册快速查询

2,快速翻转,每次翻转最快只需要两个时钟周期(F1最高速度可以到50Mhz)

3,每个IO口都可以做中断      (后面会说明什么是中断)

4,支持8种工作模式

2.3GPIO的八种模式分析

我们具体分析一下每一个模式

 这里是不通过任何的上下拉,走向如图直接IO引脚到输入寄存器IDR

这里0和1是什么意思呢?当我们设置0的时候就是0 设置1就是1 当空闲的时候,即人为不设置的时候,上拉电阻打开,VDD是高电平即空闲的时候 IO是高电平 

 这里如果设置是下拉,空闲的时候因为下拉电阻的打开下接了VSS是低电平

 上拉电阻和下拉电阻,TTL都关闭 即模拟输入

 

 

这里补充一下,当IO口设置为输出模式的时候,也是可以读取IO的电平状态的。 

正常情况开漏和推挽的区别是:开漏输出无法输出高电平(必须加外部上拉电阻),推挽可以

这里我们总结一下GPIO的八种模式 又可以分为输出和输入

输入:1 浮空输入

           2 上拉输入

           3 下拉输入

           4 模拟输入

输出:1 开漏输出

           2 复用开漏

           3 推挽

           4 复用推挽

三stm32cubemx配置

我们说完了GPIO的基础知识我们来看怎么用cubemx来配置

这里我们新建工程

输入自己单片机的型号

 点system core,然后点RCC配置时钟

 选择外部时钟

 

关于时钟树,大家可以去看正点原子的视频很详细。

 将PB4,PE5 设置为输出

 第一个是你项目的名字 第二个一定要选择MDK-ARM

 点击生成就好了

四代码分析

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化GPIO使用的结构体变量

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();//打开gpioe的时钟
  __HAL_RCC_GPIOB_CLK_ENABLE();//打开gpiob的时钟

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);//将PE5 设置为低电平

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);//将PB5 设置为低电平

  /*Configure GPIO pin : PE5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;//选择引脚号
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;//无上下拉,输出一般是无上下拉
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//传输速度
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);//初始化GPIO

  /*Configure GPIO pin : PB5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

这里我们打开gpio.c 可以看到相关的代码,这里我们根据代码的顺序涉及到的知识,一个一个描述,会涉及的有点多。

首先我们初始化某个GPIO引脚的第一步,找到设置变量的数据类型是一个结构体

1 我们先设置变量初始化为0 我们来看一下这个结构体变量的成员

GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化GPIO使用的结构体变量

go to 一下找到这个结构体的定义 

typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;

 这里就是结构体的成员,分别是 引脚号,模式,上下拉选择,速度 这里就不一一go to给大家看了 大家自己看一下,这里的官方定义也给的很详细。

2 打开对应的时钟

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();//打开gpioe的时钟
  __HAL_RCC_GPIOB_CLK_ENABLE();//打开gpiob的时钟

3 设置gpio变量各成员的值

  /*Configure GPIO pin : PE5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;//选择引脚号
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;//无上下拉,输出一般是无上下拉
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//传输速度

4 初始化变量

  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);//初始化GPIO变量

补充:这里我们可以看到有涉及到一个HAL库函数,函数是将PE5 设置为低电平

  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);//将PE5 设置为低电平

我们看一下函数原型,和官方给的函数解释

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

Sets or clears the selected data port bit 

大概意思是将某个引脚设置为 高/低 电平

到这里GPIO对应的引脚就初始化完成了,这里我们还没有编写主函数的代码,但是我们已经通过HAL_GPIO_WritePin函数将俩个函数的引脚设置为低电平了,根据一分析原理图的时候,知道将引脚设置为低电平的时候电路就导通了,LED会亮,我们来烧录一下试试

这里先编译,然后再烧录

灯是亮的,我们这里已经完成了最初的目的,这里我们在主函数里面添加代码来实现流水灯的效果,并通过#define 来封装一下相关引脚 方便移植

 

这里我封装了LED0 和LED1 

 主函数while(1)死循环里面的代码实现了灯的闪烁

LED

这里烧录一下就可以完成目的了

五 通过按键控制LED的亮灭

5.1 key的原理图分析

这里大家想一下,按键是输入还是输出,按键按下得到电平变化,是向单片机输入信号的,所以配置为输入 (还有一种说法,按键按下单片机是需要采集信号的,所以是像单片机输入)

 这里我们看原理图当按键没有按下的时候,电平不确定,是高阻态。当按键按下的时候PA0是高电平,我们需要将PA0设置为俩种状态来区分是否按键按下,已知按下是高电平 所以我们需要设置为下拉输入,按键不按下的时候是低电平

同理 PE4 PE3 就上拉输入

补充:按键我们需要延时10ms 消抖

5.2cubemx配置

PA0

PE3 PE4是一样的就举一个 

5.3代码

在演示代码前,我们先说几个库函数

1 读取某引脚的电平状态,原型可以go to 

HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

2 翻转某引脚的电平 

HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

3 延时函数 单位ms

 HAL_Delay(uint32_t Delay)

gpio.h的一些封装 

 主函数的代码

  while (1)
  {
		if(HAL_GPIO_ReadPin(KEY_UP_PORT,KEY_UP_PIN)==1)//读取key_up的电平是否为1 为1即按键按下
		{			
     HAL_Delay(10);
     if(HAL_GPIO_ReadPin(KEY_UP_PORT,KEY_UP_PIN)==1)//读取key_up的电平是否为1 为1即按键按下
		 {
			 	HAL_GPIO_TogglePin(LED0_PORT,LED0_PIN);
				HAL_GPIO_TogglePin(LED1_PORT,LED1_PIN);	
		 }			 
		}
		
		if(HAL_GPIO_ReadPin(KEY0_PORT,KEY0_PIN)==0)
		{
			HAL_Delay(20);
			if(HAL_GPIO_ReadPin(KEY0_PORT,KEY0_PIN)==0)
			{
				HAL_GPIO_TogglePin(LED0_PORT,LED0_PIN);
			}
		}	
		
		if(HAL_GPIO_ReadPin(KEY1_PORT,KEY1_PIN)==0)
		{
			HAL_Delay(20);
			if(HAL_GPIO_ReadPin(KEY1_PORT,KEY1_PIN)==0)
			{
				HAL_GPIO_TogglePin(LED1_PORT,LED1_PIN);
			}
		}		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

这里需要工程的私聊我就好

本文含有隐藏内容,请 开通VIP 后查看

微信公众号

今日签到

点亮在社区的每一天
去签到