失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【STM32】标准库 菜鸟入门教程(3)闪烁及流水灯

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

时间:2020-01-20 11:14:42

相关推荐

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

目录

GPIO

GPIO基本结构

GPIO位结构

GPIO模式

器件原理解析

LED

面包板:

蜂鸣器:

小文件分享

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个端口分别通过驱动器与十六个引脚相连,GPIO外设命名方式为GPIOX(X=A、B、C......),十六个引脚命名的方式为PX0,PX1,PX2......PX15,其中X=A、B、C,根据引脚所在外设决定。

STM32是32位的单片机,所以STM32内部的寄存器也是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,则表示电源为5V。

上拉电阻及下拉电阻:可以通过软件配置,当VDD导通VSS断开时,为上拉输入模式,引脚悬空时为高电平,反之为下拉输入模式,引脚悬空时为低电平,两者都断开时,为浮空输入模式,引脚悬空时电平不确定,极易受外界干扰而变化。

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

施密特触发器:作用为对输入电压整形,设置有阈值上限和阈值下限,当I/O口的输入模拟信号超过上限时,施密特触发器输出高电平,当I/O口输入的模拟信号低于下限时,施密特触发器输出低电平,其余时候保持原有电平不变。整形后输入数据存储器保存,再用程序读取就可以知道某位的高低电平。

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

位设置/清除寄存器:可以对寄存器中的数据进行单独的位操作,不用整体进行&=或者/=,方便快捷。写1是设置或者清除,写0的位保持不变。高16位是用于位清除的,低16位是用于位设置的,还有一个单独的位清除寄存器,两者配合使用就能之用低16位就可以完成设置与清除,更加便捷,但缺点是不能同步进行,若想要同步进行,就只是采用设置/清除寄存器即可。

P-MOS和N-MOS:两者可以控制三种输出模式:推挽输出,开漏输出以及关闭。

当设置为推挽输出时,P-MOS和N-MOS都有效,当1信号通过输出控制进入MOS管,在P-MOS管被取反为0,在N-MOS管依旧是1,此时P-MOS管导通,N-MOS管断开,输出高电平,反之低电平。

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

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

GPIO模式

器件原理解析

LED

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

面包板:

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

蜂鸣器:

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

小文件分享

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

LED闪烁

源代码百度云地址:

链接:/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_InitStructureGPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;//目标GPIOC_Pin_13,所以引脚选13GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //速读姑且选择50MHzGPIO_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口调用。

如果觉得《【STM32】标准库 菜鸟入门教程(3)闪烁及流水灯》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。