打印
[应用相关]

FAQ0102--双CAN配置

[复制链接]
3506|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hoop|  楼主 | 2021-6-24 18:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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_type  gpio_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_type  can_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 base  init */
  
   can_base_init(CAN2, &can_base_struct);
  
   
  
  /* can  baudrate, 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;
  
  /* can1  baudrate = (240/2)MHz/(10 *(3 + 7 + 2)) = 1MHz */
  
   can_baudrate_set(CAN1, &can_baudrate_struct);
  
  /* can2  baudrate = (240/2)MHz/(10 *(3 + 7 + 2)) = 1MHz */
  
   can_baudrate_set(CAN2, &can_baudrate_struct);
  
  
  /* can1 filter  init */
  
   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 filter  init */
  
   can_filter_init(CAN2, &can_filter_init_struct);
  
  
  
  /* can  interrupt 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_t  err_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_t  err_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_t  transmit_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[0] = 0x11;
  
   tx_message_struct.data[1] = 0x22;
  
   tx_message_struct.data[2] = 0x33;
  
   tx_message_struct.data[3] = 0x44;
  
   tx_message_struct.data[4] = 0x55;
  
   tx_message_struct.data[5] = 0x66;
  
   tx_message_struct.data[6] = 0x77;
  
   tx_message_struct.data[7] = 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
次功能:

FAQ0102_双CAN配置_V2.0.0.pdf

288.93 KB

使用特权

评论回复
沙发
fuqinyyy| | 2021-7-12 20:56 | 只看该作者
有CAN-FD就好了。

使用特权

评论回复
板凳
lidi911| | 2021-7-13 08:13 | 只看该作者
这个片子一共有几个CAN?

使用特权

评论回复
地板
lidi911| | 2021-7-13 08:14 | 只看该作者
这个片子一共有几个CAN?

使用特权

评论回复
5
muyichuan2012| | 2021-7-13 08:57 | 只看该作者
一共两个CAN,都是完全独立的。

使用特权

评论回复
6
单片小菜| | 2021-7-14 14:50 | 只看该作者
如果使用双CAN的话,是不是会好一些?

使用特权

评论回复
7
自己造声卡| | 2021-7-14 16:20 | 只看该作者
两个CAN特别好用的。

使用特权

评论回复
8
hoop|  楼主 | 2021-7-16 20:01 | 只看该作者
单片小菜 发表于 2021-7-14 14:50
如果使用双CAN的话,是不是会好一些?

是相互独立的两个CAN,视具体应用而定,双CAN的话,报文传输效率是会明显优于单CAN的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

322

帖子

0

粉丝