前言
硬件说明:
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 协议发送接收
目录
第2章 CAN 2.0 ISO-15765 500K 2
-
电路图 2
-
例程说明 2
(1) 硬件连接 2 -
软件设计 2
(1) main主要流程 2
(2)can.c主要函数说明 3 -
PC平台效果 7
第2章 CAN 2.0 ISO-15765 500K
-
电路图
-
例程说明
(1) 硬件连接
用OBD 一分2线接上开发板与CAN 采集器,采集器设置波特率500K不过滤采样。
- 软件设计
CAN1 接单片机 PB8 PB9,500K波特率循环发送 CAN 标准帧扩展帧数据
(1) main主要流程
//初始化IO设置波特率can_configEx(can_500k);
//设置过滤器 CAN_setAllfit();//设置不过滤ID
//发送标准帧 SendISO15765Data(SendData,0xfc00);//15765 STCAN
//发送扩展帧 SendISO15765Data(SendData,0x18DB33F1);//15765 EXCAN
Main() 主要代码
can_configEx(can_500k);//500K 波特率
//CAN1_Config16BitFilter(0xFC00,0xFD00);//设置过滤ID
CAN_setAllfit();//设置不过滤ID
/* main loop */
while (1)
{
SendISO15765Data(SendData,0xfc00);//15765 STCAN
Delay_ms(100);
SendISO15765Data(SendData,0x18DB33F1);//15765 EXCAN
Delay_ms(100);
}
(2)can.c主要函数说明
1 初始化 can_configEx
void can_configEx(uint8_t speed)
{
can_parameter_struct CAN_InitSt;
can_gpio_config();//IO 初始化 PB8 PB9
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:使能自动重发 ENABLE
// 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;
//CAN_SILENT_MODE静默模式 用于监听总线数据 不发送显性位 当总线有多个节点时 可以选择这个模式
//波特率设置 总线时钟是60M
//BaudRate = APBCLK/BRP*(1+BS1+BS2)
//SamplePoint = ((1+BS1)/(1+BS1+BS2))*100%
CAN_InitSt.resync_jump_width=CANBAUD[speed][0];
CAN_InitSt.time_segment_1=CANBAUD[speed][1];
CAN_InitSt.time_segment_2=CANBAUD[speed][2];
CAN_InitSt.prescaler=CANBAUD[speed][3];//BAUD=60m/((1+6+1)*15) 87.5%
/* initialize CAN */
can_init(CAN0, &CAN_InitSt);
/* 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<iSum;i++)
{
id1=iBuffer[iCmt++];
id2=iBuffer[iCmt++];
id1=id1>>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 CAN2.0 发送命令 SendISO15765Data
//iCanId CAN ID ,已经移位的 FC00(7E0)
// 15765 标准帧
//cmdaddr[0]= 发送长度
//cmdaddr[1…] 发送的数据
//注: iCanId>0xFFFF 时为扩展帧
// 返回1 成功 返回 0 失败
u8 SendISO15765Data(u8 *cmdaddr,u32 iCanId) //
{
u32 i=0,tmp=0;
uint8_t TransmitMailbox=0;
u8 Stollen=cmdaddr[0]&0x0F;
if(Stollen==0) return 1;
if(Stollen>8) Stollen=8;
//初始化参数
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;
for(u8 Sidx = 0; Sidx < Stollen; Sidx ++)
{
TbufMege.tx_data[Sidx] = cmdaddr[Sidx+1];
}
can_transmit_state_enum iFlag;
TransmitMailbox=can_message_transmit(CAN0, &TbufMege);
// //判断是否发送成功
GetTimer6Cnt();//清空
i=0;
while(1)
{
i++;
iFlag=can_transmit_states(CAN0,TransmitMailbox);
if(iFlag==CAN_TRANSMIT_OK) break;//校验是否发送成功
if(i>0xFFFFFF) break;
tmp=GetTimer6CntEx();
if(tmp>1000*500) break;
}
return 1;
}
- PC平台效果
EcuSimulator 工具设置CAN2.0 500K不过滤,显示数据如下图所示
单片机源码地址
https://github.com/siyuan1644/GD32_CAN-2.0-ISO-15765.git
硬件地址
硬件地址