hoop 发表于 2021-6-24 18:28

FAQ0102--双CAN配置

本帖最后由 hoop 于 2022-3-19 13:31 编辑

Questions:双CAN如何配置? Answer:注:本FAQ对应的代码是基于雅特力提供的V2.x.x 板级支持包(BSP)而开发,对于其他版本BSP,需要注意使用上的区别。此代码基于BSP的DEMO程序 \examples\can\communication_mode修改,CAN1使用PA11/PA12,CAN2使用PB12/PB13。主函数:
int main(void){   system_clock_config();   at32_board_init();   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);   can_gpio_config();   can_configuration();while(1){   can_transmit_data();   at32_led_toggle(LED4);   delay_sec(1);}}
GPIO配置:
static void can_gpio_config(void){gpio_init_typegpio_init_struct;    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);   crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);    gpio_default_para_init(&gpio_init_struct);/* can1 tx pin*/   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;   gpio_init_struct.gpio_pins = GPIO_PINS_12;   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;gpio_init(GPIOA,&gpio_init_struct);/* can2 tx pin*/   gpio_init_struct.gpio_pins = GPIO_PINS_13;   gpio_init(GPIOB, &gpio_init_struct); /* can1 rx pin*/   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;   gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;   gpio_init_struct.gpio_pins = GPIO_PINS_11;   gpio_init_struct.gpio_pull = GPIO_PULL_UP;gpio_init(GPIOA,&gpio_init_struct);/* can2 rx pin*/   gpio_init_struct.gpio_pins = GPIO_PINS_12;gpio_init(GPIOB,&gpio_init_struct);}
CAN配置:
static void can_configuration(void){    can_base_typecan_base_struct;   can_baudrate_type can_baudrate_struct;   can_filter_init_type can_filter_init_struct;       crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);    crm_periph_clock_enable(CRM_CAN2_PERIPH_CLOCK, TRUE); /* can1 base init */   can_default_para_init(&can_base_struct);   can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;   can_base_struct.ttc_enable = FALSE;   can_base_struct.aebo_enable = TRUE;   can_base_struct.aed_enable = TRUE;   can_base_struct.prsf_enable = FALSE;   can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;   can_base_struct.mmssr_selection = CAN_SENDING_BY_ID;   can_base_init(CAN1, &can_base_struct);/* can2 baseinit */   can_base_init(CAN2, &can_base_struct);   /* canbaudrate, set baudrate = pclk/(baudrate_div *(3 + bts1_size + bts2_size)) */   can_baudrate_struct.baudrate_div = 10;   can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ;   can_baudrate_struct.bts1_size = CAN_BTS1_8TQ;   can_baudrate_struct.bts2_size = CAN_BTS2_3TQ;/* can1baudrate = (240/2)MHz/(10 *(3 + 7 + 2)) = 1MHz */   can_baudrate_set(CAN1, &can_baudrate_struct);/* can2baudrate = (240/2)MHz/(10 *(3 + 7 + 2)) = 1MHz */   can_baudrate_set(CAN2, &can_baudrate_struct); /* can1 filterinit */   can_filter_init_struct.filter_activate_enable = TRUE;   can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;   can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;   can_filter_init_struct.filter_number = 0;   can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;   can_filter_init_struct.filter_id_high = 0;   can_filter_init_struct.filter_id_low = 0;   can_filter_init_struct.filter_mask_high = 0;   can_filter_init_struct.filter_mask_low = 0;   can_filter_init(CAN1, &can_filter_init_struct);/* can1 filterinit */   can_filter_init(CAN2, &can_filter_init_struct);/* caninterrupt config */   nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0x00, 0x00);   nvic_irq_enable(CAN1_SE_IRQn, 0x00, 0x00);   nvic_irq_enable(CAN2_RX0_IRQn, 0x00, 0x01);   nvic_irq_enable(CAN2_SE_IRQn, 0x00, 0x01);   can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);   can_interrupt_enable(CAN1, CAN_ETRIEN_INT, TRUE);   can_interrupt_enable(CAN1, CAN_EOIEN_INT, TRUE);   can_interrupt_enable(CAN2, CAN_RF1MIEN_INT, TRUE);   can_interrupt_enable(CAN2, CAN_ETRIEN_INT, TRUE);   can_interrupt_enable(CAN2, CAN_EOIEN_INT, TRUE);}
中断处理函数:
/* can1 interrupt function rx0 */void USBFS_L_CAN1_RX0_IRQHandler (void){   can_rx_message_type rx_message_struct;      if(can_flag_get(CAN1,CAN_RF0MN_FLAG) != RESET){   can_message_receive(CAN1, CAN_RX_FIFO0, &rx_message_struct);   if(rx_message_struct.standard_id == 0x400)       at32_led_toggle(LED1);     else      at32_led_toggle(LED3);}}/* can1 interrupt function rx0 */void CAN1_SE_IRQHandler(void){__IO uint32_terr_index = 0;    if(can_flag_get(CAN1,CAN_ETR_FLAG) != RESET){    err_index =CAN1->ests & 0x70;   can_flag_clear(CAN1, CAN_ETR_FLAG);    if(err_index== 0x00000010)    {       can_reset(CAN1);       can_configuration();    }}}/* can2 interrupt function rx0 */void CAN2_RX0_IRQHandler (void){   can_rx_message_type rx_message_struct;      if(can_flag_get(CAN2,CAN_RF1MN_FLAG) != RESET){   can_message_receive(CAN2, CAN_RX_FIFO0, &rx_message_struct);   if(rx_message_struct.standard_id == 0x400)       at32_led_toggle(LED2);     else       at32_led_toggle(LED3);}}/* can2 interrupt function rx0 */void CAN2_SE_IRQHandler(void){__IO uint32_terr_index = 0;    if(can_flag_get(CAN2,CAN_ETR_FLAG) != RESET){    err_index =CAN2->ests & 0x70;   can_flag_clear(CAN2, CAN_ETR_FLAG);    if(err_index== 0x00000010)    {       can_reset(CAN2);       can_configuration();    }}}
CAN发送配置:
static void can_transmit_data(void){uint8_ttransmit_mailbox;   can_tx_message_type tx_message_struct;   tx_message_struct.standard_id = 0x400;   tx_message_struct.extended_id = 0;   tx_message_struct.id_type = CAN_ID_STANDARD;   tx_message_struct.frame_type = CAN_TFT_DATA;   tx_message_struct.dlc = 8;   tx_message_struct.data = 0x11;   tx_message_struct.data = 0x22;   tx_message_struct.data = 0x33;   tx_message_struct.data = 0x44;   tx_message_struct.data = 0x55;   tx_message_struct.data = 0x66;   tx_message_struct.data = 0x77;   tx_message_struct.data = 0x88;   transmit_mailbox = can_message_transmit(CAN1, &tx_message_struct);   while(can_transmit_status_get(CAN1,(can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL);   transmit_mailbox = can_message_transmit(CAN2, &tx_message_struct);   while(can_transmit_status_get(CAN2,(can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL);}
类型:MCU应用适用型号:AT32F403A, AT32F407, AT32F413主功能:CAN次功能:无

fuqinyyy 发表于 2021-7-12 20:56

有CAN-FD就好了。

lidi911 发表于 2021-7-13 08:13

这个片子一共有几个CAN?

lidi911 发表于 2021-7-13 08:14

这个片子一共有几个CAN?

muyichuan2012 发表于 2021-7-13 08:57

一共两个CAN,都是完全独立的。

单片小菜 发表于 2021-7-14 14:50

如果使用双CAN的话,是不是会好一些?

自己造声卡 发表于 2021-7-14 16:20

两个CAN特别好用的。

hoop 发表于 2021-7-16 20:01

单片小菜 发表于 2021-7-14 14:50
如果使用双CAN的话,是不是会好一些?

是相互独立的两个CAN,视具体应用而定,双CAN的话,报文传输效率是会明显优于单CAN的
页: [1]
查看完整版本: FAQ0102--双CAN配置