活动发起人@小虚竹 想对你说:

这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!我们一起发掘写作的魅力,书写出属于我们的故事。我们诚挚邀请你参加为期14天的创作挑战赛!

提醒:在发布作品前,请将不需要的内容删除。

一.输出模式下:推挽 vs 开漏

结合了B站野火讲义,简单介绍推挽和开漏:

推挽:推挽的最大特点是可以真正能真正的输出高电平和低电平输出 用于驱动

开漏:需要外部上拉才能输出高电平

一般单片机IO输出方式如下:输出驱动器中的P/N-MOS两个MOS管实现推挽输出和开漏输出。

  1. 推挽输出模式下,P-MOS和N-MOS都正常工作,

  2. 开漏输出模式下,只有下面的N-MOS工作,上面的P-MOS不工作。

推挽:

开漏:

二.GPIO结构框图

(在学习过程中,发现配置全是基于结构进行开展的,所以掌握结构,就可以向拿捏ARM内核单片机迈进一大步)

GPIO结构框图见下:(和STM32的GPIO结构无差别)

 (ESD保护和STM32的二极管保护电路,如下图,起到的作用为:静电保护,防止电压大于或小于正常工作电压阈值)

备注:

GPIO_MODE_AIN(模拟输入)

GPIO_MODE_IN_FLOATING(浮空输入)

GPIO_MODE_IPD(下拉输入)

GPIO_MODE_IPU(上拉输入)

GPIO_MODE_OUT_OD(开漏输出)

GPIO_MODE_OUT_PP(推挽输出)

GPIO_MODE_AF_OD(复用开漏输出)

GPIO_MODE_AF_PP(复用推挽输出)

GPIO_MODE_INPUT(输入模式)

GPIO_MODE_OUTPUT(输出模式)

GPIO_MODE_AF(复用模式)

GPIO_MODE_ANALOG(模拟模式)

GPIO_PUPD_NONE(无上下拉)

GPIO_PUPD_PULLUP(上拉)

GPIO_PUPD_PULLDOWN(下拉)

1. 读-----(输入配置)

◼ 施密特触发输入使能;

◼ 可选择的弱上拉和下拉电阻;

◼ I/O引脚上的数据在每个APBx时钟周期都会被采样并存入端口输入状态寄存器;

◼ 输出缓冲器禁用。
 

    2.写------(输出配置)

    ◼ 施密特触发输入使能;

    ◼ 弱上拉和下拉电阻禁用;

    ◼ 输出缓冲器使能;

    ◼配置开漏或者推挽

    开漏模式: 输出控制寄存器设置为“0”时, 相应引脚输出低电平; 输出控制寄存器设置为“1”,相应管脚处于高阻状态;

    推挽模式: 输出控制寄存器设置为“0”时, 相应引脚输出低电平; 输出控制寄存器设置为“1”,相应引脚输出高电平;

    rcu_periph_clock_enable(RCU_GPIOA]);//时钟使能
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
    • GPIO_PORT : 选择端口
    • (MODE)模式选择 :输出模式_推挽输出
    • (OSPEED)输出速度
    • GPIO_PIN:PIN脚

    3.模拟配置

    ◼ 弱上拉和下拉电阻禁用;

    ◼ 输出缓冲器禁用;

    ◼ 施密特触发输入禁用;

    ◼ 端口输入状态寄存器相应位为“0”。
     

    4.复用功能

    复用类型,参考手册如下

    /*!< AFIO output with open-drain */
    #define GPIO_MODE_AF_OD                  ((uint8_t)0x1CU)          
    /*!< AFIO output with push-pull */
    #define GPIO_MODE_AF_PP                  ((uint8_t)0x18U)          
    
    rcu_periph_clock_enable(RCU_AF);
    
    /* config the GPIO as analog mode, for ADC */
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    /* config the GPIO as floating input mode, for EXTI */
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_15);

    5.主函数调用

    实现LED1点亮

    //主函数
    int main(void)
    {
        /* configure systick */
        systick_config();
    
        gd_eval_led_init(LED1); 
        
        gd_eval_led_on(LED1);
        delay_1ms(500);
        gd_eval_led_off(LED1);
       
    }
    
    //led.c
    void  gd_eval_led_init (led_typedef_enum lednum)
    {
        /* enable the led clock */
        rcu_periph_clock_enable(GPIO_CLK[lednum]);
        /* configure led GPIO port */ 
        gpio_init(GPIO_PORT[lednum], GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN[lednum]);
    
        GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
    }
    
    void gd_eval_led_on(led_typedef_enum lednum)
    {
        GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
    }
    
    void gd_eval_led_off(led_typedef_enum lednum)
    {
        GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
    }

     结合GD32用户手册,原理图,BC、BOP寄存器控制寄存器的输出电平

    BC寄存器位清除,等效于置0效果,灯灭,BOP反之。(二极管阳极接高电平导通)

    三.总结

    1、确定GPIO是输入、通用输出、复用功能还是模拟输入。(模式寄存器:MODER)


    2、如果输出还要确定是推挽输出还是开漏输出(输出类型寄存器:OTYPER)


    3、配置输出的速度(输出速度寄存器:OSPEEDR)


    4、输出的时候内部的上/下拉电阻要不要开启(上拉/下拉寄存器:PUPDR


    5、具体要输出的内容(置位复位寄存器:BSRR和数据输出寄存器:ODR

    Logo

    智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

    更多推荐