从单片机的启动提及一个单片机到点灯发生了什么下——使用GPIO点一个灯 ...

打印 上一主题 下一主题

主题 857|帖子 857|积分 2571

目录

媒介
HAL库对GPIO的抽象
核心分析:HAL_GPIO_Init
媒介

我们终于到达了熟悉的地方,对GPIO的初始化。经过漫长的铺垫,我们终于历经千辛万苦,来到了这里。关于GPIO的八种模式等更加具体的细节,由于只是点个灯,我们不做所有的分析。
HAL库对GPIO的抽象

HAL库对GPIO的抽象可以说是到了一个顶峰。使能一个GPIO,被化简到了一个非常显然的步骤。


  • 使能对应GPIO所在的Port的时钟
  • 设置GPIO对应的模式——点灯的时候,我们是推挽强力的控制外设
  • 使用HAL_GPIO_Init函数注册到寄存器当中
  • 做一些Post Init工作。好比说,我们明确的要求拉高拉低GPIO。这个,需要根据外设电路来实现
以我板子上外接的PA9作为一个例子把!
  1. static void __open_gpioclk(){
  2.    __HAL_RCC_GPIOF_CLK_ENABLE();
  3. }
  4. CCGPIOInitTypeDef led0_init = {
  5.    .type = {
  6.        .Pin    = GPIO_PIN_9,
  7.        .Mode   = GPIO_MODE_OUTPUT_PP,
  8.        .Speed  = GPIO_SPEED_HIGH,
  9.        .Pull   = GPIO_PULLUP
  10.    },
  11.    .open_clock = __open_gpioclk,
  12.    .post_init  = __post_init,
  13.    .port = GPIOF
  14. };
  15. void configure_ccgpio(
  16.    CCGPIOType* type,  CCGPIOInitTypeDef* initer)
  17. {
  18.    type->port = initer->port;
  19.    type->pinType = initer->type.Pin;
  20.    // oh shit, the open clock is missing inited
  21.    initer->open_clock ? initer->open_clock() : __die();
  22.    HAL_GPIO_Init(type->port, &initer->type);
  23.    if(initer->post_init) initer->post_init(type);
  24. }
复制代码

核心分析:HAL_GPIO_Init

我们只是简单的点个灯,这个函数就可被化简为如下的逻辑
  1. void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
  2. {
  3.  uint32_t position;
  4.  uint32_t ioposition = 0x00U;
  5.  uint32_t iocurrent = 0x00U;
  6.  uint32_t temp = 0x00U;
  7.  /* 检查参数 */
  8.  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
  9.  assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
  10.  assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
  11.  /* 配置GPIO引脚 */
  12.  for(position = 0U; position < GPIO_NUMBER; position++)
  13.   {
  14.    /* 获取IO引脚位置 */
  15.    ioposition = 0x01U << position;
  16.    /* 获取当前IO引脚的状态 */
  17.    iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
  18.     ...
  19.      /* 配置引脚为高电平来点亮LED */
  20.      GPIOx->ODR |= iocurrent; // 设置为高电平
  21.    }
  22.   }
  23. }
复制代码
这就是为什么我们可以使用Pin9 | Pin10完成我们的组操作,因为内部,我们是逐个比特的完成我们对GPIO的设置,对于每一个满意——的确是我们要设置的GPIO
  1.  
复制代码
  1.   if(iocurrent == ioposition)
  2.    {
  3.      /* --------------------- GPIO模式配置 ------------------------*/
  4.      /* 仅当输出模式时才需要配置 */
  5.      if(((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT))
  6.      {
  7.        /* 配置IO速度 */
  8.        assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
  9.        temp = GPIOx->OSPEEDR;
  10.        temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U));
  11.        temp |= (GPIO_Init->Speed << (position * 2U));
  12.        GPIOx->OSPEEDR = temp;
  13.        /* 配置IO输出类型 */
  14.        temp = GPIOx->OTYPER;
  15.        temp &= ~(GPIO_OTYPER_OT_0 << position);
  16.        temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
  17.        GPIOx->OTYPER = temp;
  18.        /* 配置IO输出模式 */
  19.        temp = GPIOx->MODER;
  20.        temp &= ~(GPIO_MODER_MODER0 << (position * 2U));
  21.        temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));
  22.        GPIOx->MODER = temp;
  23.      }
复制代码
也就是说,设置我们的输出范例是下面的:


  • 上拉是指在GPIO引脚与电源(通常是3.3V或5V)之间毗连一个电阻,这样当引脚处于输入状态时,假如没有外部信号驱动该引脚,它会主动被拉到高电平。也就是被高电平拽上去了!


  • 下拉是指在GPIO引脚与地(0V)之间毗连一个电阻,这样当引脚处于输入状态时,假如没有外部信号驱动该引脚,它会主动被拉到低电平。也就是被低电平拽下去了!


  • 无上下拉配置意味着不毗连任何上拉或下拉电阻。当GPIO引脚处于输入模式时,它的电平状态将取决于外部电路。假如没有外部驱动信号,这个引脚将处于浮空状态(Hi-Z),大概会导致电平不稳定,容易受到噪声干扰。
中的一种。至于GPIO的速度,则是分为低速中速高速。我们的输出模式大致分两种:


  • 推挽输出(Push-pull):这种输出范例意味着GPIO引脚可以驱动电流流向负载,并且在输出高电平和低电平时都会主动提供电流。即引脚会主动拉高电平和拉低电平。它是最常用的输出范例。
  • 开漏输出(Open-drain):这种输出范例意味着GPIO引脚只有在输出低电平时才会提供电流(拉低电平),而在输出高电平时,它不会输出电流,而是处于高阻态(Hi-Z)。通常需要外部上拉电阻来将引脚拉到高电平。你会在使用软件IIC的时候,再看到它。
以是,笔者按照给出的这个原理图:配置为上拉的情况,确保初始化后不会立马被点亮。

很好,如今,我们终于来到了点灯!
  1. set_ccgpio_state(&led0, CCGPIO_LOW);
  2. void set_ccgpio_state(CCGPIOType* type, CCGPIOState state)
  3. {
  4.    HAL_GPIO_WritePin(
  5.        type->port, type->pinType,
  6.        (state ? (GPIO_PIN_SET) : (GPIO_PIN_RESET)));
  7. }
复制代码
此时此刻,我们的GPIO就会被拉到低,形成一个高低的电压差,存在的电流就把我们的LED导通了!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农妇山泉一亩田

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表