本帖最后由 小猪siyuan 于 2022-9-13 20:20 编辑
第2章 CAN 2.0 ISO-15765 500K1. 电路图file:///C:/Users/MENGSI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png 2. 例程说明
(1) 硬件连接用OBD 一分2线接上开发板与CAN 采集器,采集器设置波特率500K不过滤采样。
3. 软件设计 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);//15765STCAN Delay_ms(100); SendISO15765Data(SendData,0x18DB33F1);//15765EXCAN Delay_ms(100); } (2)can.c主要函数说明
1 初始化 can_configExvoid can_configEx(uint8_tspeed) { 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 emptyinterrupt */ can_interrupt_enable(CAN0,CAN_INTEN_RFNEIE0);//使能接收中断 } 2 设置过滤器CAN_setAllfit//不过滤ID voidCAN_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 bereceived */ CAN_FilterInitStructure.filter_mask_low =(uint16_t)0 ; can_filter_init(&CAN_FilterInitStructure); } 3 设置标准过滤器 CAN1_Config16BitFilter//标准帧过滤ID 设置 voidCAN1_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 bereceived */ CAN_FilterInitStructure.filter_mask_low =(uint16_t)id2 ; //掩码 can_filter_init(&CAN_FilterInitStructure); } 4 设置扩展过滤器CAN1_Config32BitFilterExList//列表模式下 有0~13 共14组 能过滤 28个扩展帧ID //iBuffer 29 位ID 缓冲区,iSumFiterID 个数 voidCAN1_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; /* configureSFID[10:0] */ CAN_FilterInitStructure.filter_list_high= (uint32_t)(id1>>13); CAN_FilterInitStructure.filter_list_low= (uint32_t)((id1<<3)|4); /* configureSFID[10:0] mask */ CAN_FilterInitStructure.filter_mask_high= (uint32_t)(id2>>13); /* both data andremote 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 失败 u8SendISO15765Data(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; }
4. PC平台效果 EcuSimulator 工具设置CAN2.0 500K不过滤,显示数据如下图所示 file:///C:/Users/MENGSI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png 源码地址
https://github.com/siyuan1644/GD32_CAN-2.0-ISO-15765.git
源码地址
|