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次功能:无 有CAN-FD就好了。 这个片子一共有几个CAN? 这个片子一共有几个CAN? 一共两个CAN,都是完全独立的。 如果使用双CAN的话,是不是会好一些?
两个CAN特别好用的。
单片小菜 发表于 2021-7-14 14:50
如果使用双CAN的话,是不是会好一些?
是相互独立的两个CAN,视具体应用而定,双CAN的话,报文传输效率是会明显优于单CAN的
页:
[1]