lugl4313820 发表于 2022-4-17 13:16

【AT-START-F425测评】USB转CAN之六 完成动态设置收发

<p>【AT-START-F425测评】USB转CAN 预告帖 https://bbs.eeworld.com.cn/thread-1199896-1-1.html</p>

<p>【AT-START-F425测评】USB转CAN之二 https://bbs.eeworld.com.cn/thread-1199901-1-1.html</p>

<p>【AT-START-F425测评】USB转CAN之三 https://bbs.eeworld.com.cn/thread-1200055-1-1.html</p>

<p>【AT-START-F425测评】USB转CAN之四 完成收发测试 https://bbs.eeworld.com.cn/thread-1200061-1-1.html</p>

<p>【AT-START-F425测评】USB转CAN之五 &nbsp;串口命令解释 https://bbs.eeworld.com.cn/thread-1200119-1-1.html</p>

<p>【前言】接上面的帖子,今天主要做动态配置CAN分发送速率,发送测试:</p>

<p>1、更新CAN扩展、标准的配置:</p>

<pre>
<code>/**
*@brief can configiguration.
*@paramnone
*@retval none
*/
void can_configuration(void)
{   
can_base_type can_base_struct;
can_baudrate_type can_baudrate_struct;
can_filter_init_type can_filter_init_struct;
        can_gpio_config();
/* enable the can clock */
crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);

/* can base init */
can_default_para_init(&amp;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, &amp;can_base_struct);
   
}

//检查并转换字符为数字
u8 Check_Number(u8 checkdata)
{
    if (checkdata &gt;= 0x30 &amp;&amp; checkdata &lt;= 0x39)
    {
      return checkdata - 0x30;
    }
    else if (checkdata &gt;= 0x41 &amp;&amp; checkdata &lt;= 0x46)
    {
      return checkdata - 0x37;
    }
    else if (checkdata &gt;= 0x61 &amp;&amp; checkdata &lt;= 0x66)
    {
      return checkdata - 0x57;
    }
    else
    {
      CotrolVale = 0x80;
      return 0;
    }
}


/************************************************************************
* @描述:CAN扩展帧滤波器设置
* @参数:id1,id2 效验码   mid1,mid2 屏蔽码
* @返回值: None
**********************************************************************/
void CAN1_Config32BitFilter(u32 id1, u32 id2, u32 mid1, u32 mid2)
{
        can_filter_init_type can_filter_init_struct;
/* can 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 = id1&gt;&gt;13;
can_filter_init_struct.filter_id_low = (id1&lt;&lt;3)|4;
can_filter_init_struct.filter_mask_high = mid1&gt;&gt;13;
can_filter_init_struct.filter_mask_low = (mid1&lt;&lt;3)|4;
can_filter_init(CAN1, &amp;can_filter_init_struct);
can_filter_init_struct.filter_number = 1;
can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
can_filter_init_struct.filter_id_high = id2&gt;&gt;13;
can_filter_init_struct.filter_id_low = (id2&lt;&lt;3)|4;
can_filter_init_struct.filter_mask_high = mid2&gt;&gt;13;
can_filter_init_struct.filter_mask_low = (mid2&lt;&lt;3)|4;
can_filter_init(CAN1, &amp;can_filter_init_struct);
/* can interrupt config */
nvic_irq_enable(CAN1_IRQn, 0x00, 0x00);
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速率配置
* @参数:velocity 速率分频值
* @返回值: None
**********************************************************************/
void CAN_Config(uint8_t velocity)
{
        can_base_type can_base_struct;
can_baudrate_type can_baudrate_struct;
can_filter_init_type can_filter_init_struct;
        can_gpio_config();
/* enable the can clock */
crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);

/* can base init */
can_default_para_init(&amp;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, &amp;can_base_struct);
   
/* can baudrate, set boudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
can_baudrate_struct.baudrate_div = velocity;//16为500K8//1M32 //250K64//12580/100
can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ;
can_baudrate_struct.bts1_size = CAN_BTS1_8TQ;
can_baudrate_struct.bts2_size = CAN_BTS2_3TQ;
can_baudrate_set(CAN1, &amp;can_baudrate_struct);
       
       
}


/************************************************************************
* @描述:CAN标准帧滤波器设置
* @参数:id1,id2 效验码   mid1,mid2 屏蔽码
* @返回值: None
**********************************************************************/
void CAN1_Config16BitFilter(u16 id1, u16 id2, u16 mid1, u16 mid2)
{
can_filter_init_type can_filter_init_struct;
               
        /* can 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_16BIT;
can_filter_init_struct.filter_id_high = id1&lt;&lt;5;
can_filter_init_struct.filter_id_low = id2&lt;&lt;5;
can_filter_init_struct.filter_mask_high = mid1&lt;&lt;5;
can_filter_init_struct.filter_mask_low = mid2&lt;&lt;5;
can_filter_init(CAN1, &amp;can_filter_init_struct);

/* can interrupt config */
nvic_irq_enable(CAN1_IRQn, 0x00, 0x00);
can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
can_interrupt_enable(CAN1, CAN_ETRIEN_INT, TRUE);
can_interrupt_enable(CAN1, CAN_EOIEN_INT, TRUE);
}

//发送数据
void SendCANFrame(void)
{
    uint8_t transmit_mailbox,i;
    can_tx_message_type tx_message_struct;
    u16 ID1,ID2,MID1,MID2;
    u32 id1,id2,mid1,mid2;
    CAN_Config(8000000/(Check_Number(Cmd)*1000000+Check_Number(Cmd)*100000+Check_Number(Cmd)*10000+Check_Number(Cmd)*1000
                        +Check_Number(Cmd)*100+Check_Number(Cmd)*10+Check_Number(Cmd)));




    if (!strncmp((const char *)Cmd+4,"STD",3))
    {
      //配合上位机软件加入          2016.10.09
      if((CotrolVale &amp; 0x80) != 0x80)
      {
            ID1 = Check_Number(Cmd)&lt;&lt;8;
            ID1 |= Check_Number(Cmd)&lt;&lt;4;
            ID1 |= Check_Number(Cmd);
            ID2 = Check_Number(Cmd)&lt;&lt;8;
            ID2 |= Check_Number(Cmd)&lt;&lt;4;
            ID2 |= Check_Number(Cmd);
            MID1 = Check_Number(Cmd)&lt;&lt;8;
            MID1 |= Check_Number(Cmd)&lt;&lt;4;
            MID1 |= Check_Number(Cmd);
            MID2 = Check_Number(Cmd)&lt;&lt;8;
            MID2 |= Check_Number(Cmd)&lt;&lt;4;
            MID2 |= Check_Number(Cmd);
            if((CotrolVale &amp; 0x80) != 0x80)
            {
                CAN1_Config16BitFilter(ID1, ID2, MID1, MID2);
            }
            else
            {
                CAN1_Config16BitFilter(0,0,0,0);
                CotrolVale=0x05;
            }
      }
      tx_message_struct.id_type = CAN_ID_STANDARD;
      tx_message_struct.frame_type = CAN_TFT_DATA;
      tx_message_struct.dlc = Check_Number(Cmd);
      tx_message_struct.standard_id = (u32)Check_Number(Cmd)&lt;&lt;8;
      tx_message_struct.standard_id |= (u32)Check_Number(Cmd)&lt;&lt;4;
      tx_message_struct.standard_id |= (u32)Check_Number(Cmd);
      for(i = 0; i &lt; tx_message_struct.dlc; i++)
      {
            tx_message_struct.data = (u8)Check_Number(Cmd)&lt;&lt;4;
            tx_message_struct.data |= (u8)Check_Number(Cmd);
      }
      if ((CotrolVale &amp; 0x80) != 0x80)
      {
            transmit_mailbox = can_message_transmit(CAN1, &amp;tx_message_struct);
                                                while(can_transmit_status_get(CAN1, (can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL);
                                                CotrolVale = 0x10;
      }
    }
    else if (!strncmp((const char *)Cmd+4,"EXT",3))
    {
      //配合上位机软件加入          2016.10.09
      if((CotrolVale &amp; 0x80) != 0x80)
      {
            id1 = 0;
            id2 = 0;
            mid1 = 0;
            mid2 = 0;
            for (i = 0; i &lt; 8; i++)
            {
                id1 |= Check_Number(Cmd)&lt;&lt;4*(7-i);
            }

            for (i = 0; i &lt; 8; i++)
            {
                id2 |= Check_Number(Cmd)&lt;&lt;4*(7-i);
            }

            for (i = 0; i &lt; 8; i++)
            {
                mid1 |= Check_Number(Cmd)&lt;&lt;4*(7-i);
            }

            for (i = 0; i &lt; 8; i++)
            {
                mid2 |= Check_Number(Cmd)&lt;&lt;4*(7-i);
            }
            if((CotrolVale &amp; 0x80) != 0x80)
            {
                CAN1_Config32BitFilter(id1,id2,mid1,mid2);
            }
            else
            {
                CAN1_Config16BitFilter(0,0,0,0);
                CotrolVale=0x05;
            }
      }
      tx_message_struct.id_type = CAN_ID_EXTENDED;
      tx_message_struct.frame_type = CAN_TFT_DATA;
      tx_message_struct.dlc = Check_Number(Cmd);
      for (i = 0; i &lt; 8; i++)
      {
            tx_message_struct.extended_id |= (u32)Check_Number(Cmd)&lt;&lt;4*(7-i);
      }
      for(i = 0; i &lt; tx_message_struct.dlc; i++)
      {
            tx_message_struct.data = (u8)Check_Number(Cmd)&lt;&lt;4;
            tx_message_struct.data |= (u8)Check_Number(Cmd);
      }
      if ((CotrolVale &amp; 0x80) != 0x80)
      {
            transmit_mailbox = can_message_transmit(CAN1, &amp;tx_message_struct);
                                                while(can_transmit_status_get(CAN1, (can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL);
                                                CotrolVale = 0x10;
      }
    }
}</code></pre>

<p>更新主程序:</p>

<pre>
<code> if (CotrolVale == 0x01)
                        {
                                        HELPText();
                        }
               else if        (CotrolVale == 0x03)
                        {
                                        SetSTDFilter();
                        }
                        else if (CotrolVale == 0x04)
                        {
                                        SetEXTFilter();
                        }
                        else if (CotrolVale == 0x05)
                        {
                                        SendCANFrame();
                        }
                        if (CotrolVale == 0x80)
                        {
                                        WarningText();
                        }
</code></pre>

<p>实验现象:</p>

<p>1、配置标准帧1M:</p>

<p>&nbsp;CAN分析仪设置为1M</p>

<p>&nbsp;发送数据:</p>

<p>&nbsp;设置扩张帧1M:</p>

<p>&nbsp;至此CAN转收发设置,收发全部调通。</p>
页: [1]
查看完整版本: 【AT-START-F425测评】USB转CAN之六 完成动态设置收发