• GD32F107RC调试,CAN2不能进入接收中断的原因


    一开始的配置

        rcu_periph_clock_enable(RCU_CAN0);
        rcu_periph_clock_enable(RCU_CAN1);
        rcu_periph_clock_enable(RCU_GPIOB);
    
        rcu_periph_clock_enable(RCU_AF);
    
        /* configure CAN0 GPIO */
        gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11); //CAN0
        gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    
    
        /* configure CAN1 GPIO */
        gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_5);
        gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
        gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);
    
        nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
        /* configure CAN0 NVIC */
        nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
    
        /* configure CAN1 NVIC */
        nvic_irq_enable(CAN1_RX0_IRQn,2,0);
    
        can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
        can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
        /* initialize CAN register */
        can_deinit(CAN0);
        can_deinit(CAN1);
    
        /* initialize CAN parameters */
        can_parameter.time_triggered = DISABLE;
        can_parameter.auto_bus_off_recovery = ENABLE;//DISABLE;允许离线自动恢复
        can_parameter.auto_wake_up = DISABLE;
        can_parameter.no_auto_retrans = DISABLE;
        can_parameter.rec_fifo_overwrite = DISABLE;
        can_parameter.trans_fifo_order = DISABLE;
        can_parameter.working_mode = CAN_NORMAL_MODE;
        can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
        can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
        can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
    
        /* 1MBps */
        #if CAN_BAUDRATE == 1000
        can_parameter.prescaler = 6;//        56M/6/(1+3+5)=1M
        /* 500KBps */
        #elif CAN_BAUDRATE == 500
        can_parameter.prescaler = 12;
        /* 250KBps */
        #elif CAN_BAUDRATE == 250
        can_parameter.prescaler = 24;
        /* 125KBps */
        #elif CAN_BAUDRATE == 125
        can_parameter.prescaler = 48;
        /* 100KBps */
        #elif  CAN_BAUDRATE == 100
        can_parameter.prescaler = 60;
        /* 50KBps */
        #elif  CAN_BAUDRATE == 50
        can_parameter.prescaler = 120;
        /* 20KBps */
        #elif  CAN_BAUDRATE == 20
        can_parameter.prescaler = 300;
        #else
    #error "please select list can baudrate in private defines in main.c "
        #endif
        /* initialize CAN */
        can_init(CAN0, &can_parameter);
        can_init(CAN1, &can_parameter);
    
        /* initialize filter */
        can_filter.filter_number=0;
        can_filter.filter_mode = CAN_FILTERMODE_MASK;
        can_filter.filter_bits = CAN_FILTERBITS_32BIT;
        can_filter.filter_list_high = 0x3000;
        can_filter.filter_list_low = 0x0000;
        can_filter.filter_mask_high = 0x3000;
        can_filter.filter_mask_low = 0x0000;
        can_filter.filter_fifo_number = CAN_FIFO0;
        can_filter.filter_enable = ENABLE;
    
    /* CAN1 filter number */    can_filter.filter_number = 14;
        can_filter.filter_mode = CAN_FILTERMODE_MASK;
        can_filter.filter_bits = CAN_FILTERBITS_32BIT;
        can_filter.filter_list_high = 0x0000;
        can_filter.filter_list_low = 0x0000;
        can_filter.filter_mask_high = 0x0000;
        can_filter.filter_mask_low = 0x0000;
        can_filter.filter_fifo_number = CAN_FIFO0;//stm32为CAN_FIFO1
        can_filter.filter_enable = ENABLE;
        can_filter_init(&can_filter);
    
        can_interrupt_enable(CAN0, CAN_INT_RFNE0);//使能CAN中断
        can_interrupt_enable(CAN1, CAN_INT_RFNE0);

    发现CAN1中断进入不了。

    各种折腾都没有。测试硬件,发现CAN_RX和TX的电平都是0,推测是芯片的Can接口没有配置好,但怎么检查都没有发现配置问题。后来在数据手册发现

    程序确实在配置CAN后开启的TIM3

    void timer3_config(void)
    {
        /* ----------------------------------------------------------------------------
        TIMER1 Configuration:
        TIMER1CLK = SystemCoreClock/5400 = 20KHz.
        TIMER1 configuration is timing mode, and the timing is 0.2s(4000/20000 = 0.2s).
        CH0 update rate = TIMER1 counter clock/CH0CV = 20000/4000 = 5Hz.
        ---------------------------------------------------------------------------- */
    
        /* ----------------------------------------------------------------------------
        TIMER1 Configuration:
        TIMER1CLK = SystemCoreClock/135 = 800KHz.
        TIMER1 configuration is timing mode, and the timing is 0.1ms(80/8000000 = 0.1ms).
        CH0 update rate = TIMER1 counter clock/CH0CV = 800000/80 = 10KHz.
        ---------------------------------------------------------------------------- */
        timer_oc_parameter_struct timer_ocinitpara;
        timer_parameter_struct timer_initpara;
    
        rcu_periph_clock_enable(RCU_TIMER3);
    
        timer_deinit(TIMER3);
        /* initialize TIMER init parameter struct */
        timer_struct_para_init(&timer_initpara);
        /* TIMER1 configuration */
        timer_initpara.prescaler         = 134;//5399;
        timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
        timer_initpara.counterdirection  = TIMER_COUNTER_UP;
        timer_initpara.period            = 80;//4000;
        timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
        timer_init(TIMER3, &timer_initpara);
    
        /* initialize TIMER channel output parameter struct */
        timer_channel_output_struct_para_init(&timer_ocinitpara);
        /* CH0,CH1 and CH2 configuration in OC timing mode */
        timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
        timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
        timer_channel_output_config(TIMER3, TIMER_CH_0, &timer_ocinitpara);
    
        /* CH0 configuration in OC timing mode */
        timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, 40);//2000);
        timer_channel_output_mode_config(TIMER3, TIMER_CH_0, TIMER_OC_MODE_TIMING);
        timer_channel_output_shadow_config(TIMER3, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
    
        timer_interrupt_enable(TIMER3, TIMER_INT_CH0);
        timer_enable(TIMER3);
    }
    View Code

    改成

    void timer3_config(void)
    {
        /* ----------------------------------------------------------------------------
        TIMER1 Configuration:
        TIMER1CLK = SystemCoreClock/5400 = 20KHz.
        TIMER1 configuration is timing mode, and the timing is 0.2s(4000/20000 = 0.2s).
        CH0 update rate = TIMER1 counter clock/CH0CV = 20000/4000 = 5Hz.
        ---------------------------------------------------------------------------- */
    
        /* ----------------------------------------------------------------------------
        TIMER1 Configuration:
        TIMER1CLK = SystemCoreClock/135 = 800KHz.
        TIMER1 configuration is timing mode, and the timing is 0.1ms(80/8000000 = 0.1ms).
        CH0 update rate = TIMER1 counter clock/CH0CV = 800000/80 = 10KHz.
        ---------------------------------------------------------------------------- */
        timer_oc_parameter_struct timer_ocinitpara;
        timer_parameter_struct timer_initpara;
    
        rcu_periph_clock_enable(RCU_TIMER3);
    
        timer_deinit(TIMER3);
        /* initialize TIMER init parameter struct */
        timer_struct_para_init(&timer_initpara);
        /* TIMER1 configuration */
        timer_initpara.prescaler         = 134;//5399;
        timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
        timer_initpara.counterdirection  = TIMER_COUNTER_UP;
        timer_initpara.period            = 80;//4000;
        timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
        timer_init(TIMER3, &timer_initpara);
    
        /* initialize TIMER channel output parameter struct */
        timer_channel_output_struct_para_init(&timer_ocinitpara);
    //    /* CH0,CH1 and CH2 configuration in OC timing mode */
    //    timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;
    //    timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    //    timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    //    timer_channel_output_config(TIMER3, TIMER_CH_0, &timer_ocinitpara);
    
    //    /* CH0 configuration in OC timing mode */
    //    timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_0, 40);//2000);
    //    timer_channel_output_mode_config(TIMER3, TIMER_CH_0, TIMER_OC_MODE_TIMING);
    //    timer_channel_output_shadow_config(TIMER3, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
    
        timer_interrupt_enable(TIMER3, TIMER_INT_CH0);
        timer_enable(TIMER3);
    }
    View Code

    CAN2中断就可以了!原来,开启TIM3的ch1输出PWM,竟然导致CAN2的remap失效了!!

  • 相关阅读:
    CMD命令
    存储过程-使用(二)
    存储过程-基本(一)
    事务学习-概念(一)
    组装简历必备的9大要件
    Java 正则表达式详解_正则表达式
    各类程序员学习路线图
    mrql初级教程-使用(er)
    PHP获取当期前运行文件的路径,名字,服务器路径
    mysqldump导入导出mysql数据库
  • 原文地址:https://www.cnblogs.com/heywei/p/15960984.html
Copyright © 2020-2023  润新知