硬件部分已经有了,主要是看你的传感器支持的通讯协议是哪一种,还有就是到那个地址去读传感器的数据 |
发代码的哥们是真的顶 |
Ww10W 发表于 2020-7-11 09:44 modbus协议主要是规定了你发送数据的格式,比如说字符串第一个字节代表通信设备的地址 第二个字节表示功能代码或者寄存器地址……,参考网上的程序和modbus协议封装成函数就可以 |
// 以前做的8路温度模块RS485接口modbus协议 // 部分主要程序,小鬼子的芯片,485部分可以参考 unsigned char send_i=0; unsigned char send_j=0; unsigned char recv_ok; //接收完成标志 unsigned char ADDR_s1; //本机地址 unsigned int CRC_data; //CRC计算存放值 unsigned char com_count; //接收计数器 unsigned char tx_count; //发送指针计数器 unsigned char count_all; //接收总字节数 unsigned char send_count; //发送计数器 unsigned char load_count; unsigned char send_data[32]; //发送缓冲区 unsigned int ram_data[8]; //RAM变量 ram_data[1]:状态标志 // ram_data[16](0x10):控制 // ram_data[17](0x11): // ram_data[18](0x12):静音标志 unsigned int recv_data[16]; //接收缓存区 const unsigned int crc_table[] = /* CRC 值表*/ { 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741, 0x0500,0xC5C1,0xC481,0x0440,0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40, 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,0xD801,0x18C0,0x1980,0xD941, 0x1B00,0xDBC1,0xDA81,0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41, 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341, 0x1100,0xD1C1,0xD081,0x1040,0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240, 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,0x3C00,0xFCC1,0xFD81,0x3D40, 0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840, 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,0xEE01,0x2EC0,0x2F80,0xEF41, 0x2D00,0xEDC1,0xEC81,0x2C40,0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640, 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,0xA001,0x60C0,0x6180,0xA141, 0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441, 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41, 0x6900,0xA9C1,0xA881,0x6840,0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41, 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,0xB401,0x74C0,0x7580,0xB541, 0x7700,0xB7C1,0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041, 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741, 0x5500,0x95C1,0x9481,0x5440,0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40, 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,0x8801,0x48C0,0x4980,0x8941, 0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41, 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341, 0x4100,0x81C1,0x8081,0x4040 }; void init_UART0(void); void com_recv(void); void CRC_byte(unsigned char byte); //一个字节CRC void main(void) { unsigned char k; asm("FCLR I"); //关中断 /*****起动外部晶振*****/ prc0=1; //关保护 cm13=1; //开外晶振 cm15=1; //驱动为高 cm05=0; //外晶振振荡 cm16=0; //不分频 cm17=0; cm06=0; //不分频 asm("nop"); asm("nop"); asm("nop"); asm("nop"); ocd0=0; //不检失效 ocd1=0; //失效不中断 ocd2=0; //选择外部晶振 prc0=0; //保护 wdc7=0; //设置看门狗定时器频率为 f(Xin)/16 prc1=1; //关保护 pm0=0; pm1=0x04; //WDT溢出复位 prc1=0; //开保护 wdc7=1; //设置看门狗定时器频率为 f(Xin)/128 prc1=1; //关保护 pm0=0; pm1=0x04; //WDT溢出复位 prc1=0; //开保护 asm("FSET I"); //开中断 /*******初始化IO*******/ p1=0xc0; pd1=0xc0; // P1_6--P1_7为输出 p2=0x00; // pd2=0xff; // P2口为输出 //pur0|=0x38; // P2口上拉,P1.4-P1.7上拉 p3=0xFF; pd3|=0x38; // P3_3--P3_5为输出 time1=255; count_ad=10; recv_ok=0; CRC_data=0xffff;//CRC初值 com_count=0; ADDR_s1=0x03; //地址03 /**********************/ //read_set_data(); // 读出EEPROM数据 init_AD(); //初始化 init_RA(); //2ms init_UART0(); wdts=0; //启动看门狗 while(1) { // 1 温度计算 if(buffer_flg!=0) { Array_Sort(temp_buffer1,8);// 通道1 8点排序 for(k=2;k<6;k++) { temp_sum1+=temp_buffer1[k];//中间4点求和 } Array_Sort(temp_buffer2,8);// 通道2 8点排序 for(k=2;k<6;k++) { temp_sum2+=temp_buffer2[k]; } Array_Sort(temp_buffer3,8);// 通道3 8点排序 for(k=2;k<6;k++) { temp_sum3+=temp_buffer3[k]; } Array_Sort(temp_buffer4,8);// 通道4 8点排序 for(k=2;k<6;k++) { temp_sum4+=temp_buffer4[k]; } Array_Sort(temp_buffer5,8);// 通道5 8点排序 for(k=2;k<6;k++) { temp_sum5+=temp_buffer5[k]; } Array_Sort(temp_buffer6,8);// 通道6 8点排序 for(k=2;k<6;k++) { temp_sum6+=temp_buffer6[k]; } Array_Sort(temp_buffer7,8);// 通道7 8点排序 for(k=2;k<6;k++) { temp_sum7+=temp_buffer7[k]; } Array_Sort(temp_buffer8,8);// 通道8 8点排序 for(k=2;k<6;k++) { temp_sum8+=temp_buffer8[k]; } buffer_flg=0; temp_sum1=temp_sum1>>2; //4点求平均 temp_sum2=temp_sum2>>2; temp_sum3=temp_sum3>>2; temp_sum4=temp_sum4>>2; temp_sum5=temp_sum5>>2; temp_sum6=temp_sum6>>2; temp_sum7=temp_sum7>>2; temp_sum8=temp_sum8>>2; /* temp_sum1=0x1b2; //4点求平均 temp_sum2=0x1b0; temp_sum3=0x1b7; temp_sum4=0x1b7; temp_sum5=0x1b7; temp_sum6=0x1b7; temp_sum7=0x1b7; temp_sum8=0x1b7; */ view_sum1[count_Vsum]=temp_sum1*49; temp_sum1=0; view_sum2[count_Vsum]=temp_sum2*49; temp_sum2=0; view_sum3[count_Vsum]=temp_sum3*49; temp_sum3=0; view_sum4[count_Vsum]=temp_sum4*49; temp_sum4=0; view_sum5[count_Vsum]=temp_sum5*49; temp_sum5=0; view_sum6[count_Vsum]=temp_sum6*49; temp_sum6=0; /* view_sum7[count_Vsum]=18220; // 24度 temp_sum7=0; view_sum8[count_Vsum]=18220; temp_sum8=0; */ view_sum7[count_Vsum]=temp_sum7*49; temp_sum7=0; view_sum8[count_Vsum]=temp_sum8*49; temp_sum8=0; if(count_Vsum>2) { count_Vsum=0; //1 for(k=0;k<4;k++) { temp_sum1+= view_sum1[k]; //电压值的累加和 } temp_sum1=temp_sum1>>2; if(temp_sum1<21000) //正的温度 { temp_sum1=(21000-temp_sum1)/11; //设步进为11mV if((temp_sum1%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view1=temp_sum1/10; } else { tmpe_view1=temp_sum1/10; if(tmpe_view1!=0) tmpe_view1--; //减1 } temp_sum1=0; } else //负的温度 { temp_sum1=(temp_sum1-21000)/11; //设步进为11mV if((temp_sum1%10)>4) { //tmpe_view1=(temp_sum1/10)|0xff00;//加符号位 tmpe_view1=temp_sum1/10; tmpe_view1=tmpe_view1|0xff00; } else { //tmpe_view1=(temp_sum1/10-1)|0x10;//加符号位 tmpe_view1=temp_sum1/10; if(tmpe_view1!=0) { tmpe_view1--; //减1 tmpe_view1=tmpe_view1|0xff00; } } temp_sum1=0; } //2 for(k=0;k<4;k++) { temp_sum2+= view_sum2[k]; //电压值的累加和 } temp_sum2=temp_sum2>>2; if(temp_sum2<21000) { temp_sum2=(21000-temp_sum2)/11; //设步进为11mV if((temp_sum2%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view2=temp_sum2/10; } else { tmpe_view2=temp_sum2/10; if(tmpe_view2!=0) tmpe_view2--; //减1 } temp_sum2=0; } else { temp_sum2=(temp_sum2-21000)/11; //设步进为11mV if((temp_sum2%10)>4) { //tmpe_view2=(temp_sum2/10)|0xff00;//加符号位 tmpe_view2=temp_sum2/10; tmpe_view2=tmpe_view2|0xff00; } else { tmpe_view2=temp_sum2/10; if(tmpe_view2!=0) { tmpe_view2--; //减1 tmpe_view2=tmpe_view2|0xff00; } } temp_sum2=0; } //3 for(k=0;k<4;k++) { temp_sum3+= view_sum3[k]; //电压值的累加和 } temp_sum3=temp_sum3>>2; if(temp_sum3<21000) { temp_sum3=(21000-temp_sum3)/11; //设步进为11mV if((temp_sum3%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view3=temp_sum3/10; } else { tmpe_view3=temp_sum3/10; if(tmpe_view3!=0) tmpe_view3--; //减1 } temp_sum3=0; } else { temp_sum3=(temp_sum3-21000)/11; //设步进为11mV if((temp_sum3%10)>4) { //tmpe_view3=(temp_sum3/10)|0xff00;//加符号位 tmpe_view3=temp_sum3/10; tmpe_view3=tmpe_view3|0xff00; } else { tmpe_view3=temp_sum3/10; if(tmpe_view3!=0) { tmpe_view3--; //减1 tmpe_view3=tmpe_view3|0xff00; } } temp_sum3=0; } //4 for(k=0;k<4;k++) { temp_sum4+= view_sum4[k]; //电压值的累加和 } temp_sum4=temp_sum4>>2; if(temp_sum4<21000) { temp_sum4=(21000-temp_sum4)/11; //设步进为11mV if((temp_sum4%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view4=temp_sum4/10; } else { tmpe_view4=temp_sum4/10; if(tmpe_view4!=0) tmpe_view4--; //减1 } temp_sum4=0; } else { temp_sum4=(temp_sum4-21000)/11; //设步进为11mV if((temp_sum4%10)>4) { //tmpe_view4=(temp_sum4/10)|0xff00;//加符号位 tmpe_view4=temp_sum4/10; tmpe_view4=tmpe_view4|0xff00; } else { tmpe_view4=temp_sum4/10; if(tmpe_view4!=0) { tmpe_view4--; //减1 tmpe_view4=tmpe_view4|0xff00; } } temp_sum4=0; } //5 for(k=0;k<4;k++) { temp_sum5+= view_sum5[k]; //电压值的累加和 } temp_sum5=temp_sum5>>2; if(temp_sum5<21000) { temp_sum5=(21000-temp_sum5)/11; //设步进为11mV if((temp_sum5%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view5=temp_sum5/10; } else { tmpe_view5=temp_sum5/10; if(tmpe_view5!=0) tmpe_view5--; //减1 } temp_sum5=0; } else { temp_sum5=(temp_sum5-21000)/11; //设步进为11mV if((temp_sum5%10)>4) { //tmpe_view5=(temp_sum5/10)|0xff00;//加符号位 tmpe_view5=temp_sum5/10; tmpe_view5=tmpe_view5|0xff00; } else { tmpe_view5=temp_sum5/10; if(tmpe_view5!=0) { tmpe_view5--; //减1 tmpe_view5=tmpe_view5|0xff00; } } temp_sum5=0; } //6 for(k=0;k<4;k++) { temp_sum6+= view_sum6[k]; //电压值的累加和 } temp_sum6=temp_sum6>>2; if(temp_sum6<21000) { temp_sum6=(21000-temp_sum6)/11; //设步进为11mV if((temp_sum6%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view6=temp_sum6/10; } else { tmpe_view6=temp_sum6/10; if(tmpe_view6!=0) tmpe_view6--; //减1 } temp_sum6=0; } else { temp_sum6=(temp_sum6-21000)/11; //设步进为11mV if((temp_sum6%10)>4) { //tmpe_view6=(temp_sum6/10)|0xff00;//加符号位 tmpe_view6=temp_sum6/10; tmpe_view6=tmpe_view6|0xff00; } else { tmpe_view6=temp_sum6/10; if(tmpe_view6!=0) { tmpe_view6--; //减1 tmpe_view6=tmpe_view6|0xff00; } } temp_sum6=0; } //7 for(k=0;k<4;k++) { temp_sum7+= view_sum7[k]; //电压值的累加和 } temp_sum7=temp_sum7>>2; if(temp_sum7<21000) { temp_sum7=(21000-temp_sum7)/11; //设步进为11mV if((temp_sum7%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view7=temp_sum7/10; } else { tmpe_view7=temp_sum7/10; if(tmpe_view7!=0) tmpe_view7--; //减1 } temp_sum7=0; } else { temp_sum7=(temp_sum7-21000)/11; //设步进为11mV if((temp_sum7%10)>4) { //tmpe_view7=(temp_sum7/10)|0xff00;//加符号位 tmpe_view7=temp_sum7/10; tmpe_view7=tmpe_view7|0xff00; } else { tmpe_view7=temp_sum7/10; if(tmpe_view7!=0) { tmpe_view7--; //减1 tmpe_view7=tmpe_view7|0xff00; } } temp_sum7=0; } //8 for(k=0;k<4;k++) { temp_sum8+= view_sum8[k]; //电压值的累加和 } temp_sum8=temp_sum8>>2; if(temp_sum8<21000) { temp_sum8=(21000-temp_sum8)/11; //设步进为11mV if((temp_sum8%10)>4) //4舍5入 { //为了校正,4减1,5不入 tmpe_view8=temp_sum8/10; } else { tmpe_view8=temp_sum8/10; if(tmpe_view8!=0) tmpe_view8--; //减1 } temp_sum8=0; } else { temp_sum8=(temp_sum8-21000)/11; //设步进为11mV if((temp_sum8%10)>4) { //tmpe_view8=(temp_sum8/10)|0xff00;//加符号位 tmpe_view8=temp_sum8/10; tmpe_view8=tmpe_view8|0xff00; } else { tmpe_view8=temp_sum8/10; if(tmpe_view8!=0) { tmpe_view8--; //减1 tmpe_view8=tmpe_view8|0xff00; } } temp_sum8=0; } //发送数据更新 ram_data[0]=tmpe_view1; ram_data[1]=tmpe_view2; ram_data[2]=tmpe_view3; ram_data[3]=tmpe_view4; ram_data[4]=tmpe_view5; ram_data[5]=tmpe_view6; ram_data[6]=tmpe_view7; ram_data[7]=tmpe_view8; } else count_Vsum++; } // 2 发送温度 if(recv_ok==1) { com_recv(); } // 3 清狗 if(flg_300ms!=0) { asm("FCLR I"); wdtr=0x00; wdtr=0xff; asm("FSET I"); //开中断 flg_300ms=0; } } } //排序(Low to High) void Array_Sort(unsigned int *Array, unsigned char num) { unsigned char i, j ; unsigned int tmp; for(i = num -1; i > 0; i--) { for(j = 0; j < i ; j++) { if(Array[j] > Array[j+1]) { tmp = Array[j+1]; Array[j+1] = Array[j]; Array[j] = tmp; } } } } /**********单字节CRC校验****************/ void CRC_byte(unsigned char byte) { CRC_data=(CRC_data >> 8)^crc_table[(CRC_data&0xff)^byte]; } /**************************************/ void CRC_string(unsigned char p ) { unsigned char i; CRC_data=0xffff; for(i=0;i<p;i++) { CRC_byte(send_data[i]); } } void init_UART0(void) { s0ric=0x06; //接收数据设置中断为6级 s0tic=0x04; //发送数据中断为4级 u0mr=0x05; //异步方式,数据长度为8位,1个停止位,无奇偶校验 u0c0=0x00; //LSB格式,f1,发送完成,CMOS输出 u0brg=0x40; //设置波特率为9600 u0c1=0x15; //允许发送,允许接收,发送完成中断 p1_6=0; //485先设为输入 } void _uart0_trance(void)/*串口0发送中断*/ { asm("FSET I"); /*开中断*/ if(send_count!=0) { u0tb=send_data[tx_count]; send_count--; tx_count++; } else { p1_6=0; //发完,485设为输入 re_u0c1=1; } } // 串口接收中断 void _uart0_receive(void) { static unsigned int r_data; /*接收暂存*/ static unsigned int r_crc_data; /*CRC暂存*/ static unsigned char crc_receive; /*接收CRC字节标志*/ asm("FSET I"); /*开中断*/ r_data=u0rb; if(r_data&0xf000!=0) //判有没有出错 { r_data=u0rb; com_count==0; } r_data&=0x00ff; //只要低字节 if(com_count==0) /*如果是第一次接收*/ { CRC_data=0xffff; count_all=0; crc_receive=0; //接收CRC字节标志 if(r_data==ADDR_s1) /*地址配对*/ { recv_data[com_count++]=r_data; CRC_byte(r_data); /*第一个字节CRC*/ //set_time_re(delay15); /*设定1.5字符时间*/ //} //else //{ //set_time_re(delay35); /*放弃,等待3.5字符时间*/ } else { com_count=0; CRC_data=0xffff; } } else /*第二个以后的字节*/ { //if(time_15==0) //{ recv_data[com_count++]=r_data; if(crc_receive==0) /*没到CRC字节*/ { CRC_byte(r_data); /*字节CRC*/ } if(com_count==6) /*收到6个字节后通过功能码判断这帧数据的长度*/ { switch(recv_data[1]) /*选择功能码,好确定接收的总个数*/ { case 0x03: { count_all=8; /*功能为03H的字节数都位8个*/ break; } case 0x10: { count_all=(recv_data[5]<<1)+9; /*功能为10H的字节数为变量个数乘2*/ break; /*除了变量字节数,还有9个字节*/ } default : { com_count=0; CRC_data=0xffff; break; /*出错*/ } } } if(com_count==(count_all-2)) { crc_receive=1; } if(com_count==count_all) /*是否收完*/ { r_crc_data=(recv_data[com_count-1]<<8)|recv_data[com_count-2]; if(CRC_data!=r_crc_data) /*CRC是否出错*/ { //time_35=0; //set_time_re(delay35); /*放弃,等待3.5字符时间*/ com_count=0; CRC_data=0xffff; } else /*接收完成*/ { re_u0c1=0; recv_ok=1; crc_receive=0; count_all=0; //set_time_re(delay35); /*重新等待3.5字符时间,收完1帧后复位定时器*/ com_count=0; CRC_data=0xffff; } } //else //{ // set_time_re(delay15); /*设定1.5字符时间,收完1个字节后复位定时器*/ //} //} //else /*1.5字符超时*/ //{ // set_time_re(delay35); /*重新等待3.5字符时间*/ //} } } /********485通讯接收处理*******/ void com_recv(void) { recv_ok=0; /*读寄存器功能码03H处理*/ if(recv_data[1]==0x03) //读寄存器(功能码03H)处理 { //if(recv_data[0]!=0)//地址不为0 //{ send_data[0]=ADDR_s1; //本机地址 send_data[1]=0x03; //功能码 send_data[2]=recv_data[5]<<1; //字节数(变量个数不清 x 2 =字节数) send_count=send_data[2]; while(send_count!=0) { send_data[send_i+3]=(ram_data[recv_data[3]+send_j]&0xff00)>>8; //取变量高字节 send_i++; send_data[send_i+3]=ram_data[recv_data[3]+send_j]&0x00ff; //取变量低字节 send_i++; send_j++; send_count--; } CRC_string(send_data[2]+3); //发送数据串CRC校验 总字节数+开头的3个字节 send_data[send_data[2]+3]=(CRC_data&0x00ff); //CRC校验码低字节 send_data[send_data[2]+4]=(CRC_data&0xff00)>>8; //CRC校验码高字节 send_count=send_data[2]+5; p1_6=1; //485设为输出 re_u0c1=0; //不允许接收 tx_count=1; send_count--; u0tb=send_data[0]; CRC_data=0xffff; send_i=0; send_j=0; //red_addr_flg=0; //} //else //{ // re_u0c1=1; //允许串口接收 //} } else { /* if((status.stu.far_near==1)&&(recv_data[0]!=0)) //为远程和地址不为0才能设置 { //功能码10H处理 if(recv_data[1]==0x10) //写寄存器(功能码10H)处理 { //********10H功能给主机返馈*********** send_data[0]=ADDR_s1; //本机地址 send_data[1]=0x10; //功能码 send_data[2]=recv_data[2]; //变量起始地址高字节 send_data[3]=recv_data[3]; //变量起始地址低字节 send_data[4]=recv_data[4]; //变量个数高字节 send_data[5]=recv_data[5]; //变量个数低字节 CRC_string(6); //发送数据串CRC校验 send_data[6]=(CRC_data&0x00ff); //CRC校验码低字节 send_data[7]=(CRC_data&0xff00)>>8;//CRC校验码高字节 p1_6=1; //485设为输出 re_u0c1=0; //不允许接收 tx_count=1; //指向第二个字节 send_count=7; //后续字节在发送中断中发 u0tb=send_data[0]; //发第一个字节 CRC_data=0xffff; //************************************** //**********装载收到的数据************* load_count=recv_data[5];//变量个数 send_i=7; //recv_data[7]开始为数据 while(load_count!=0) { ram_data[recv_data[3]+send_j]=recv_data[send_i]<<8; send_i++; ram_data[recv_data[3]+send_j]=ram_data[recv_data[3]+send_j]|recv_data[send_i]; send_i++; send_j++; load_count--; } ram_data[1]=status.stus;//状态不能写 if((ram_data[16]==0x0008)||(ram_data[16]==0x0009)||(ram_data[16]==0x000a)) { ram_data[16]=0x0008; } send_i=0; send_j=0; //time_spke=0; //声音延时时间清零 //delay_spke_flg=1; //声音延时标志 } } */ re_u0c1=1; //允许串口接收 } } |
lxf2299 发表于 2020-7-11 09:53 软件真的太难了 |
硬件接法是比较简单的,软件我不太懂 |
不要黑 发表于 2020-7-10 19:28 师兄,我想请问一下,在485通信的基础上怎么添加modbus协议,小白请教 |
单片机与485设备或传感器通信,需要使用TTL转485的芯片MAX485,单片机串口接到MAX485的RXTX,另外接两个控制端控制读写,具体可以看手册,485芯片AB端接传感器的AB。买传感器应该会给参考资料的 |
a984984sd123456 发表于 2019-9-3 10:59 请问师兄做出来了么?我最近也在学这个。可以请教一下么 |
楼主,我最近也在做一个实验(stm32+ rs485 风速传感器),以前没有用过,可以参考一下你的程序吧吗 |
EatonDu 发表于 2019-4-4 15:18 楼主做出来了吗,我最近也在用一个485的传感器和stm32做实验,但是不会弄,可以参考一下你的程序吗 |
uvw 发表于 2019-4-4 12:47 第一个图也可以TTL转485,我想让传感器接到单片机上,请问程序该如何写在哪能找到类似的程序? |
1、硬件连接:你第一个图是一个USB转485的转换器,先在电脑上安装它的驱动程序,并找到用的是那个COM口; 2、用电线,l两心线 连接这个转换器的AB 对应传感器的AB,传感器给电源,转换器插到电脑里 3、用串口调试软件,按传感器的说明书设置波特率,按modbus 协议的格式发送数据,就可以接受数据了。 |
既然有TTL-RS485转换元件,那就用 RS485 通讯,也便于扩展; 注意定义好通讯协议。通讯协议从网上找一个参考。 |