首页 > 版块 > STM32 > 帖子正文

STM32学习GPIO之设计篇

黄忠 发布于 2021-10-28 14:09
收藏 0 回复 0 浏览 210 原创

大家好,我是张飞实战电子黄忠老师,今日分享GPIO结合寄存器以及硬件电路,再来举例子分析输入输出。

寄存器介绍:

通过寄存器的位标注rw,我们可知这个寄存器的某个位是可读(r)并且可写的(w),我们也可以通过读寄存器里面的值得到引脚的配置信息,如果寄存器的位标注只有r或者w,那就代表这个寄存器的这个位只能进行读(r)或者写(w)

复位后IO口寄存器的值每一位可能不都是一样的,也就是说复位后IO口的状态、工作模式等不完全相同,一定要注意。

图片9.png 

模式配置寄存器GPIOx_MODER,右上角用蓝色圆圈标识的地方告诉我们IO口的复位值,可以看到复位后对于AIO口来说初始值0XA8000000,对于BIO口初始值为0x00000280,其他组IO口都是0。该寄存器共 32 位,每 2个位控制 1IO

如图中左下角划蓝线的为第0位和第1位。通过往第0位写0,第1位写0配置成Input Mode(输入模式),通过往第0位写0,第1位写1配置成General purpose output Mode(普通输出模式),通过往第0位写1,第1位写0配置成Alternate function Mode(复用功能模式),通过往第0位写1,第1位写1配置成Analog Mode(模拟模式)。

例如我们要把这个寄存器第0位写1,其他都写0,表示如下:

GPIOA->MODER |= 0x00000001;

这就相当于把A组的PA0口配置成了普通输出模式,其他IO口配置成了输入模式。

图片10.png 

GPIOx_OTYPER寄存器用于控制 IO 的输出类型,仅用于输出模式,在输入模式下不起作用。该寄存器低 16 位(第0-15位)有效,每一个位控制一个 IO 口,根据往不同的位写1(开漏输出)/0(推挽输出)来配置成不同的输出模式。复位后,该寄存器值均为 0,即默认为推挽输出。

例如我们往AIO口的第0位写1那就将PA0成开漏输出模式:

GPIOA->OTYPER |= 0x00000001;

图片11.png 

GPIOx_OSPEEDR寄存器用于控制 IO的输出速度,仅用于输出模式,在输入模式下不起作用。该寄存器每 2 个位控制一个 IO 口,根据往不同的位写1/0不同的位来配置成不同的模式。复位后对于A口来说初始值为0X0C000000,对于B口初始值0x000000C0,其他口都是0

例如我们往AIO口的第0位和第1位写1那就将PA0成高速输出模式:

GPIOA->OSPEEDR |= 0x00000003;

GPIOx_PUPDR寄存器用于控制 IO 的上拉/下拉,该寄存器每 2 个位控制一个 IO 口, 用于设置上下拉,根据往不同的位写1/0不同的位来配置成不同的模式。复位后对于A口来说初始值为0X64000000,对于B口初始值0x00000100,其他口都0x0C000000

例如我们往AIO口的第0位写1那就将PA0下拉模式:

GPIOA->PUPDR |= 0x00000001;

GPIOx_ODR寄存器是IO口的输出数据寄存器,寄存器低 16 位(第0-15位)有效,寄存器每 1 个位控制一个 IO 口, 也就是这个里面位的状态代表了单片机输出的状态,根据往不同的位写1/0不同的位来配置成不同的模式。复位后都是0

例如我们往AIO口的第0位写1PA0就输出高:

GPIOA->0DR |= 0x00000001;

对于一些其他的寄存器大家可以去参考数据手册,按照上面讲述的方法去配置。

硬件设计:

 

图片12.png 

图示LED灯部分我们用到了B组的2PIN(脚的简称)和4PIN, C组的15PIN, D组的8PIN, E组的8PIN9PIN

LED灯硬件的设计决定了LED灯的驱动方法,LED灯相当于一个发光二极管,如果单片机引脚输出高,则二极管的左边和右边电压相同,不亮,反之单片机输出低,右边电压大于左边电压通过单片机内部电路形成回路点亮二极管,那麽通过控制引脚输出的高低就控制了LED灯的亮灭。

软件设计:

下面就通过实际的寄存器来配置IO口模块,下面为LED寄存器配置代码:

void Init_GPIO(void)

{

//开启IO时钟

/**********************LED*****************************/

RCC->AHBENR |= (1<<18);  //I/O port C clock enabled

RCC->AHBENR |= (1<<19);  //I/O port D clock enabled

RCC->AHBENR |= (1<<20);  //I/O port B clock enabled

RCC->AHBENR |= (1<<17);  //I/O port A clock enabled

RCC->AHBENR |= (1<<21);  //I/O port E clock enabled

GPIOB->MODER = 0; //Reset register

    GPIOB->OSPEEDR = 0;//Reset register

GPIOB->PUPDR = 0;//Reset register

//GPIOB_Pin2  GPIOB_Pin4

GPIOB->MODER |= 0x00000110; //设置GPIOB_Pin2/Pin4输出模式

   GPIOB->OSPEEDR |= 0x00000330;//设置GPIOB_Pin2/Pin4输出速度

GPIOB->ODR |= 0x0014;    //设置GPIOB_Pin2/Pin4输出高电平

//GPIOE_Pin8 GPIOE_Pin9

GPIOE->MODER |= 0x00050000; //设置GPIOE_Pin8/Pin9输出模式

   GPIOE->OSPEEDR |= 0x000F0000; //设置GPIOE_Pin8/Pin9输出速度

GPIOE->ODR |= 0x0300; //设置GPIOE_Pin8/Pin9输出高电平

//GPIOD_Pin8

GPIOD->MODER |= 0x00010000; //设置GPIOD_Pin8输出模式

   GPIOD->OSPEEDR |= 0x00030000; //设置GPIOD_Pin8输出速度

GPIOD->ODR |= 0x0100; //设置GPIOD_Pin8输出高电平  

//GPIOC_Pin15

GPIOC->MODER |= 0x40000000; //设置GPIOC_Pin15输出模式

   GPIOC->OSPEEDR |= 0xC0000000; //设置GPIOC_Pin15输出速度

GPIOC->ODR |= 0x8000; //设置GPIOC_Pin15输出高电平

}

上面没有配置的寄存器我们使用默认值,通过改变输出数据寄存器(ODR)的值,控制某一个引脚输出高和低控制LED灯的状态

例如:控制IO输出高电平:

GPIOD->ODR |= 0x0100;    //设置GPIOD_Pin8输出高电平

控制IO输出低电平:

GPIOD->ODR &= 0xFEFF;    //设置GPIOD_Pin8输出低电平

在这里我们仅配置IO口的推挽高速输出,不上拉,不下拉模式作为演示,大家也可以根据上面介绍的方法去配置调试其他模式,GPIO部分设计实现介绍就在此结束,若有不理解的欢迎交流~


0 0
发表评论 侵权投诉
评论 (0)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表乌云踏雪网立场。

文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。