STM32之初学点亮led灯

本文介绍了如何使用STM32微控制器通过固件库函数和直接操作寄存器来控制GPIOB上的PB0和PB1引脚,以实现LED灯的亮灭。在固件库方法中,涉及了时钟使能、GPIO初始化和引脚赋值;而在寄存器方法中,直接对RCC和GPIO的相关寄存器进行操作来完成相同功能。
摘要由CSDN通过智能技术生成

板子使用的是洋桃电子的开发板,核心板上面的两个led灯连接的是PB0和PB1两个引脚,如下图所示
在这里插入图片描述
可以看到这个电路图,如果将PB0的引脚的信号设置为高电平,则电流会从LED灯的左边流向右边,即点亮LED灯。
对stm32的操作有两种方法,一种是使用固件库函数,另一种是直接使用寄存器的方法。使PB0引脚变成高电平的方法

一、使用固件库函数

1、使能时钟

在这里插入图片描述
从上图的STM32的结构图可以看出,GPIOB是在APB2上面的外设,所以使能时钟应该选择APB2。
在固件库中的stm32f10x_rcc.c文件中有库函数void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    RCC->APB2ENR |= RCC_APB2Periph;
  }
  else
  {
    RCC->APB2ENR &= ~RCC_APB2Periph;
  }
}```
函数的第一个参数RCC_APB2Periph是一个32位的无符号整型数据,用来指定需要激活的哪一个时钟线对对应的外设,我们此处需要激活的是APB2的外设。在这个文件中也给我们指出了对应参数的选择。

```c
/**
  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.
  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
  *   This parameter can be any combination of the following values:
  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     
  * @param  NewState: new state of the specified peripheral clock.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */

即这里的第一个参数我们选择RCC_APB2Periph_GPIOB,因为我们的GPIO是在选择的GPIOB,另一个参数选择ENABLE即可。即调用函数即可使能对应的外设的时钟。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE)

至此,时钟设置就结束了。

2、选择引脚

此处选择的引脚是PB0和PB1,在选择引脚的时候需要设置三个参数,一是我们选择的是哪一个引脚,这里选择的PB0和PB1,二是需要设置一个速度,三是设置一个输出或者输入方式,一般led灯对应的是输出,按键对应的是输入。
在stm32f10x_gpio.h中官方给我们定义了一个名为GPIO_InitTypeDef结构体用来设置引脚,结构体具体内容如下

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

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;**

里面有三个成员,对应上面所述的三个参数的设置。其类型选择如下

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

所以设置引脚就可以先定义结构体GPIO_InitTypeDef对引脚进行设置,具体代码如下:

GPIO_InitTypeDef InitStrcuture;//定义一个结构体以便为其成员赋值
	InitStrcuture.GPIO_Pin = GPIO_LED_PIN_0 | GPIO_LED_PIN_1;
	InitStrcuture.GPIO_Speed = GPIO_Speed_10MHz;
	InitStrcuture.GPIO_Mode = GPIO_Mode_Out_PP;

这样就完成了对PB0和PB1引脚的设置,当然设置完成之后需要将该设置的引脚进行初始化操作,这里利用stm32f10x_gpio.c文件的函数GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
可以看到该函数第一个参数这里应该选择GPIOB,而第二个参数就是之前定义的结构体

GPIO_Init(GPIOB, &InitStrcuture);

至此,就将对应的引脚设置完成。

3、对引脚赋值

接下来就可以对该引脚的电平进行操作了,这里使用固件库函数

GPIO_SetBits(GPIOB,GPIO_Pin_0);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);

这样就可以使得PB0为高电平,PB1为低电平,从而使得led1亮,led2灭。
其完整代码如下

#include "stm32f10x.h"

int main(void)
{
	GPIO_InitTypeDef InitStrcuture;//定义一个结构体以便为其成员赋值
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//打开对应外设的时钟
	InitStrcuture.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;
	InitStrcuture.GPIO_Speed = GPIO_Speed_10MHz;
	InitStrcuture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &InitStrcuture);
	while(1)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_0);
		GPIO_ResetBits(GPIOB,GPIO_Pin_1);
	}
}

二、使用寄存器

使用寄存器操作引脚,步骤与固件库函数的是极为类似的,唯一不同的是需要自己根据STM32参考手册去寻找相应外设或引脚的地址。个人觉得固件库的方法更为简单,但寄存器的学习也是必不可少的内容,下面用寄存器的方法点亮led灯。
这里同样是三部曲,一使能对应的时钟,二是配置IO口,三是对引脚赋值。

1、使能时钟

首先找到RCC时钟的地址,从下图可以看到RCC的基地址为0x40021000
在这里插入图片描述
使能时钟是通过APB2外设时钟使能寄存器(RCC_APB2ENR)来进行操作的。
在这里插入图片描述
可以从上图看到,该寄存器的偏移地址为0x18,如果在该地址的第4位填写1的话,则APB2上的GPIOB外设的时钟将被激活。

*(unsigned int*)0x40021018 = 0x8;

这样GPIO外设时钟就被激活了。

2、配置IO口

从参考手册中的寄存器映像中可以找到APB2所对应的地址范围,在这个范围中又可以找到GPIOB所对应的地址范围,可以看到这个基地址为0x40010C00
在这里插入图片描述
这里配置IO口的寄存器名为端口配置低寄存器(GPIOx_CRL) ,0-7为低寄存器,8-15为高寄存器。
在这里插入图片描述
可以看到只要将该地址的值配置好就可以设置相应的模式了。

*(unsigned int*)0x40010C00 = 0x11;

3、引脚赋值

引脚赋值使用的寄存器为端口输出数据寄存器(GPIOx_ODR)
在这里插入图片描述

*(unsigned int*)0x40010C0C |= 0x3

至此使得两个led灯亮。完整代码如下

#include "stm32f10x.h"

int main(void)
{
	*(unsigned int*)0x40021018 = 0x8;
	*(unsigned int*)0x40010C00 = 0x11;
	*(unsigned int*)0x40010C0C = 0x3;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值