资讯详情

【STM32】标准库 菜鸟入门教程(3)闪烁及流水灯

GPIO

基本结构-toc" style="margin-left:40px;">GPIO基本结构

GPIO位结构

GPIO模式

设备原理分析

LED

面包板:

蜂鸣器:-toc" style="margin-left:80px;">蜂鸣器:

小文件分享

LED闪烁

源代码百度云地址:

第一步:使用RCC开启GPIO时钟

第二步:使用GPIO_Init函数初始化GPIO

第三步:使用输出或输入函数控制GPIO

流水灯

第一步:使用RCC开启GPIO时钟

第二步:使用GPIO_Init函数初始化GPIO

第三步:使用输出或输入函数控制GPIO


GPIO

全称:(General Purpose Input Output):通用输入输出口,俗称I/O口

可配置为8种输入输出模式 引脚电平:输出0V~3.3V,部分引脚可容忍输入5V(带FT(Five Tolerate))

对于功率较大的设备,需要增加驱动电路

若输入模拟信号,GPIO可编程模拟输入模式,然后与内部配合ADC外设可以读取端口的模拟电压

GPIO基本结构

每一个GPIO外设上有一个寄存器和一个驱动器。寄存器上有16个端口,通过驱动器与16个引脚相连。GPIO外设命名为GPIOX(X=A、B、C...),16个引脚命名的方法是PX0,PX1,PX2...PX15,其中X=A、B、C,根据引脚所在外设。

STM32是32位单片机,所以STM内部寄存器也是32位,但这里只用了低16位,高16位没用。

内核通过APB2.外设总线控制寄存器进行读写操作。当读寄存器中的一个是1时,可以知道相应的引脚是高电平的。当写入寄存器中的一个是1时,就是输出相应的引脚高电平。

所有GPIO都是挂载在APB2外设总线。

驱动器负责提高驱动能力,寄存器只负责存储功能。

GPIO位结构

二级管工作原理的保护:I/O口输入高于3.3V电压时,连接VDD电流从二极管导通I/O口流向VDD,不流入后续电路,起到保护作用;当I/O当口的电压为负电压时,电流从VSS流向I/O不吸收后续电路电路的电流,也起到保护作用。VDD改为VDD_FT,这意味着电源V。

当软件配置时,可以配置上拉电阻和下拉电阻VDD导通VSS断开时,为上拉输入模式,引脚悬挂时为高电平,相反为下拉输入模式,引脚悬挂时为低电平,两者都断开时为浮动输入模式。

模拟输入:一般连接ADC,接收模拟量。

施密特触发器:用于输入电压整形手术,设置阈值上限和阈值下限I/O当口的输入模拟信号超过上限时,施密特触发器输出高电平I/O当口腔输入的模拟信号低于下限时,施密特触发器输出低电平,其余时间保持原电平不变。整形手术后,输入数据存储器进行保存,然后通过程序读取来了解某个电平。

复用功能输入:一般接收其他外设。

位置设置/清除寄存器:寄存器中的数据可以单独操作,无需整体操作&=或者/=,方便快捷。写1是设置或者清除,写0的位保持不变。高16位用于位置清除,低16位用于位置设置。还有一个单独的位置清除寄存器。可以用低16位完成设置和清除,比较方便,但缺点是不能同步。如果你想同步,你只能使用设置/清除寄存器。

P-MOS和N-MOS:两者可控制三种输出模式:推拉输出、开漏输出和关闭。

当设置为推挽输出时,P-MOS和N-MOS当1信号通过输出控制进入时,都是有效的MOS管,在P-MOS在N-MOS此时管道还是1P-MOS管导通,N-MOS断管,输出高电平,反之亦然。

当设置为泄漏输出时,P-MOS当1信号通过输出控制进入时,管道一直断开MOS管,N-MOS当0信号通过输出控制进入时,输出高阻态。MOS管,N-MOS管导通,输出高电平。输入驱动器打开时关闭。可设置泄漏模式,外接5v电源增加电阻,设置输出5v电压。

一个端口只能有一个输入,但可以有多个输出。

GPIO模式

数字输出

模式名称

性质

特征

浮空输入

数字输入

可读取引脚电平。如果引脚悬空,则电平不确定

上拉输入

数字输入

可读取引脚电平,内部连接上拉电阻,悬挂时默认高电平

下拉输入

数字输入

可读取引脚电平,内部连接下拉电阻,悬挂时默认低电平

模拟输入

模拟输入

GPIO无效,引脚直接进入内部ADC

开漏输出

可输出引脚电平,高电平为高阻态,低电平接VSS

推挽输出

数字输出

可输出引脚电平,高电平接VDD,低电平接VSS

复用开漏输出

数字输出

由片上外设控制,高电平为高阻态,低电平接VSS

复用推挽输出

数字输出

由片上外设控制,高电平接VDD,低电平接VSS

器件原理解析

LED

 左边发光二极管高电平驱动,右边发光二极管低电平驱动。倘若单片机设置是高电平弱驱动,则不可用左边的接法,若为低电平弱驱动,则不可以用右边的接法。

面包板:

可以撕开后面看看哪里跟哪里导通的,避免踩坑。

蜂鸣器:

对于功率比较大的器件,一般使用三极管驱动的方法来连接电路,避免I/O口负担过重,有箭头是发射极,对左图,当基极给低电平时,三极管导通,蜂鸣器工作;对右图,当基极给高电平时,三极管导通,蜂鸣器工作; 需要注意的是,基极跟发射极之间需要一点开启电压,故而负载蜂鸣器一般不接在发射极一端。

小文件分享

小文件keilkill可以删减过程函数,因为工程文件一般比较大,主要内容就是这些过程量,故而想要实现高效率的分享,可以通过删减过程量,把原来的代码分享出去即可,需要编译后才能恢复如初。

LED闪烁

源代码百度云地址:

链接:https://pan.baidu.com/s/1ZL-6_cgzzKMiS8oxC2MA8Q  提取码:0323

第一步:使用RCC开启GPIO时钟

第二步:使用GPIO_Init函数初始化GPIO

第三步:使用输出或者输入函数控制GPIO

RCC常用函数在rcc.h文件中692行,跳转查看RCC用法,若无法跳转,则重新编译再尝试

GPIO常用库函数在gpio.h的349行左右,跳转查看RCC用法,若无法跳转,则重新编译再尝试

Ctr+Shift+N 快速新建文件夹

Library文件夹中可以看到各种外设的函数使用方法 根据表中寻找要使用的外设连接到哪个总线上

GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);

GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);

.c文件看内在逻辑,.h看怎么用

GPIO_WriteBit(GPIOA, GPIO_Pin_2,(BitAction)1);强制转换类型才能设置,不能直接设置1或者0.

第一步:使用RCC开启GPIO时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);   //使能APB2总线上的GPIOC上的所有引脚

第二步:使用GPIO_Init函数初始化GPIO

GPIO口的输入输出类型

从上到下依次是:模拟输入,浮空输入,下拉输入,上拉输入,开漏输出,推挽输出,复用开漏输出,复用开漏输出。


    GPIO_InitTypeDef GPIO_InitStructure;              //定义结构体名为GPIO_InitStructure
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;    //推挽输出
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;          //目标GPIOC_Pin_13,所以引脚选13
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;   //速读姑且选择50MHz
    GPIO_Init(GPIOC,&GPIO_InitStructure);             //注意第二个参数必须为指向结构名字的指针

  GPIO_InitTypeDef GPIO_InitStructure;中,设置的名字必须是GPIO_的格式,不然运行不了,因为在GPIO_Init();中,要求地址格式是那样子 。

第三步:使用输出或者输入函数控制GPIO

GPIO_SetBits(GPIOC,GPIO_Pin_13);   //PC13口输出高电平
GPIO_ResetBits(GPIOC,GPIO_Pin_13);  //PC13口输出低电平

#include "stm32f10x.h"            
#include "Delay.h"                                //延时函数头文件

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);	
	
	while (1)
	{
		GPIO_SetBits(GPIOC,GPIO_Pin_13); 
		Delay_ms(500);		                    //延时500ms,可以任意修改
		GPIO_ResetBits(GPIOC,GPIO_Pin_13); 
		Delay_ms(500);	
      }
	}

代码大义:GPIOC_Pin_13端口输出高电平并且延时500ms,然后输出低电平并且保持500ms,不断循环反复。

把上述代码中的主体函数替换为以下代码之一也有相同效果:

GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);
Delay_ms(500);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
Delay_ms(500);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,(BitAction)0;
Delay_ms(500);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,(BitAction)1);
Delay_ms(500);

流水灯

目标:使用PA0到PA5的所有端口,LED低电平亮起,依次从0到5引脚亮起。

第一步:使用RCC开启GPIO时钟

第二步:使用GPIO_Init函数初始化GPIO

第三步:使用输出或者输入函数控制GPIO

第一步:使用RCC开启GPIO时钟

第二步:使用GPIO_Init函数初始化GPIO

GPIO_Pin_All  可以选择开启所有端口,当要用到的引脚比较多的时候,不方便一个一个列举进行配置,故而可以把所有的端口都开启,不用的不进行配置就行。

也可以如下:

GPIO_InitStucture.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;

第一步第二步完整代码如下: 

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStucture;
	GPIO_InitStucture.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStucture.GPIO_Pin=GPIO_Pin_All;
	GPIO_InitStucture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStucture);

 第三步:使用输出或者输入函数控制GPIO

GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);控制多个端口,其中uint16_t PortVal表示十六位二进制数的十六进制表示,直接写到ODR寄存器中,C语言不支持直接写二进制,所以以十六进制代替。

比如:0000 0000 0000 0001 用0x0001表示

GPIO_Write(GPIOA,~0x0001);~为各位取反符号,就是0变1,1变0;

比如:~0x0001=~(0000 0000 0000 0001)=1111 1111 1111 1110

二进制的十六位分别代表PA0到PA15的16个端口。

GPIO_Write(GPIOA,~0x0001);//1111 1111 1111 1110 十六位依次对应十六个引脚,意思就是PA0置0,其余置1.
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0002);
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0004);
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0008);
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0010);//0000 0000 0001 0000

这是流水灯的主要部分的函数,其原理为把引脚从0开始,依次置0,当其中一个为0时,其他置1,这样的话在引脚处不断输出低电平,在对应的引脚灯不断亮起熄灭。

总代码:

#include "stm32f10x.h"         
#include "Delay.h"   
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStucture;
	GPIO_InitStucture.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStucture.GPIO_Pin=GPIO_Pin_All;
	GPIO_InitStucture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStucture);
	while (1)
	{
	GPIO_Write(GPIOA, ~0x0001);
	Delay_ms(500);
	GPIO_Write(GPIOA, ~0x0002);
	Delay_ms(500);
	GPIO_Write(GPIOA, ~0x0004);
	Delay_ms(500);
	GPIO_Write(GPIOA, ~0x0008);
	Delay_ms(500);
	GPIO_Write(GPIOA, ~0x0010);
	Delay_ms(500);

}

注意:A15 B3 B4调试端口,不能直接作为普通I/O口进行作用,要进行重映射后方可正常使用,尽量不适用这三者进行I/O口调用。

标签: 电阻b3a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台