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

lugl4313820   2022-4-17 13:16 楼主

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

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

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

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

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

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

1、更新CAN扩展、标准的配置:

/**
  *  [url=home.php?mod=space&uid=159083]@brief[/url] can configiguration.
  *  @param  none
  *  @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(&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);
    
}

//检查并转换字符为数字
u8 Check_Number(u8 checkdata)
{
    if (checkdata >= 0x30 && checkdata <= 0x39)
    {
        return checkdata - 0x30;
    }
    else if (checkdata >= 0x41 && checkdata <= 0x46)
    {
        return checkdata - 0x37;
    }
    else if (checkdata >= 0x61 && checkdata <= 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>>13;
  can_filter_init_struct.filter_id_low = (id1<<3)|4;
  can_filter_init_struct.filter_mask_high = mid1>>13;
  can_filter_init_struct.filter_mask_low = (mid1<<3)|4;
  can_filter_init(CAN1, &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>>13;
  can_filter_init_struct.filter_id_low = (id2<<3)|4;
  can_filter_init_struct.filter_mask_high = mid2>>13;
  can_filter_init_struct.filter_mask_low = (mid2<<3)|4;
  can_filter_init(CAN1, &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(&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);
    
  /* can baudrate, set boudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
  can_baudrate_struct.baudrate_div = velocity;  //16为500K  8//1M  32 //250K  64//125  80/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, &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<<5;
  can_filter_init_struct.filter_id_low = id2<<5;
  can_filter_init_struct.filter_mask_high = mid1<<5;
  can_filter_init_struct.filter_mask_low = mid2<<5;
  can_filter_init(CAN1, &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[7])*1000000+Check_Number(Cmd[8])*100000+Check_Number(Cmd[9])*10000+Check_Number(Cmd[10])*1000
                        +Check_Number(Cmd[11])*100+Check_Number(Cmd[12])*10+Check_Number(Cmd[13])));




    if (!strncmp((const char *)Cmd+4,"STD",3))
    {
        //配合上位机软件加入	  2016.10.09
        if((CotrolVale & 0x80) != 0x80)
        {
            ID1 = Check_Number(Cmd[45])<<8;
            ID1 |= Check_Number(Cmd[46])<<4;
            ID1 |= Check_Number(Cmd[47]);
            ID2 = Check_Number(Cmd[49])<<8;
            ID2 |= Check_Number(Cmd[50])<<4;
            ID2 |= Check_Number(Cmd[51]);
            MID1 = Check_Number(Cmd[53])<<8;
            MID1 |= Check_Number(Cmd[54])<<4;
            MID1 |= Check_Number(Cmd[55]);
            MID2 = Check_Number(Cmd[57])<<8;
            MID2 |= Check_Number(Cmd[58])<<4;
            MID2 |= Check_Number(Cmd[59]);
            if((CotrolVale & 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[19]);
        tx_message_struct.standard_id = (u32)Check_Number(Cmd[15])<<8;
        tx_message_struct.standard_id |= (u32)Check_Number(Cmd[16])<<4;
        tx_message_struct.standard_id |= (u32)Check_Number(Cmd[17]);
        for(i = 0; i < tx_message_struct.dlc; i++)
        {
            tx_message_struct.data[i] = (u8)Check_Number(Cmd[21+3*i])<<4;
            tx_message_struct.data[i] |= (u8)Check_Number(Cmd[22+3*i]);
        }
        if ((CotrolVale & 0x80) != 0x80)
        {
            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);
						CotrolVale = 0x10;
        }
    }
    else if (!strncmp((const char *)Cmd+4,"EXT",3))
    {
        //配合上位机软件加入	  2016.10.09
        if((CotrolVale & 0x80) != 0x80)
        {
            id1 = 0;
            id2 = 0;
            mid1 = 0;
            mid2 = 0;
            for (i = 0; i < 8; i++)
            {
                id1 |= Check_Number(Cmd[50+i])<<4*(7-i);
            }

            for (i = 0; i < 8; i++)
            {
                id2 |= Check_Number(Cmd[59+i])<<4*(7-i);
            }

            for (i = 0; i < 8; i++)
            {
                mid1 |= Check_Number(Cmd[68+i])<<4*(7-i);
            }

            for (i = 0; i < 8; i++)
            {
                mid2 |= Check_Number(Cmd[77+i])<<4*(7-i);
            }
            if((CotrolVale & 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[24]);
        for (i = 0; i < 8; i++)
        {
            tx_message_struct.extended_id |= (u32)Check_Number(Cmd[15+i])<<4*(7-i);
        }
        for(i = 0; i < tx_message_struct.dlc; i++)
        {
            tx_message_struct.data[i] = (u8)Check_Number(Cmd[26+3*i])<<4;
            tx_message_struct.data[i] |= (u8)Check_Number(Cmd[27+3*i]);
        }
        if ((CotrolVale & 0x80) != 0x80)
        {
            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);
						CotrolVale = 0x10;
        }
    }
}

更新主程序:

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

实验现象:

1、配置标准帧1M:

image.png  CAN分析仪设置为1M

image.png  发送数据:

image.png  设置扩张帧1M:

image.png  至此CAN转收发设置,收发全部调通。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复