STM32学习日志:GPIO外设寄存器与库函数点亮LED对比及学习感悟

        本周学习STM32单片机,由于之前学过51单片机,为了便于切入,先学习了寄存器点亮LED灯的方法,整体思路与51单片机相似。在基本掌握后,尝试自己构建库函数雏形,过程比较困难,后面开始借鉴野火官方库函数。

        这里其实建议大家在学会构建库函数后,没必要每个库函数都自己构建,太消耗时间。当然,若果时间充裕的话,自己构建库函数可以使之后的工程的开发、学习都更加方便,毕竟自己写的更加熟悉。

一、GPIO简述、功能及输出过程

        GPIO 即 general purpose intput output ,是通用输入输出端的简称,简单来说就是软件可控制 的引脚, STM32芯片的GPIO弓|脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。例如输出高低电平控制LED灯的亮灭状态。GPIO是包含在100引脚之内的,包含诸如PE2、PE3……等引脚。

        专用器件接到专用的总线,比如I2C, SPI, SDIO, FSMC, DCMI这些总线的器件需要接到专用的I0,普通的元器件接到GPIO,比如蜂鸣器,LED,按键等元器件用普通的GPIO,如果还有剩下的I0,可根据项目需要引出或者不引出。

        由于时间限制,本篇文章只讲述DPIO输出,接下来将以下面的功能框架图作为例图进行讲解。

         如果电压高于VDD,电流会由I/O引脚流向VDD,如果高出太多,可能会导致芯片烧毁。因此I/O口不能直接接电机,需要通过一个驱动电路进行隔离。从图中我们可以看到推挽输出、开漏输出、关闭三个输出模式。

        首先是推挽输出。当输出数据寄存器输出1时,经过1-2管时会反转为0,此时Ug=0<Us,vdd与OUT导通且,两端电压相等,为3.3v,即p管导通,n管截止,out输出3.3v。反之亦然,若输出数据寄存器输出0时,out输出0。

什么叫推挽输出?

1、可以输出高低电平,用于连接数字器件,高电平由VDD(3.3v)决定,低电平由VSS决定。

2、推挽结构指两个三极管受两路互补的信号控制,总是在一个导通的时候另外一个截止,优点开关效率效率高(电流大,驱动能力强。

3、输出高电平时,电流输出到负载,叫灌电流,可以理解成推,输出低电平时,负载电流流向芯片,叫拉电流,即挽。

什么叫开漏输出?

1、只能输出低电平,不能输出高电平。

2、如果要输出高电平,则需要外接上拉。

3、开漏输出具有“线与”功能,一个为低,全部为低,多用于I2C和SMBUS总线。

二、寄存器点亮LED灯

        总线共有三个,APB1、APB2、AHB。

        BSRR指bit set reset 寄存器,是32位寄存器,输入1为有效,0为无效,低16位为set,设置,高电平,高16位为reset,复位,低电平,即0。

        各寄存器之间存在一个地址的偏移,偏移是以4为一个单位,首先找到总线的基地址,然后通过偏移找到外设基地址,再通过偏移找到需要的寄存器基地址,最初外设基地址是总线1,即APB1的基地址。

        

下面的图是基址的偏移的实例。

我们这里首先开启GPIOB 端口时钟,清空控制PB0的端口位之后,再配置PB0为通用推挽输出,使PB0输出为低电平。编程如下:

#include "stm32f10x.h" 

int main(void)
{    
    // 开启GPIOB 端口时钟
    RCC_APB2ENR |= (1<<3);

    //清空控制PB0的端口位
    GPIOB_CRL &= ~( 0x0F<< (4*0));    
    // 配置PB0为通用推挽输出,速度为10M
    GPIOB_CRL |= (1<<4*0);

    // PB0 输出 低电平
    GPIOB_ODR &= ~(1<<0);
    
    //GPIOB_ODR |= (1<<0);
    while(1);
}

// 函数为空,目的是为了骗过编译器不报错
void SystemInit(void)
{    
}

效果图:

三、固件库点亮LED灯

1.下面是自定义头文件的源文件.c

#include "bsp_led.h"   

void LED_GPIO_Config(void)
{        
        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;

        /*开启LED相关的GPIO外设时钟*/
        RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK, ENABLE);
        /*选择要控制的GPIO引脚*/
        GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;    

        /*设置引脚模式为通用推挽输出*/
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

        /*设置引脚速率为50MHz */   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

        /*调用库函数,初始化GPIO*/
        GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);    
        
        /*选择要控制的GPIO引脚*/
        GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;

        /*调用库函数,初始化GPIO*/
        GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
        
        /*选择要控制的GPIO引脚*/
        GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;

        /*调用库函数,初始化GPIOF*/
        GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);

        /* 关闭所有led灯    */
        GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
        
        /* 关闭所有led灯    */
        GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);     
    
    /* 关闭所有led灯    */
        GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN);
}

2.下面是主函数源文件.c

#include "stm32f10x.h"
#include "bsp_led.h"

#define SOFT_DELAY Delay(0x0FFFFF);

void Delay(__IO u32 nCount);

 
int main(void)
{    
    /* LED 端口初始化 */
    LED_GPIO_Config();     

    while (1)
    {
        LED1_ON;              // 亮
        SOFT_DELAY;
        LED1_OFF;           // 灭

        LED2_ON;             // 亮
        SOFT_DELAY;
        LED2_OFF;           // 灭

        LED3_ON;             // 亮
        SOFT_DELAY;
        LED3_OFF;           // 灭     

        /*轮流显示 红绿蓝黄紫青白 颜色*/
        LED_RED;
        SOFT_DELAY;
        
        LED_GREEN;
        SOFT_DELAY;
        
        LED_BLUE;
        SOFT_DELAY;
        
        LED_YELLOW;
        SOFT_DELAY;
        
        LED_PURPLE;
        SOFT_DELAY;
                
        LED_CYAN;
        SOFT_DELAY;
        
        LED_WHITE;
        SOFT_DELAY;
        
        LED_RGBOFF;
        SOFT_DELAY;        
    }
}

void Delay(__IO uint32_t nCount)     //简单的延时函数
{
    for(; nCount != 0; nCount–);
}
/*********************************************END OF FILE**********************/

下面是效果图:

下载链接:

http://products.embedfire.com

注:来自于野火官方

作者:萌新在线学习

物联沃分享整理
物联沃-IOTWORD物联网 » STM32学习日志:GPIO外设寄存器与库函数点亮LED对比及学习感悟

发表评论