【STM32】HAL库的本质 及 芯片内部GPIO模块细节

【STM32】HAL库的本质 及 芯片内部GPIO模块细节

文章目录

  • [【STM32】HAL库的本质 及 芯片内部GPIO模块细节](#【STM32】HAL库的本质 及 芯片内部GPIO模块细节)
    • 一、芯片摆放与引脚编号识别
    • [二、片上系统-SOC_(System On Chip)](#二、片上系统-SOC_(System On Chip))
      • [2.1 HAL库的本质](#2.1 HAL库的本质)
        • [2.1.1 HAL库实现点灯](#2.1.1 HAL库实现点灯)
        • [2.1.2 操作寄存器](#2.1.2 操作寄存器)
      • [2.2 `GPIO`模块](#2.2 GPIO模块)
        • [2.2.1 `GPIO`的常见用法](#2.2.1 GPIO的常见用法)
        • 2.2.2`GPIO`的工作模式
          • [2.2.2.1 输入模式(上半张图)](#2.2.2.1 输入模式(上半张图))
          • [2.2.2.2 施密特触发器_0和1的问题](#2.2.2.2 施密特触发器_0和1的问题)
          • [2.2.2.3 输出模式(下半张图)](#2.2.2.3 输出模式(下半张图))
          • [2.2.2.4 开漏输出是双向通信的示例(类`I2C`硬件原理)](#2.2.2.4 开漏输出是双向通信的示例(类I2C硬件原理))
          • [2.2.2.3 输出模式(下半张图 复用)](#2.2.2.3 输出模式(下半张图 复用))
          • [2.2.2.5 操作GPIO](#2.2.2.5 操作GPIO)
        • [2.2.3 `GPIO_HAL`库源码解析](#2.2.3 GPIO_HAL库源码解析)
    • **从底层本质来看,HAL库归根结底就是在操作寄存器**。**它是一个硬件抽象层,让你不用直接面对寄存器。**

一、芯片摆放与引脚编号识别

  • 圆圈放在左上角
  • 逆时针数引脚编号

二、片上系统-SOC_(System On Chip)

HAL库的本质就是读写寄存器;

HAL库的本质,就是帮我们去操作这些寄存器,我们就不用那么幸苦的去查看芯片手册,确认一下它的基地址,确认一下它的偏移地址,还得去确认一下里面每一位的含义,方便了很多。

工作中,建议大家使用厂家提供的库函数,不要自己去写基于寄存器的那些函数,基于寄存器的那些操作。

2.1 HAL库的本质

  • 组装PC机需要 CPU、内存条、硬盘 ==> 放在主板上
  • 对于单片机的芯片内部呢?
    • 集成CPU
    • 集成 RAM(内存条)
    • 集成 Flash(硬盘)
    • 集成USB控制器
    • GPIO:General-purpose I/O(通用目的的输入输出引脚)
  • SOC简易图
简易SOC示意图_GPIO配置 简易SOC示意图_地址访问GPIO寄存器

在SOC中,

  • 在CPU眼里,我可以直接访问到内存、GPIO、Flash;

  • CPU使用某些地址的时候,根据不同的地址来访问不同的设备。ABCDEF均是地址,在芯片手册中的内存映射(Memory map)中可以找到。

  • CPU可以去读写内存,或者GPIOC,读写GPIOC里面的寄存器

    • 我们为什么称为寄存器?
      • RAM(内存条):写入val ,读出仍是val;(暂存)
      • Flash(硬盘):读出指令,不可以直接写,写之前需要擦除;(长期保存)
2.1.1 HAL库实现点灯
  • 我们从最简单的操作说起,看看用HAL库点灯和操作寄存器电灯,有什么区别,看看HAL库到底在干什么。
操作LED灯的步骤
1、使能GPIO模块
2、选择Pin2的功能,连接到GPIO模块
3、配置GPIO模块,让引脚作为输出引脚
4、配置GPIO模块,让引脚输出 高/低 电平

前三个步骤可以用cubeMX生成,第四步一般看HAL库手册,找到对应函数,进行调用就行,或者直接在程序中找到对应函数;

对于CubeMX,它省去了我们繁琐的硬件初始化的代码,我们只要专注于应用程序的开发就可以了。

c 复制代码
//HAL库实现电灯程序
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	while(1)
	{
		/*set PC13 output high*/
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
		HAL_Delay(500);
		/*set PC13 output low*/
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
		HAL_Delay(500);
	}
  /* USER CODE END 2 */
}

我们只要专注于应用程序的开发就可以了,正在要我们写的只有几个HAL库 函数调用而已,这些函数在芯片手册上面都有详细的解释。

c 复制代码
/*set PC13 output high*/
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(500);
/*set PC13 output low*/
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(500);
2.1.2 操作寄存器
GPIOC寄存器类型 GPIOC寄存器

在GPIOC中

  • 里面有很多寄存器,功能各不相同

  • 根据memory map 可知,基地址为0x4001 1000,要读写第13位寄存器,就要对地址 0x4001 100C 进行操作。

C 复制代码
//操作寄存器实现点灯程序
int main(void)
{
  /* USER CODE BEGIN 1 */
	//unsigned int a;
	unsigned int *p;
		
	//p = &a;  
	p = (unsigned int *)0x4001100c;
	
	//*p = val;  // a = val 
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	while(1)
	{
		/*set PC13 output high*/
		//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
		unsigned val = *p;
		val = val | (1<<13);
		*p = val;
		
		HAL_Delay(500);
		
		/*set PC13 output low*/
		//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
		val = *p;
		val = val & ~(1<<13);
		*p = val;
		
		HAL_Delay(500);
	}
  /* USER CODE END 2 */
}

我们真正要做的

c 复制代码
	unsigned int *p;
	//p = &a;  
	p = (unsigned int *)0x4001100c;

	while(1)
	{
		/*set PC13 output high*/
		//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
		unsigned val = *p;		// read
		val = val | (1<<13);	
		*p = val;				// 写回去	

		HAL_Delay(500);
		
		/*set PC13 output low*/
		//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
		val = *p;				// read
		val = val & ~(1<<13);	// 修改
		*p = val;				// 写回去	
	
		HAL_Delay(500);
	}

2.2 GPIO模块

General-purpose( 常规用途)和alternate-function(多用途)I/Os ==> (GPIO and AFIOS)

2.2.1 GPIO的常见用法
  • 使能GPIO
  • 选择PIN功能
  • 选择方向
  • 设置输出值 / 读取引脚值
2.2.2GPIO的工作模式
对于某个GPIO引脚
2.2.2.1 输入模式(上半张图)
  • 输入模式有四种:上拉输入、下拉输入、浮空输入、模拟输入(走模拟信号的分支);
使能 上拉 电阻 使能 下拉 电阻
浮空输入 模拟输入
  • TTL Schmitt trigger:施密特触发器(输入信号抗干扰神器,起到稳定输入信号的作用) ==> 输出 0/1;如何判断是 1 还是 0 呢?

    2.2.2.2 施密特触发器_0和1的问题
施密特触发器(TTL Schmitt trigger)的用途
2.2.2.3 输出模式(下半张图)
  • 输出模式也有四种:推挽输出、开漏输出、复用推挽输出、复用开漏输出;
推挽输出(push pull)
  • 引入开漏输出 (两个IC通信)
存在的问题:两个IC通信的情况
IC1输出1,IC2输出0
开漏输出(open drain)(复杂一点)
  • 开漏输出,就是开漏连接,高电平为高阻抗,低电平就是拉低电平

VDD:供电正电压;VSS:公共地 GND

场效应管 P-MOS & N-MOS

2.2.2.4 开漏输出是双向通信的示例(类I2C硬件原理)
  • 双向通信

    • IC1想发 Data:

      • 输出1:意思是,我不驱动P-MOS,这引脚 I/O pin 我不管了,电平由外部电路决定 (由外部的上拉电阻决定,由外部的芯片决定)

      • IC1读引脚:V==0 = => IC2 驱动pin,占用

        V==1 = = >IC2未驱动,可用 ==> 下一步

      • IC1 驱动 Data 为 0 ==> 目的是起通知作用:通知对方说,我占用了这个引脚,我要给你发数据了

2.2.2.3 输出模式(下半张图 复用)
复用推挽&开漏输出
2.2.2.5 操作GPIO
操作GPIO 寄存器
  • 设置方向:输入、输出

  • 设置模式

    • 输入:上拉、下拉
    • 输出:推挽、开漏

    设置速率:跳变速度,若快,对外部电磁干扰比较大;(小毛刺幅度更大)

  • 读写

    • 输入:Read val;

    • 输出:数据寄存器写值:(先读,再改,再写)

      ​ bit set/reset 寄存器,操作寄存器一次就行,直接写

2.2.3 GPIO_HAL库源码解析
GPIO_HALGPIO 初始化

从底层本质来看,HAL库归根结底就是在操作寄存器它是一个硬件抽象层,让你不用直接面对寄存器。


本文仅为个人学习总结,若有不对之处,敬请批评指正。期待与大家一起讨论、共同进步。

相关推荐
kebidaixu1 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
CSDN官方博客1 小时前
「谁说嵌入式只是调包和焊板子?」—— 2026嵌入式全栈技术征锋令
嵌入式硬件·物联网·embedding
半条-咸鱼1 小时前
【INACCESSIBLE_BOOT_DEVICE】安装 Config Tool 后 Windows 蓝屏,最终通过 VMware 虚拟机解决
windows·stm32·vmware·芯片
点灯小铭2 小时前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
云栖梦泽2 小时前
玩转RK3506SDK
linux·嵌入式硬件
数智工坊4 小时前
机器人四大主控板系统分层选型指南:树莓派、ESP32、STM32与Arduino的能力边界与实战定位
stm32·嵌入式硬件·机器人
某林2124 小时前
跨越底层与AI的鸿沟:ROS2+多模态大模型(Qwen-VL)机器人全链路排障实录
人工智能·stm32·机器人·人机交互·ros2·技术复盘
进击的小头5 小时前
第8篇:IGBT 从零到精通:核心原理、关键参数、选型指南与工业级应用要点
经验分享·嵌入式硬件·学习
点灯小铭5 小时前
基于单片机的多模式智能洗衣机设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
项目題供诗5 小时前
STM32-AD单通道&AD多通道(十九)
stm32·单片机·嵌入式硬件