当前位置: 首页 > news >正文

基于STM32F105系列使用CAN总线实现双机通信代码

基于STM32F105系列使用CAN总线实现双机通信代码,包含初始化、发送和接收功能。这里使用标准外设库,并假设使用CAN1。

1. CAN总线初始化

#include"stm32f10x.h"#include"stm32f10x_can.h"#include"stm32f10x_gpio.h"#include"stm32f10x_rcc.h"#include"misc.h"// CAN初始化结构体CAN_InitTypeDef CAN_InitStructure;CAN_FilterInitTypeDef CAN_FilterInitStructure;CanTxMsg TxMessage;CanRxMsg RxMessage;voidCAN_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIO和CAN时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);// 配置CAN引脚: PA11->RX, PA12->TXGPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;// TXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;// 推挽复用输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;// RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;// 上拉输入GPIO_Init(GPIOA,&GPIO_InitStructure);}voidCAN_NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;// 配置CAN接收中断NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);}voidCAN_Mode_Config(void){CAN_DeInit(CAN1);CAN_StructInit(&CAN_InitStructure);// CAN工作模式配置CAN_InitStructure.CAN_TTCM=DISABLE;// 禁止时间触发通信模式CAN_InitStructure.CAN_ABOM=DISABLE;// 禁止自动离线管理CAN_InitStructure.CAN_AWUM=DISABLE;// 禁止自动唤醒模式CAN_InitStructure.CAN_NART=DISABLE;// 禁止自动重传CAN_InitStructure.CAN_RFLM=DISABLE;// 禁止FIFO锁定CAN_InitStructure.CAN_TXFP=DISABLE;// 禁止发送FIFO优先级// 配置波特率// CAN波特率 = APB1时钟 / ((CAN_BS1 + CAN_BS2 + 1) * CAN_Prescaler)// 假设APB1时钟为36MHz,波特率设为500kbpsCAN_InitStructure.CAN_BS1=CAN_BS1_9tq;// 时间段1CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;// 时间段2CAN_InitStructure.CAN_Prescaler=6;// 分频系数// 总时间片 = 1 + 9 + 4 = 14// 波特率 = 36MHz / (14 * 6) = 428.57kHz (接近500k)CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;// 正常工作模式CAN_Init(CAN1,&CAN_InitStructure);// 配置CAN过滤器CAN_FilterInitStructure.CAN_FilterNumber=0;// 使用过滤器0CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;// 掩码模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;// 32位模式CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 要过滤的ID高位CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;// 要过滤的ID低位CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;// 掩码高位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;// 掩码低位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 关联到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 启用过滤器CAN_FilterInit(&CAN_FilterInitStructure);// 使能CAN接收中断CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);}

2. CAN数据发送函数

uint8_tCAN_Send_Msg(uint8_t*msg,uint8_tlen,uint32_tid){uint8_ti=0;uint8_ttransmit_mailbox=0;TxMessage.StdId=id;// 标准IDTxMessage.ExtId=0x00;// 扩展IDTxMessage.IDE=CAN_Id_Standard;// 标准帧TxMessage.RTR=CAN_RTR_Data;// 数据帧TxMessage.DLC=len;// 数据长度(最大8字节)// 填充数据for(i=0;i<len;i++){TxMessage.Data[i]=msg[i];}// 发送数据transmit_mailbox=CAN_Transmit(CAN1,&TxMessage);// 等待发送完成i=0;while((CAN_TransmitStatus(CAN1,transmit_mailbox)!=CANTXOK)&&(i<0xFF)){i++;}if(i>=0xFF){return1;// 发送失败}return0;// 发送成功}

3. CAN数据接收中断服务函数

voidUSB_LP_CAN1_RX0_IRQHandler(void){staticuint8_treceive_buffer[8];if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!=RESET){// 读取接收到的数据CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);// 清除中断标志CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);// 处理接收到的数据if(RxMessage.IDE==CAN_Id_Standard){uint8_ti;// 复制接收到的数据for(i=0;i<RxMessage.DLC;i++){receive_buffer[i]=RxMessage.Data[i];}// 在这里处理接收到的数据// 例如:将数据发送到串口或进行其他处理// Process_Received_Data(receive_buffer, RxMessage.DLC, RxMessage.StdId);}}}

4. 主函数示例

intmain(void){uint8_tsend_data[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};uint32_tmessage_id=0x123;// CAN消息ID// 初始化系统时钟SystemInit();// 配置GPIOCAN_GPIO_Config();// 配置NVIC中断CAN_NVIC_Config();// 配置CAN模式CAN_Mode_Config();// 主循环while(1){// 每隔1秒发送一次数据Delay(1000);// 自定义延时函数// 发送CAN消息CAN_Send_Msg(send_data,8,message_id);// 可以在这里添加其他处理逻辑}}

参考代码 stm32f105系列使用can总线实现双机通信源代码www.youwenfan.com/contentcsv/70917.html

5. 双机通信配置说明

设备A配置(发送设备):

// 设置设备A的ID为0x100uint32_tdevice_a_id=0x100;

设备B配置(接收设备):

// 配置过滤器只接收来自设备A的消息CAN_FilterInitStructure.CAN_FilterIdHigh=0x0100<<5;// ID高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;// ID低16位CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;// 掩码高位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;// 掩码低位

6. 完整的工程配置步骤

  1. 硬件连接

    • CAN_H 连接 CAN_H
    • CAN_L 连接 CAN_L
    • 两个设备的GND相连
    • 在总线的两端接120Ω终端电阻
  2. 软件配置

    // 波特率计算// 假设系统时钟为72MHz,APB1时钟为36MHz// 500kbps配置:BS1=9, BS2=4, Prescaler=6// 1Mbps配置:BS1=9, BS2=4, Prescaler=3
  3. 编译和下载

    • 使用Keil MDK或STM32CubeIDE
    • 确保包含正确的头文件
    • 配置正确的系统时钟

注意事项

  1. 终端电阻:必须在CAN总线的两端各接一个120Ω的终端电阻
  2. 波特率:两个设备的波特率必须相同
  3. 中断优先级:根据实际应用需求合理配置中断优先级
  4. 错误处理:在实际应用中应添加错误检测和重发机制
  5. ID冲突:确保每个设备的CAN ID唯一,避免冲突
http://www.jsqmd.com/news/855358/

相关文章:

  • eNSP实验避坑指南:华为路由器IP地址配完却Ping不通?这5个细节检查了吗?
  • 2026年Q2广州宠物犬舍猫舍评测:四家连锁机构深度对比 - 优质品牌商家
  • 告别理论!用Python可视化带你彻底搞懂电机插补算法(逐点比较法)
  • 从零搭建企业级网络准入:用Agile Controller-Campus + 华为交换机实战802.1X认证
  • RK3588工业一体机:异构计算、AI推理与Linux系统构建实战
  • 2026年工业门应用白皮书:兰州工业提升门/兰州工业滑升门/兰州工业翻板门/兰州工业车间门/兰州工业钢木门/兰州工业钢质门/选择指南 - 优质品牌商家
  • 2026嵌入式晾衣架实测评测:落地晾衣架、语音晾衣架、遥控晾衣机、阳台晾衣架、隐藏式晾衣架、伸缩晾衣架、全自动晾衣架选择指南 - 优质品牌商家
  • SAP-ABAP:数据类型与数据对象(8篇) 第七篇:进阶优化篇——基于类型与对象特征的性能优化技巧
  • 从Matlab仿真到上板验证:手把手完成Xilinx DDS多项数据生成的全流程
  • HarmonyOS 图片缩放没想象中简单——detailEnhance 四档质量深度解析
  • 告别理论推导!用Python+NumPy手撸一个卡尔曼滤波器(附AR序列预测完整代码)
  • 从‘Hello World’到自主导航:一个ROS1节点的完整生命周期与调试指令全记录
  • 别再乱调JVM堆大小了!Elasticsearch内存配置的5个实战避坑点
  • LabVIEW事件驱动状态机:从原理到实战的混合编程架构解析
  • 2026四川全屋定制打印机实力厂家排行及地址汇总:高温彩釉打印机/700度高温烧结打印机/uv光油墨水/排行一览 - 优质品牌商家
  • 双目立体视觉实战:SAD、SSD与SGBM算法原理与OpenCV调优指南
  • STC8H的PWM除了调光还能干啥?一个呼吸灯代码带你窥探电机控制与信号捕获
  • 数字化转型最大的谎言:上了低代码就能“降本增效”?
  • 2026届必备的十大降重复率平台解析与推荐
  • MyBatis 执行流程与延迟加载原理
  • 3岁孩子能不能喝花姐八珍粉?怎么控制用量?
  • SAP-ABAP:数据类型与数据对象(8篇) 第八篇:误区避坑篇——数据类型与对象操作的常见误区解析
  • 别再一个个置位了!博图PLC编程效率翻倍:SET_BF指令结合ARRAY的进阶玩法
  • FreeRTOS信号量实战:从同步互斥原理到嵌入式并发编程避坑指南
  • EtherCAT SDO通信慢?深入解析IgH主站的非实时读写机制与优化思路
  • 内存进化史:从SDRAM的‘单车道’到DDR的‘双车道’,聊聊那些被砍掉的功能(如全页突发)
  • 避坑指南:在UE里用蓝图做传送门,Actor旋转、碰撞检测这些细节千万别踩坑
  • eclipse数值模拟器并行计算
  • 保姆级教程:在Ubuntu 20.04上从零复现M3DM多模态异常检测(含DINO+Point_MAE权重)
  • 除了ModHeader,还有哪些HTTP头修改插件?离线安装全攻略与横向评测