【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: