STM32萌新学习日志——用GPIO外设寄存器输出点亮LED对比库函数点亮LED——谈学习感悟

本文介绍了STM32单片机中GPIO的使用,包括其功能、输出模式,以及如何通过寄存器操作点亮LED灯。作者分享了从基础配置到构建自定义库函数的过程,强调了使用现成库函数的效率和必要性。
摘要由CSDN通过智能技术生成

        本周学习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

注:来自于野火官方

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32的开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器来控制LED点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值