CAN_FD_500K_5M_83.3%
硬件说明:
MCU: GD32C103 120M,128K,32k RAM.
输入:USB 5V.
OBD功能口定义:OBD(2,10)VPWM、OBD 7(K线)、OBD 6(CAN H)、OBD 14(CAN L)、OBD 15(L线).
软件说明:
一、汽车CAN2.0(双线OBD 6、14)
1、支持波特率:1M、800K、500K、250K、125K、100K、62K、50K、33.3K、25K
二、汽车CAN FD(双线OBD 6、14)
1、仲裁区波特率:1M、500K
2、数据区波特率5M 4M 2M 1M
三、汽车KWP/LIN(OBD 7)总线数据采集说明
1、波特率:5、4800、9600、10416、57600、115200 BPS
三、SAE J1850(OBD 2、10)
1、PWM 协议发送接收
2、VPW 协议发送接收
3.软件设计
CAN1 接单片机 PB8 PB9,500K_5M波特率循环发送 CAN 标准帧扩展帧数据
(1)main主要流程
//初始化IO设置波特率CanFD_config(can_500k,Data_5M);//CAN FD 500k 5M ;
//设置过滤器 CAN_setAllfit();//设置不过滤ID
//canfd发送标准帧 CanFdSendISO15765Data(SendData,0xfc00);//15765 STCAN
//canfd发送扩展帧 CanFdSendISO15765Data(SendData,0x18DB33F1);//15765 EXCAN
Main() 主要代码
uint8_t SendData[10]={0x08,0X02,0X10,0x03,0x00,0x00,0x00,0x00,0x00};
uint8_t SendData1[100]={0x09,0X02,0X10,0x03,0x00,0x00,0x00,0x00,0x00};
CanFD_config(can_500k,Data_5M);//CAN FD 500k 5M
//CAN1_Config16BitFilter(0xFC00,0xFD00);//设置过滤ID
CAN_setAllfit();//设置不过滤ID
/* main loop */
while (1)
{
CanFdSendISO15765Data(SendData,0xfc00);//15765 STCAN 标准帧
Delay_ms(100);
CanFdSendISO15765Data(SendData,0x18DB33F1);//15765 EXCAN 扩展帧
Delay_ms(100);
for(i=0;i<0x10;i++)//循环发送 长度0~64 字节的数据
{
SendData1[0]=i;//长度改变
SendData1[1]=i;
CanFdSendISO15765Data(SendData1,0xfd00);// STCAN 变长度 验证CAN FD
Delay_ms(100);
}
}
(2)can.c主要函数说明
1 初始化 CanFD_config
//speed1 仲裁去波特率
//speed2 数据区波特率
void CanFD_config(uint8_t speed1,uint8_t speed2)
{
can_parameter_struct CAN_InitSt;
can_fdframe_struct can_fd_parameter; //CAN FD 参数
can_fd_tdc_struct can_fd_tdc_parameter;//
//GPIO
can_gpio_config();
can_struct_para_init(CAN_INIT_STRUCT, &CAN_InitSt);
/* initialize CAN register */
can_deinit(CAN0);
/* initialize CAN parameters */
CAN_InitSt.time_triggered = DISABLE;
CAN_InitSt.auto_bus_off_recovery = DISABLE;
CAN_InitSt.auto_wake_up = DISABLE;
// 0:使能自动重发
// 1:禁用自动重发
CAN_InitSt.auto_retrans = ENABLE;//报文自动传输 是否开启
CAN_InitSt.rec_fifo_overwrite = DISABLE;
CAN_InitSt.trans_fifo_order = DISABLE;
CAN_InitSt.working_mode = CAN_NORMAL_MODE;
//speed1 仲裁区波特率
CAN_InitSt.resync_jump_width=CANBAUD[speed1][0];
CAN_InitSt.time_segment_1=CANBAUD[speed1][1];
CAN_InitSt.time_segment_2=CANBAUD[speed1][2];
CAN_InitSt.prescaler=CANBAUD[speed1][3];//BAUD=60m/((1+6+1)*15) 87.5%
/* initialize CAN */
can_init(CAN0, &CAN_InitSt);
//can_frequency_set(CAN0, DEV_CAN_BAUD_RATE);
//数据区 初始化
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
can_fd_parameter.fd_frame = ENABLE;
can_fd_parameter.excp_event_detect = ENABLE;
can_fd_parameter.delay_compensation = ENABLE;
can_fd_tdc_parameter.tdc_filter = 0x04;
can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;
can_fd_tdc_parameter.tdc_offset = 0x04;
can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;
can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;
can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;
//数据区波特率设置
can_fd_parameter.data_resync_jump_width=CANBAUD_data[speed2][0];
can_fd_parameter.data_time_segment_1=CANBAUD_data[speed2][1];
can_fd_parameter.data_time_segment_2=CANBAUD_data[speed2][2];
can_fd_parameter.data_prescaler=CANBAUD_data[speed2][3];//BAUD=60m/((1+6+1)*15)
can_fd_init(CAN0, &can_fd_parameter);
//can_fd_frequency_set(CAN0, 5000000);//1M 自动波特率函数
/* configure CAN0 NVIC /
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
/ enable can receive FIFO0 not empty interrupt */
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
}
2 设置过滤器CAN_setAllfit
//不过滤ID
void CAN_setAllfit(void)
{
can_filter_parameter_struct CAN_FilterInitStructure;
can_struct_para_init(CAN_FILTER_STRUCT, &CAN_FilterInitStructure);
CAN_FilterInitStructure.filter_number = 0;
CAN_FilterInitStructure.filter_mode = CAN_FILTERMODE_MASK;
CAN_FilterInitStructure.filter_bits = CAN_FILTERBITS_32BIT;
CAN_FilterInitStructure.filter_enable = ENABLE;
CAN_FilterInitStructure.filter_fifo_number = CAN_FIFO0;
/* configure SFID[10:0] */
CAN_FilterInitStructure.filter_list_high = (uint16_t)0 ;
CAN_FilterInitStructure.filter_list_low = (uint16_t)0;
/* configure SFID[10:0] mask */
CAN_FilterInitStructure.filter_mask_high = (uint16_t)0;
/* both data and remote frames can be received */
CAN_FilterInitStructure.filter_mask_low = (uint16_t)0 ;
can_filter_init(&CAN_FilterInitStructure);
}
3 设置标准过滤器 CAN1_Config16BitFilter
//标准帧过滤ID 设置
void CAN1_Config16BitFilter(u16 id1, u16 id2)
{
can_filter_parameter_struct CAN_FilterInitStructure;
can_struct_para_init(CAN_FILTER_STRUCT, &CAN_FilterInitStructure);
CAN_FilterInitStructure.filter_number = 0;//过滤器组
CAN_FilterInitStructure.filter_mode = CAN_FILTERMODE_LIST;//列表模式
CAN_FilterInitStructure.filter_bits = CAN_FILTERBITS_16BIT;//16位ID 模式
CAN_FilterInitStructure.filter_enable = ENABLE;
CAN_FilterInitStructure.filter_fifo_number = CAN_FIFO0;
/* configure SFID[10:0] */
CAN_FilterInitStructure.filter_list_high = (uint16_t)id1 ;//ID
CAN_FilterInitStructure.filter_list_low = (uint16_t)id2;//ID
/* configure SFID[10:0] mask */
CAN_FilterInitStructure.filter_mask_high = (uint16_t)id1;//掩码
/* both data and remote frames can be received */
CAN_FilterInitStructure.filter_mask_low = (uint16_t)id2 ; //掩码
can_filter_init(&CAN_FilterInitStructure);
}
4 设置扩展过滤器 CAN1_Config32BitFilterExList
//列表模式下 有0~13 共14组 能过滤 28个扩展帧ID
//iBuffer 29 位ID 缓冲区,iSumFiter ID 个数
void CAN1_Config32BitFilterExList(u32 *iBuffer,u8 iSumFiter)
{
u32 id1=0,id2=0;
u8 i=0,iCmt=0,iSum=0;
can_filter_parameter_struct CAN_FilterInitStructure;
iSum=iSumFiter/2;
if(iSumFiter%2)
{
iSum+=1;
}
for(i=0;i>3;
id2=id2>>3;
if(id1==0) id1=0xffffffff;
if(id2==0) id2=0xffffffff;
can_struct_para_init(CAN_FILTER_STRUCT, &CAN_FilterInitStructure);
CAN_FilterInitStructure.filter_number = i;
CAN_FilterInitStructure.filter_mode = CAN_FILTERMODE_LIST;
CAN_FilterInitStructure.filter_bits = CAN_FILTERBITS_32BIT;
CAN_FilterInitStructure.filter_enable = ENABLE;
CAN_FilterInitStructure.filter_fifo_number = CAN_FIFO0;
/* configure SFID[10:0] */
CAN_FilterInitStructure.filter_list_high = (uint32_t)(id1>>13);
CAN_FilterInitStructure.filter_list_low = (uint32_t)((id1<<3)|4);
/* configure SFID[10:0] mask */
CAN_FilterInitStructure.filter_mask_high = (uint32_t)(id2>>13);
/* both data and remote frames can be received */
CAN_FilterInitStructure.filter_mask_low = (uint32_t)((id2<<3)|4);
can_filter_init(&CAN_FilterInitStructure);
}
}
5 CANFD发送命令 CanFdSendISO15765Data
//iCanId CAN ID ,已经移位的 FC00(7E0)
// 15765 标准帧
//cmdaddr[0]= 发送长度
//cmdaddr[1…] 发送的数据
//注: iCanId>0xFFFF 时为扩展帧
//CAN FD 协议 数据长度 1~8,12 16,20,24,32,48,64 最大长度是64,但并不能1~64 之间的任意长度
// 返回1 成功 返回 0 失败
u8 CanFdSendISO15765Data(u8 *cmdaddr,u32 iCanId) //
{
u32 i=0;
uint8_t TransmitMailbox=0;
u8 Stollen=GetFdCanLen(cmdaddr[0]&0x0F);//CAN FD 长度
//初始化参数
can_trasnmit_message_struct TbufMege;
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &TbufMege);
if(iCanId>0xFFFF)//扩展帧
{
TbufMege.tx_sfid = 0;
TbufMege.tx_efid = iCanId/0X08;
TbufMege.tx_ff = CAN_FF_EXTENDED;//
}
else
{
TbufMege.tx_sfid = iCanId/0X20;
TbufMege.tx_efid = 0x00;
TbufMege.tx_ff = CAN_FF_STANDARD;
}
TbufMege.tx_ft = CAN_FT_DATA;//数据帧
TbufMege.tx_dlen = Stollen;//帧长度
TbufMege.fd_flag = CAN_FDF_FDFRAME;//CAN FD
TbufMege.fd_brs = CAN_BRS_ENABLE;//波特率切换
TbufMege.fd_esi = CAN_ESI_DOMINANT;//CAN_ESI_DOMINANT;//;
for(u8 Sidx = 0; Sidx < Stollen; Sidx ++)
{
TbufMege.tx_data[Sidx] = cmdaddr[Sidx+1];
}
u8 flag=0;
//can_transmit_state_enum iFlag;
TransmitMailbox=can_message_transmit(CAN0, &TbufMege);
while(1)
{
flag=can_transmit_states(CAN0,TransmitMailbox);
if(flag==CAN_TRANSMIT_OK) break;
if(i>250)
{//
i=0;
break;
}
Delay_us(1);
i++;
}
return 1;//
}
4.PC平台效果
EcuSimulator 工具设置CANFD 500K ,5M_83% 不过滤,显示数据如下图所示
源码地址
https://github.com/siyuan1644/GD32_CANFD_500K_5M.git
硬件地址
单片机源码地址