ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-03-03 17:33:41  阅读:340  来源: 互联网

标签:GD32F107RC TIMER filter init CAN2 timer TIMER3 parameter 调试


一开始的配置

    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失效了!!

 

标签:GD32F107RC,TIMER,filter,init,CAN2,timer,TIMER3,parameter,调试
来源: https://www.cnblogs.com/heywei/p/15960984.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有