stm32F1GPIO实验

GPIO简介

GPIO是通用输入输出端口,IO端口里面拥有寄存器控制IO端口的输入输出工作。

GPIO驱动步骤

  1. 使能时钟 _HAL_RCC_GPIOx_CLK_ENABLE():x表A,B,C,D…F1:RCC_APB2ENR()
  2. 设置工作模式 :HAL_GPIO_Init():操作寄存器,F1:CRL、CRH、ODR
  3. 设置输出状态:HAL_GPIO_WritePin() ,HAL_GPIO_TogglePin(),操作寄存器BSRR,通过操作BSRR寄存器操作ODR寄存器。
  4. 读取输入状态:HAL_GPIO_ReadPin(),操作寄存器IDR
typedef struct 
{ 
  uint32_t Pin;        /* 引脚号 */ 
  uint32_t Mode;       /* 模式设置 */ 
  uint32_t Pull;       /* 上拉下拉设置 */ 
  uint32_t Speed;      /* 速度设置 */ 
} GPIO_InitTypeDef;

HAL_GPIO_Init()函数

HAL_GPIO_Init()函数,在stm32f1xx_gpio.c中。

//GPIOx中的x表示A,B,C,D,E,F,G;
void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init){}
//GPIO_TypeDef是IO所有寄存器得到结构体
typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef//定义在stm32f103xe.h
//GPIOB的定义在stm32f103xe.h中,他表示外设的基地址强制转化为结构体GPIO_TypeDef。这个就可以以结构体的方式操作。寄存器地址。
//#define GPIOB       ((GPIO_TypeDef *)GPIOB_BASE)
//define GPIOA_BASE    (APB2PERIPH_BASE + 0x00000800UL)

//此结构体在stm32f1xx_hal_gpio.h中。
typedef struct 
{ 
  uint32_t Pin;        /* 引脚号 */ 
  uint32_t Mode;       /* 模式设置 */ 
  uint32_t Pull;       /* 上拉下拉设置 */ 
  uint32_t Speed;      /* 速度设置 */ 
} GPIO_InitTypeDef;

HAL_GPIO_WritePin()

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)//GPIO_PIN_RESET±íʾ0£¬¸´Î»
  {
		//BSSR是32位寄存器,低16位位设置端口x的位y(y=0...15)
       GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
      GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
  }
}

BSRR寄存器介绍
在这里插入图片描述

HAL_GPIO_ReadPin()

是操作寄存器IDR

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  GPIO_PinState bitstatus;

  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
  {
    bitstatus = GPIO_PIN_SET;
  }
  else
  {
    bitstatus = GPIO_PIN_RESET;
  }
  return bitstatus;
}

#编程实战1 点亮一个LED灯

LED灯引脚
在这里插入图片描述
main.c

int main(void)
{
    HAL_Init();                         /*初始化Hal库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    led_init();                         /* LED初始化 */
    while(1)
    { 
//        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);    /* PB5ÖÃ1 */ 
//        delay_ms(200);
//        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);  /* PB5ÖÃ0 */
//        delay_ms(200);
        
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
        delay_ms(200);
    }
}

led.h


/******************************************************************************************/
#define LED0_GPIO_PORT                  GPIOB
#define LED0_GPIO_PIN                   GPIO_PIN_5
#define LED0_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)             

#define LED1_GPIO_PORT                  GPIOE
#define LED1_GPIO_PIN                   GPIO_PIN_5
#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)             

#define LED0(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)      /* LED0·­×ª */

#define LED1(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)      /* LED1·­×ª */

/*  */
#define LED0_TOGGLE()   do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0)        /* ·­×ªLED0 */
#define LED1_TOGGLE()   do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)        /* ·­×ªLED1 */

/******************************************************************************************/
/* */
void led_init(void);                                                                            /*  */

#endif

led_Init();在led.c中。

void led_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    __HAL_RCC_GPIOB_CLK_ENABLE();    
    gpio_init_struct.Pin = GPIO_PIN_5;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
}

使用寄存器方式
led.c

void led_init(void)
{
    LED0_GPIO_CLK_ENABLE(); /* LED0ʱÖÓʹÄÜ */
    LED1_GPIO_CLK_ENABLE(); /* LED1ʱÖÓʹÄÜ */

    sys_gpio_set(LED0_GPIO_PORT, LED0_GPIO_PIN,SYS_GPIO_MODE_OUT, SYS_GPIO_OTYPE_PP, SYS_GPIO_SPEED_MID, SYS_GPIO_PUPD_PU);   /* LED0Òý½ÅģʽÉèÖà */

    sys_gpio_set(LED1_GPIO_PORT, LED1_GPIO_PIN,SYS_GPIO_MODE_OUT, SYS_GPIO_OTYPE_PP, SYS_GPIO_SPEED_MID, SYS_GPIO_PUPD_PU);   /* LED1Òý½ÅģʽÉèÖà */

    LED0(1);    /* ¹Ø±Õ LED0 */
    LED1(1);    /* ¹Ø±Õ LED1 */
}

led.h


#ifndef __LED_H
#define __LED_H

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* Òý½Å ¶¨Òå */

#define LED0_GPIO_PORT                  GPIOB
#define LED0_GPIO_PIN                   SYS_GPIO_PIN5
#define LED0_GPIO_CLK_ENABLE()          do{ RCC->APB2ENR |= 1 << 3; }while(0)   /* PB¿ÚʱÖÓʹÄÜ */

#define LED1_GPIO_PORT                  GPIOE
#define LED1_GPIO_PIN                   SYS_GPIO_PIN5
#define LED1_GPIO_CLK_ENABLE()          do{ RCC->APB2ENR |= 1 << 6; }while(0)   /* PE¿ÚʱÖÓʹÄÜ 91Ò³Óвο¼¡£*/

/******************************************************************************************/



/* LED¶Ë¿Ú¶¨Òå */
#define LED0(x)         sys_gpio_pin_set(LED0_GPIO_PORT, LED0_GPIO_PIN, x)      /* LED0 */
#define LED1(x)         sys_gpio_pin_set(LED1_GPIO_PORT, LED1_GPIO_PIN, x)      /* LED1 */

/* LEDÈ¡·´¶¨Òå¡£ÕâÀïûÓп´Ì«¶®¡£ */
#define LED0_TOGGLE()   do{ LED0_GPIO_PORT->ODR ^= LED0_GPIO_PIN; }while(0)      /* LED0 = !LED0 */
#define LED1_TOGGLE()   do{ LED1_GPIO_PORT->ODR ^= LED1_GPIO_PIN; }while(0)      /* LED1 = !LED1 */

void led_init(void);    /* ³õʼ»¯ */

#endif
### STM32F1 GPIO 使用教程 #### 初始化和配置GPIO引脚 为了使STM32F1系列微控制器上的GPIO正常工作,首先需要对其进行初始化设置。这可以通过图形化界面工具STM32CubeMX来完成,也可以手动编写代码实现。 当采用HAL库进行编程时,通常会先定义要操作的具体端口及其模式(输入/输出)。对于输出模式下的引脚来说,还需要指定其初始状态是高电平还是低电平;而对于输入模式,则可以选择上拉、下拉或浮空等不同类型的电阻连接方式[^1]。 ```c // 定义并初始化GPIO结构体变量 __IO uint8_t LED_State = 0; GPIO_InitTypeDef GPIO_InitStruct; // 设置LED所接的PA5为推挽输出, 初始状态关闭 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(GPIOA, &GPIO_InitStruct); ``` 上述代码片段展示了如何利用HAL函数`HAL_GPIO_Init()`对特定管脚执行初始化过程。这里选择了PA5作为目标对象,并将其设定成推挽输出形式,在此之前已经声明了一个名为`GPIO_InitStruct`的对象用于保存参数选项。 #### 实现基本的输入输出功能 一旦完成了必要的硬件抽象层(HAL)初始化之后,就可以轻松地控制外部设备了。下面的例子说明了怎样改变某个数字信号的状态——即打开或者熄灭一个连接到MCU I/O线路上的小灯泡: ```c if (LED_State == 0){ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // 打开LED LED_State = 1; } else { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 关闭LED LED_State = 0; } ``` 这段程序逻辑非常简单明了:如果当前指示器处于未激活状态(`LED_State==0`)就把它置位(点亮),反之则清除它(熄灭)。 除了简单的高低电平切换之外,还可以读取来自其他传感器或者其他电路元件传来的二进制数值。比如检测按钮是否被按下: ```c if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9)==GPIO_PIN_SET){ // 当PB9处电压较高时表示按键未按压 }else{ // PB9接地表示按键已被触发 } ``` 此处假设有一个开关接到PC9上面,那么只要该位置呈现低电平时就意味着用户正在触碰这个部件。 #### 中断配置 为了让处理器能够在第一时间响应某些事件的发生而不必一直轮询查询各个可能的变化情况,可以考虑启用相应的中断服务例程(ISR)。以定时器溢出为例介绍如下方法创建自定义ISR处理流程: ```c void EXTI9_5_IRQHandler(void) { /* USER CODE BEGIN EXTI9_5_IRQn 0 */ /* USER CODE END EXTI9_5_IRQn 0 */ HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == GPIO_PIN_9) { // 处理PB9产生的边沿触发中断请求... } } ``` 在此基础上进一步完善细节部分即可满足实际应用场景的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值