
主从机can通讯stm32基于STM32的CAN总线温度检测节点 的硬件设计与制作。1个主节点3个从节点每个节点均包含STM32最小系统、CAN通信模块、温度采集模块能够稳定完成本地温度采集并通过CAN总线实现数据收发。1、CAN 总线CANController Area Network控制器局域网1983 年博世为汽车电子开发是差分串行通信总线多主仲裁、抗干扰强、实时性高广泛用于汽车、工业 PLC、嵌入式设备。 核心特点多主机、无主从区分差分信号抗 EMI硬件帧仲裁错误自动检测重传最远 10km 低速通信。本系统选取的是闭环CAN总线网络。特点高速、短距离它的总线最大长度为40m通信速度最高为1Mbps总线的两端各要求有一个120 欧的电阻。如下图所示2、CAN 模块CAN通信模块核心器件选用TJA1050 CAN收发器该器件支持5kbps至1Mbps波特率兼容CAN 2.0AB协议可将STM32内部CAN控制器的逻辑电平转换为总线差分信号提升抗干扰能力。其具备热保护、短路保护功能可避免总线故障损坏器件且体积小、功耗低适合节点模块化部署总线两端配置120Ω终端电阻抑制信号反射保障长距离传输稳定性。3、注意事项由于TJA1050 CAN收发器配置了120Ω终端电阻在连接TJA1050 硬件之前需要对其中两个TJA1050去掉120Ω终端电阻保证是闭环CAN总线网络这样信号传输就不会丢包。4、器件清单stm32f103c8t64TJA10504DS18B204BEEP3LED4电源模块1OLED 屏幕1按键模块25、主机原理图6、从机原理图7、主机代码#include stm32f10x.h // Device header #include Delay.h #include OLED.h #include Key.h #include MyCAN.h #include STDIO.h #include ds18b20.h #include LED.h uint8_t Keycount; uint8_t Keymode; uint32_t RxID; uint8_t RxLength; uint8_t RxData[8]; uint32_t TxID 0x111; uint8_t TxLength 8; uint8_t TxData[8] {0x00, 0x00, 0x00}; float TA; float TB; float TC; float TD; char TA_buf[10]; char TB_buf[10]; char TC_buf[10]; char TD_buf[10]; uint8_t TA_s 30; uint8_t TB_s 30; uint8_t TC_s 30; uint8_t TD_s 30; void SHOW(void) { OLED_ShowString(1, 1, A:); OLED_ShowString(2, 1, B:); OLED_ShowString(3, 1, C:); OLED_ShowString(4, 1, D:); if(TA TA_s) OLED_ShowString(1,10,warning); else OLED_ShowString(1,10,normal ); if(TB TB_s) OLED_ShowString(2,10,warning); else OLED_ShowString(2,10,normal ); if(TC TC_s) OLED_ShowString(3,10,warning); else OLED_ShowString(3,10,normal ); if(TD TD_s) OLED_ShowString(4,10,warning); else OLED_ShowString(4,10,normal ); } float temp_data; float temp_data1[1]; int main(void) { OLED_Init(); Key_Init(); MyCAN_Init(); OLED_Clear(); DS18B20_Init(); BEEP_Init(); LED_Init(); while (1) { Keycount Key_GetNum(); if(Keycount 1){ OLED_Clear(); Keymode; if(Keymode4)Keymode 0; } if(Keymode0) { SHOW(); TD(float)DS18B20_Get_Temp()/10.0f; TxData[0] TA_s; TxData[1] TB_s; TxData[2] TC_s; MyCAN_Transmit(0X111, TxLength,TxData); MyCAN_Transmit(0X222, TxLength,TxData); MyCAN_Transmit(0X333, TxLength,TxData); if(TD (float)TD_s){ LED_ON();BEEP_ON(); Delay_ms(10); } else{ LED_OFF();BEEP_OFF(); Delay_ms(10); } if (MyCAN_ReceiveFlag()) { MyCAN_Receive(RxID, RxLength, RxData); if(RxID 0x111)//从机A TA RxData[0] *10 RxData[1] (float)RxData[2]*0.1; if(RxID 0x222)//从机B TB RxData[0] *10 RxData[1] (float)RxData[2]*0.1; if(RxID 0x333)//从机C TC RxData[0] *10 RxData[1] (float)RxData[2]*0.1; sprintf(TA_buf,%.1fC,TA);OLED_ShowString(1,3,TA_buf); Delay_ms(2); sprintf(TB_buf,%.1fC,TB);OLED_ShowString(2,3,TB_buf); Delay_ms(2); sprintf(TC_buf,%.1fC,TC);OLED_ShowString(3,3,TC_buf); Delay_ms(2); sprintf(TD_buf,%.1fC,TD);OLED_ShowString(4,3,TD_buf); Delay_ms(2); } } Delay_ms(2); if(Keymode0) { OLED_ShowString(1,3,TA_H:); OLED_ShowString(2,3,TB_H:); OLED_ShowString(3,3,TC_H:); OLED_ShowString(4,3,TD_H:); OLED_ShowNum(1,8,TA_s ,2); OLED_ShowNum(2,8,TB_s ,2); OLED_ShowNum(3,8,TC_s ,2); OLED_ShowNum(4,8,TD_s ,2); } if(Keymode1) { OLED_ShowString(1,11,); if(Keycount 2){ TA_s; if(TA_s40)TA_s20;} } if(Keymode2) { OLED_ShowString(2,11,); if(Keycount 2){ TB_s; if(TB_s40)TB_s20;} } if(Keymode3) { OLED_ShowString(3,11,); if(Keycount 2){ TC_s; if(TC_s40)TC_s20;} } if(Keymode4) { OLED_ShowString(4,11,); if(Keycount 2){ TD_s; if(TD_s40)TD_s20;} } } }8、从机代码下面是从机A代码。从机B、C、D代码只需将CAN的ID改成不同的即可。#include stm32f10x.h // Device header #include Delay.h #include LED.h #include MyCAN.h #include ds18b20.h #include stdio.h #include stdlib.h uint32_t RxID; uint8_t RxLength; uint8_t RxData[8]; uint32_t TxID 0x222; uint8_t TxLength 8; uint8_t TxData[8] {0x00, 0x00, 0x00}; int Ttens, Tunits, Tdecimal; float temp_data; float temp_data1[1]; int temp_data_H; void extract_digits(float num, int *tens, int *units, int *decimal) { float abs_num (num 0) ? -num : num; int scaled (int)(abs_num * 10.0f 0.5f); *decimal scaled % 10; // 小数位 *units (scaled / 10) % 10; // 个位 *tens (scaled / 100) % 10; // 十位 } int main(void) { DS18B20_Init(); LED_Init(); BEEP_Init(); MyCAN_Init(); while (1) { temp_data(float)DS18B20_Get_Temp()/10.0f; if(temp_data temp_data_H){ LED_ON();BEEP_ON(); Delay_ms(10); } else{ LED_OFF();BEEP_OFF(); Delay_ms(10); } temp_data1[0]temp_data; extract_digits(temp_data1[0], Ttens, Tunits, Tdecimal); TxData[0] Ttens; TxData[1] Tunits; TxData[2] Tdecimal; MyCAN_Transmit(TxID, TxLength,TxData); if (MyCAN_ReceiveFlag()) { MyCAN_Receive(RxID, RxLength, RxData); if(RxID 0x222)//从机A { temp_data_H RxData[1]; } } Delay_ms(100); } }9、实物图指导如果需要全套源码器件清单、含原理图、pcb文件、代码可以搜上面的号