一、问题与现象:
最近在用GD32F303VET6配置CAN的时候出现问题:
1、CAN不能正常收发,(检查之后是我疏忽,没有开启CAN时钟)
2、但是,我将CAN时钟开启之后,并没有解决CAN收发的问题,并且还导致了新的问题,屏幕显示有问题了。花屏,并且不能界面切换。
用到的引脚是:PB8 PB9
二、分析排查:
刚开始的代码如下:液晶屏显示正常,正常按键切换画面,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);
}
经过排查,首先有一点就是:没有开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);
}
这个时候,不但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); //配置成全重映射还会导致我的设备的显示有问题。
}
三、分析原因:
以上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)呢?
下边两张图:可以对应起来,配置为完全映射还是部分映射。
|