打印
[其他ST产品]

基于hal库,GPIO的主要内容。

[复制链接]
236|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GPIO, IO, gp, pi
前言:
因学业繁忙,停更了许久,暑假来袭,也有些空余时间,想在这更新下。这里我想了下,下面只介绍四节内容。其实这一块已经学完好久了,只是没有时间去更新。

1、GPIO

2、串口

3、定时器

4、ADC DAC

我认为这四个内容比较重要。

电赛实验室培训用到的第一个外设就是GPIO,当然这也是最简单的一个外设了,学习的话,当然要从容易的开始学习啦。在学习之前,我们还是先看一看这块板子吧,这介绍了很多外设。这里我拿的是正点原子的板子举例的,自己本身用的不是这块板子。(都是STM32F407)



这期呢,我会介绍如何利用按键点亮一个led灯,这里用到的就是引脚的I/O口,点灯大师就是我。

使用特权

评论回复
沙发
梵蒂冈是神uy|  楼主 | 2023-12-27 14:42 | 只看该作者
一、GPIO的原理
介绍:
GPIO是通用输入输出端口的简称,简单来说就是stm32可控制的引脚。

每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、 GPIOx_OSPEEDR 和 GPIOx_PUPDR)、2 个 32 位数据寄存器(GPIOx_IDR 和 GPIOx_ODR)、1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、1 个 32 位锁定寄存器 (GPIOx_LCKR) 和 2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)

使用特权

评论回复
板凳
梵蒂冈是神uy|  楼主 | 2023-12-27 14:42 | 只看该作者
功能:
STM32 提供了大量的 GPIO 引脚,可用于与其他外部设备进行数字信号通信。这些引脚可配置为输入或输出,并具有中断功能。

使用特权

评论回复
地板
梵蒂冈是神uy|  楼主 | 2023-12-27 14:43 | 只看该作者
功能:
STM32 提供了大量的 GPIO 引脚,可用于与其他外部设备进行数字信号通信。这些引脚可配置为输入或输出,并具有中断功能。

使用特权

评论回复
5
梵蒂冈是神uy|  楼主 | 2023-12-27 14:43 | 只看该作者
二、基本外设介绍即代码
我觉得单片机最基本的外设就是按键和LED灯,所以这里就介绍一下这块的代码。
LED
首先介绍LED,我们学习一块单片机首先要看原理,熟悉它的引脚与外设的基本对应关系,在使用cubemx的时候也就十分方便。

使用特权

评论回复
6
梵蒂冈是神uy|  楼主 | 2023-12-27 14:43 | 只看该作者
     我们看到LED0和LED1,引脚对应是PF9和PF10,发光二极管具有单向导通性,左边为高电平,所以只用当PF9和PF10为低电平时,发光二极管才能被点亮,反之,则会熄灭。这里也讲一下简单的cubemx的配置

使用特权

评论回复
7
梵蒂冈是神uy|  楼主 | 2023-12-27 14:43 | 只看该作者
将我们芯片的PF9和PF10设置为输出模式即GPIO_Output,这里的LED相当于外设,输出外设。

使用特权

评论回复
8
梵蒂冈是神uy|  楼主 | 2023-12-27 14:44 | 只看该作者
把我们的GPIO输出电平改为高电平,初始状态灯灭,选择我的的推挽输出。

开漏模式:输出 0 时,N-MOS 导通,P-MOS 不被激活,输出0。

              输出 1 时,N-MOS 高阻, P-MOS 不被激活,输出1(需要外部上拉电路);此模式可以把端口作为双向IO使用。

使用特权

评论回复
9
梵蒂冈是神uy|  楼主 | 2023-12-27 14:44 | 只看该作者
   推挽模式:输出 0 时,N-MOS 导通,P-MOS 高阻,输出0。

              输出 1 时,N-MOS 高阻,P-MOS 导通,输出1(不需要外部上拉电路)。

既不上拉也不下拉,输出速度低速就够了,然后可以将我们的引脚名字改为LED0和LED1,其他配置与我之前所发第一篇大致相同。这里就可以生成keil文件了。


使用特权

评论回复
10
梵蒂冈是神uy|  楼主 | 2023-12-27 14:44 | 只看该作者

使用特权

评论回复
11
梵蒂冈是神uy|  楼主 | 2023-12-27 14:44 | 只看该作者
在while内写入这段代码,执行起来的效果就是每隔1s两个灯闪烁一次。
 /* USER CODE BEGIN WHILE */
  while (1)
  {
                HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);//灯亮
                //HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET);//上方是因为命名过后,也可以这么写.
                HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
                HAL_Delay(500);
                HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);//灯灭
                HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
                HAL_Delay(500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }


使用特权

评论回复
12
梵蒂冈是神uy|  楼主 | 2023-12-27 14:44 | 只看该作者
高低电平

按键
接下来介绍单片机的按键,按键属于输入外设,首先看引脚图,按键按下PE3就接低电平,读取引脚的电平,当读取到低电平表明按键被按下。如果没 被按下,PE3就接高电平。

使用特权

评论回复
13
梵蒂冈是神uy|  楼主 | 2023-12-27 14:45 | 只看该作者
接下来就是配置,PE3选择输入模式

使用特权

评论回复
14
梵蒂冈是神uy|  楼主 | 2023-12-27 14:45 | 只看该作者
选择上拉模式,更名为KEY1,然后就可以形成keil文件了。这里我也看到一篇关于介绍GPIO输入输出模式的博客,供大家参考

使用特权

评论回复
15
梵蒂冈是神uy|  楼主 | 2023-12-27 14:45 | 只看该作者


这里按键会存在抖动,这里不做介绍了,网上也有很多博客讲关于软件消抖。

使用特权

评论回复
16
梵蒂冈是神uy|  楼主 | 2023-12-27 14:45 | 只看该作者
/* USER CODE BEGIN WHILE */
  while (1)
  {
                if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
                {
                        HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);//灯亮
                }
                else
                {
                        HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
                }

使用特权

评论回复
17
梵蒂冈是神uy|  楼主 | 2023-12-27 14:45 | 只看该作者
按键1按下灯0亮,松开灯灭。

使用特权

评论回复
18
梵蒂冈是神uy|  楼主 | 2023-12-27 14:46 | 只看该作者
矩阵键盘
这里还介绍一个4*4的矩阵键盘的代码,可能有些问题,只提供一个思路
uint8_t keypad_read(void)
{
          uint8_t row, col;
    const uint8_t row_pins[4] = {ROW1_Pin, ROW2_Pin, ROW3_Pin, ROW4_Pin};
    const uint8_t col_pins[4] = {COL1_Pin, COL2_Pin, COL3_Pin, COL4_Pin};
    const uint8_t keymap[4][4] = {
        {'1', '2', '3', 'A'},
        {'4', '5', '6', 'B'},
        {'7', '8', '9', 'C'},
        {'*', '0', '#', 'D'}
    };
    for (row = 0; row < 4; row++)
                {
        // 设置当前行为低电平
        HAL_GPIO_WritePin(GPIOB, row_pins[row], GPIO_PIN_RESET);

        for (col = 0; col < 4; col++)
                        {
            // 检查列引脚是否为低电平
                                HAL_Delay(20);
            if (HAL_GPIO_ReadPin(GPIOB, col_pins[col]) == GPIO_PIN_RESET)
                                                {
                // 按键被按下,返回对应的键值
                return keymap[row][col];
            }
        }

        // 设置当前行回高电平
        HAL_GPIO_WritePin(GPIOB, row_pins[row], GPIO_PIN_SET);
    }

    return 0; // 未检测到按键
}

GPIO这就讲到这里,欢迎各位大佬指正错误,谢谢大家。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

47

主题

680

帖子

1

粉丝