GD32 CAN1和TIMER0同时开启问题

背景:今天在一个项目调试的时候发现了一些问题,由此贴记录一下问题解决的过程。

使用的芯片是GD32F305VE。使用到了CAN1和TIMER0。在使用这连个外设的时候发送了一些问题。

单独使用CAN1。功能正常。

单独使用TIMER0。配置为输出模式。功能正常。

但是当两个功能同时使用,初始化的时候,就出问题了。


1、引脚配置

cpp 复制代码
//TIMER0 引脚定义
#define   TIMER0_CH2_GPIO_PIN              GPIO_PIN_10
#define   TIMER0_CH1_GPIO_PIN              GPIO_PIN_9
#define   TIMER0_CH2N_GPIO_PIN             GPIO_PIN_15
#define   TIMER0_CH1N_GPIO_PIN             GPIO_PIN_14
cpp 复制代码
//CAN1引脚定义
#define   CAN1_CLOCK                    RCU_GPIOB
#define   CAN1_GPIO                     GPIOB
#define   CAN1_TX_GPIO_PIN              GPIO_PIN_13
#define   CAN1_RX_GPIO_PIN              GPIO_PIN_12

从引脚上看,每个是没有用到重复的引脚的。都是单独分开。

2、发现问题

但是这时候,会导致一个问题。

CAN1的初始化失败了。

cpp 复制代码
//这是底层的库函数,CAN初始化
ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
{
    uint32_t timeout = CAN_TIMEOUT;
    ErrStatus flag = ERROR;
    
    /* disable sleep mode */
    CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
    /* enable initialize mode */
    CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
    /* wait ACK */
    while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
        timeout--;
    }
    /* check initialize working success */
    if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
        flag = ERROR;
    }else{
        /* set the bit timing register */
        CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
                              BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
                              BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
                              BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
                              BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));

        /* time trigger communication mode */
        if(ENABLE == can_parameter_init->time_triggered){
            CAN_CTL(can_periph) |= CAN_CTL_TTC;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
        }
        /* automatic bus-off managment */
        if(ENABLE == can_parameter_init->auto_bus_off_recovery){
            CAN_CTL(can_periph) |= CAN_CTL_ABOR;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
        }
        /* automatic wakeup mode */
        if(ENABLE == can_parameter_init->auto_wake_up){
            CAN_CTL(can_periph) |= CAN_CTL_AWU;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
        }
        /* automatic retransmission mode disable */
        if(ENABLE == can_parameter_init->no_auto_retrans){
            CAN_CTL(can_periph) |= CAN_CTL_ARD;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
        }
        /* receive fifo overwrite mode */        
        if(ENABLE == can_parameter_init->rec_fifo_overwrite){
            CAN_CTL(can_periph) |= CAN_CTL_RFOD;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
        } 
        /* transmit fifo order */
        if(ENABLE == can_parameter_init->trans_fifo_order){
            CAN_CTL(can_periph) |= CAN_CTL_TFO;
        }else{
            CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
        }  
        /* disable initialize mode */
        CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
        timeout = CAN_TIMEOUT;
        /* wait the ACK */
        while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
            timeout--;
        }
        /* check exit initialize mode */
        if(0U != timeout){
            flag = SUCCESS;
        }
    }  
    return flag;
}

进入这个函数后,会进入使能初始化工作工作模式。这个查看用户手册可以查到。

下图是进入函数运行中的寄存器状态。这是是出于初始化工作状态的

但退出函数之前,发现并没有退出初始化工作模式。导致初始化失败了。

3、定位问题

在定位问题的过程中,试了一下把TIMER0的初始化先屏蔽掉。结果就又正常了。

因此定位问题发生在TIMER0的初始化。

但是很奇怪,TIMER0的初始化,只初始化了通道1,和通道2,没有初始化通道0,按理说是不应该有影响的。

查看了寄存器

这个地方导致,这个脚被初始化为输出。再看下一个寄存器。

这里导致输出为高电平,和示波器抓到的波形一样。

所以这就是导致CAN1初始化失败的原因。

4、原理

5、解决方法

把通道0配置初始化为输入模式。就能解决问题了。

相关推荐
JiaWen技术圈1 小时前
机器人小脑的核心技术有哪些 ?
单片机·嵌入式硬件·机器人·硬件架构
要做朋鱼燕1 小时前
解析UART空闲中断与DMA接收机制
开发语言·笔记·单片机·嵌入式硬件·rtos·嵌入式软件
沪漂的码农2 小时前
MCU时钟源深度解析:内部晶振与外部晶振的技术博弈
c语言·单片机·嵌入式硬件
Mr成文2 小时前
【usb】windows usb驱动框架简介
windows·stm32·单片机
10001hours2 小时前
(基于江协科技)51单片机入门:2.独立按键
科技·嵌入式硬件·51单片机
Wave8453 小时前
STM32---了解
stm32·单片机·嵌入式硬件
STC_USB_CAN_80514 小时前
STC32G144K246-视频级动画效果演示
单片机·51单片机
jianqiang.xue4 小时前
ESP32-S3 入门教程:从环境搭建到物联网应用实战
c语言·单片机·嵌入式硬件·物联网·青少年编程·51单片机·嵌入式
一枝小雨5 小时前
STM32中的Flash、ROM与RAM全解析
stm32·单片机·嵌入式·arm·内存分布
国科安芯6 小时前
AS32S601ZIT2型MCU:基于RISC-V架构的抗辐照设计与试验评估
网络·单片机·嵌入式硬件·fpga开发·架构·硬件架构·risc-v