[蓝桥杯嵌入式有手就行]4_GPIO(上)

[蓝桥杯嵌入式有手就行]系列文章

第一章 开发环境的配置
第二章 从点灯开始
第三章 学会看手册
第四章 GPIO(上)
第五章 GPIO(下)
第六章 LCD
第七章 串口
第八章 I2C
第九章 ADC
第十章 TIM(上)
第十一章 TIM(下)
第十二章 RTC
第十三章 14届模拟题1
第十四章 14届模拟题2
第十五章 14届真题解析
未完待续…



前言

注:本系列基于2023年蓝桥杯实战情况就行编写,所有软件均采用2023年赛点资源包
本文将讲解GPIO输出(不含复用)部分。在板子上的体现,就是LED。

ps:前几期的视频已经剪好了,但是垃圾电脑,导出到一半嘎了,大家多多点赞,让我早日换个电脑。


一、内部结构

下图在参考手册9.3节。本文主讲输出,所以我们只看下面一个虚线框,以及右侧I/O引脚。
在这里插入图片描述

1、Output driver(下方的虚线框)

这里我们不难发现,这里主要结构是两个mos管。P-MOS和N-MOS组成了一个反相器驱动输出,通过改变两个mos管的状态,我们就可以构成推挽、开漏、禁止三种状态。

1、开漏和推挽的区别

开漏输出:==P-MOS不工作,具有“线与"功能(见第四节、问题)==外部上拉电阻的大小决定了逻辑电平转换的速度,阻值越小,延时越小,功耗越高,反之,亦然。当延时有要求时,使用下降沿输出

输入状态
0N-MOS导通,接地
1N-MOS关闭,高阻态
优点缺点
硬件实现线与功能对高电平没有驱动能力

推挽输出:推挽输出时,引脚高低电平切换时,P-MOS和N-MOS轮流导通,P-MOS负责灌电流,N-MOS负责拉电流。

优点缺点
负载能力强,速度快存在短路风险

2、开漏输出状态

在这里插入图片描述
我们不难看出,在虚线框中,只有一个N-MOS管工作,只能拉低电平,也就是只能漏。
蓝桥杯比赛中,只有I2C需要配置为开漏输出,其他全部为推挽输出。

3、推挽输出状态

在这里插入图片描述
推挽输出过程中,两个管子轮流工作,这样电平变化更快,但是mos管开关速度也不是无限快的,当时间足够短的时候,就会出现两个mos管同时导通,此时电源短路,导致芯片损坏。当然,只要你不瞎搞(stm32似乎可以超频50%以上),一般都不会坏。

2、I/O引脚(两个虚线框右侧)

在这里插入图片描述
我们可以看到,这里有2个电阻,2个二极管。两个电阻是用于输入的,这里跳过。这里两个保护二极管,顾名思义,就是保护后面的芯片内部电路。设置为输出时,与这里无关。

3、寄存器分析

这里见参考手册9.4节(一共有11个寄存器)

名称功能
GPIOx_MODERGPIO端口模式寄存器
GPIOx_OTYPERGPIO端口输出类型寄存器
GPIOx_OSPEEDRGPIO端口输出速度寄存器
GPIOx_PUPDRGPIO端口上下拉寄存器
GPIOx_IDRGPIO端口输入数据寄存器
GPIOx_ODRGPIO端口输出数据寄存器
GPIOx_BSRRGPIO端口置/复位寄存器
GPIOx_LCKRGPIO端口配置锁定寄存器
GPIOx_AFRLGPIO复用功能低位寄存器
GPIOx_AFRHGPIO复用功能高位寄存器
GPIOx_BRRGPIO位复位寄存器

二、LED模块的原理分析

1、原理图

在这里插入图片描述
通过原理图,我们可以发现,LED灯的左侧通过一个电阻接到了VDD,右侧连接到了SN74HC573,然后连接到了PC8-15引脚。那么,如果我们想让LED灯亮,就需要在右侧输出一个低电平,这样电路才会导通。

2、SN74HC573

那么,这是一个什么元件呢。资料包中给出了其手册,我们不难发现,这是一个锁存器。
那么怎么使用,很简单,在手册的第一页中就告诉你了。

The 74HC573; 74HCT573 has octal D-type transparent latches featuring separate D-type inputs for each latch and 3-state true outputs for bus oriented applications. A latch enable (LE) input and an output enable (OE) input are common to all latches.
When LE is HIGH, data at the Dn inputs enter the latches. In this condition the latches are transparent, i.e. a latch output will change state each time its corresponding D input changes.
When LE is LOW the latches store the information that was present at the D-inputs a set-up time preceding the HIGH-to-LOW transition of LE. When OE is LOW, the contents of the 8 latches are available at the outputs. When OE is HIGH, the outputs go to the high-impedance OFF-state. Operation of the OE input does not affect the state of the latches.

通过原理图可以看到,OE脚已经接地了,那么我们只需要给LE脚一个高电平,那么右侧的电平信号就可以透过锁存器来到左边的LED引脚。接着给LE引脚一个低电平,那么信号将被锁住,不受右侧输入的影响。

三、软件部分

1、cubemx配置

1、RCC配置

这里同第二节的内容,时钟频率能够配置就可以。

2、GPIO配置

我们需要将PD2和PC8-15引脚设置为GPIO_Output,其余配置保持默认即可。
在这里插入图片描述

3、生成工程

注意点和第二节也是一样的,没有中文就可以了。

2、代码编写

这里务必确保锁存器有足够多的时间锁住信号,一般中间夹一行代码就可以了。PD2的高低电平操作挨着的情况下,可能会出现LED显示异常。

1、最简单的

viod LED_Disp(unsigned char ucled)
{
	//熄灭所有的灯
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
	//点亮PC8对应的LED1
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
}

2、移位法

这里的GPIO_PIN的是16位的,因此左移12位,也就能够控制最后4个LED等。请从寄存器的角度去理解。
当然,你也可以左移8位,这样就可以控制8个LED灯了。

viod LED_Disp(unsigned char ucled)
{
	//熄灭所有的灯
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
	//根据ucled(1,2,4,8)的值点亮LED(LD8,LD7,LD6,LD5)
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,ucled<<12,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
}

3、翻转电平法

viod LED_Toggle()
{
	//这里翻转了PC8的电平
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
}

4、直接操作寄存器

这里实现的功能和移位法是一样的,至于ODR寄存器的内容请参看手册。(还不会看手册的给我看上一篇文章去)
实际上我们使用BSRR寄存器在后期编程的时候会更加简单,因为它一个寄存器就可以置位和复位一个GPIO16个引脚的电平,我们只需要传入一个32位的数据。

viod LED_Disp(unsigned char ucled)
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	GPIOC->ODR|=ucled<<12;
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_All,GPIO_PIN_RESET);
}

四、问题

1、什么是“线与”

“线与”特性就是将多个开漏模式的引脚连接至同一条信号线,只有全部为高阻态时,才由上拉电阻提供高电平。
这里可以简单理解,泳池不停注水,有许多大洞(就是我们的开漏输出,只能漏,不能灌),只有全部堵上,水面才会上升。
这种特性,一般有两个使用场景:
1、需要进行电平转换时。芯片的输出只有3.3V,而开漏输出的高电平是外部上拉提供的,因此可以实现5V供电。
2、特殊通信协议。比如I2C通信时,信号线上不允许有多个器件同时发送信号。相当于只要有一个洞没堵住,泳池里就没有水。而其他器件看到没有水,就不会去拔下堵洞的塞子。

2、寄存器看不懂

没有关系,我们直接使用hal库进行编程就可以,LED灯在代码量上和操作寄存器没有太大的差距。但是寄存器是最直观的。

总结

本节讲述了GPIO输出部分,下一节我们将分析GPIO的输入部分。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工具人呵呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值