• GPIO端口之AFIO的完全映射与部分映射的理解


    一、问题与现象:

    最近在用GD32F303VET6配置CAN的时候出现问题:
    1、CAN不能正常收发,(检查之后是我疏忽,没有开启CAN时钟)
    2、但是,我将CAN时钟开启之后,并没有解决CAN收发的问题,并且还导致了新的问题,屏幕显示有问题了。花屏,并且不能界面切换。
    
    • 1
    • 2
    用到的引脚是:PB8 PB9

    datasheet引脚说明

    二、分析排查:

    刚开始的代码如下:液晶屏显示正常,正常按键切换画面,CAN不能收发。

    static void bsp_can_gpio_init(void)
    {
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_GPIO );
        
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_AFIO);
    
        //RX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN_RX_GPIO_PIN);
        
        //TX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN_TX_GPIO_PIN);
        
        gpio_pin_remap_config(GPIO_CAN_FULL_REMAP, ENABLE);  
    }   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    经过排查,首先有一点就是:没有开CAN时钟。所以。起开CAN时钟。就有如下代码:
    static void bsp_can_gpio_init(void)
    {
        rcu_periph_clock_enable(RCU_CAN0);  
      
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_GPIO );
        
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_AFIO);
    
        //RX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN_RX_GPIO_PIN);
        
        //TX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN_TX_GPIO_PIN);
        
        gpio_pin_remap_config(GPIO_CAN_FULL_REMAP, ENABLE);   
    }   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    这个时候,不但CAN收发功能没有好,而且导致了液晶显示花屏。比较郁闷。就看手册,看原来图。慢慢的感觉,好多东西还是得从手册中去找,去理解。
    但当我将gpio_pin_remap_config(GPIO_CAN_FULL_REMAP, ENABLE) 修改为 gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP, ENABLE); 的时候,CAN收发正常,并且液晶显示也好了。正常的代码如下:
    static void bsp_can_gpio_init(void)
    {
        rcu_periph_clock_enable(RCU_CAN0);  
      
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_GPIO );
        
        rcu_periph_clock_enable((rcu_periph_enum) CAN_RCU_AFIO);
    
        //RX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN_RX_GPIO_PIN);
        
        //TX
        gpio_init(CAN_GPIO_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN_TX_GPIO_PIN);
        
        gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP, ENABLE);  //配置成部分重映射就OK了
        
        //gpio_pin_remap_config(GPIO_CAN_FULL_REMAP, ENABLE);   //配置成全重映射还会导致我的设备的显示有问题。
    }   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    三、分析原因:

    图片1来自用户手册
    图片二来自库文件
    图3来自GD303用户手册图4来自GD303用户手册
    以上4张图,加上博文:链接: 完全重映射和部分重映射分析(超详细)但是就像评论中说得,博主的理解不完全正确,并不是说REMAP:后边一个外设就是完全重映射,超过一个就是部分重映射】 中举例的部分。然后我就理解了,理解如下:
    还是以CAN为例:我如何确定到底是部分重映射,还是完全重映射呢?

    1、我们可以查看用户手册中的GPIO部分的AFIO端口配置寄存器部分。如图:可以确认为部分重映射。

    在这里插入图片描述

    2、要准确的确定哪个引脚是部分映射还是全映射,还是得看官方手册中的GPIO部分的AFIO端口配置寄存器。如下图:

    并不能说明:TIMER3_CH0就是部分重映射。。。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    之前的错误理解:认为Remap的都应该配置为FULL_REMAP ;Alternate默认就是PARTIAL_REMAP。太操蛋了。。。。。

    在这里插入图片描述

    每一个调用库函数,都是向特定寄存器中写入特定的值,那么调用gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP, ENABLE)呢?

    下边两张图:可以对应起来,配置为完全映射还是部分映射。

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    一起来庆祝属于GISer的节日GIS DAY!
    IO 原理
    Vue项目
    四种常用的自动化测试框架
    实时时钟 RTC(2)
    Pinia基本使用
    AutoCAD 2022安装及激活
    ubuntu18/20 下如何生成core文件
    web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理
    c primer plus(2)
  • 原文地址:https://blog.csdn.net/Naunyang/article/details/126659540