关于STM32F1精英版读取rs485传感器的数据的一些疑问

2019-07-20 23:30发布

本帖最后由 郑忠毅 于 2019-5-31 10:00 编辑

现在身边设备有:
  • STM32F1的单片机开发板
  • RS485 - modbus-16的水质PH值传感器
  • RS485转USB

主要想要完成单片机读取到传感器的数据,(传感器和单片机的相互通信)。


       仔细查看了modbus协议,我的理解是 只要单片机和传感器可以相互传输字节流,就基本完成通信。具体的数据,只要把对应的十六进制数据转换一下便可以得到;在一定程度上可能不用关心CRC16的校验码,因为读取数据的报文是固定的,CRC已经计算好了,只要写死在程序里就可以;疑问一:不知道是否理解的对?)下方图片是传感器提供的通信格式;
传感器提供的通信格式 传感器提供的通信格式
       鉴于上方的理解,我使用的是 精英版 源码 《实验24 485实验》,不知道这个实验的源码是否可以满足我的需求(疑问二:不知道这个实验源码 发送 和 接收的模块,是否可以使用),使用过程中,我将u8 rs485buf[8]的值从cnt改为{0x01,0x03,0x00,0x01,0x00,0x02,0x95,0xCB},并且发送到传感器,传感器确实返回了值,但是返回的值和我在电脑上用串口工具直接连传感器时完全不一样,返回的值类似于 ff  e0  cf  c0  e  ff  ,ff  e0  ff  e0  cf  ff 这样的和通信协议上不一样的值(疑问三:为什么会返回这样的值,我该如何处理?);有趣的是为了验证是否真的是和传感器通信,我做了以下的一些调试:
  • 断开了485的物理连接,不会有返回值;
  • 修改单片机的CRC(修改最后的2个字节,随便改为0x01,0x03,0x00,0x01,0x00,0x02,0x95,0xCC),也不会有如何设置的返回;
下图是使用串口工具连接传感器是调试的页面,可以用正常返回报文。
QQ截图20190530154918.png

从零开始搞这些,感觉非常吃力,之前一直WEB开发,非常感谢能有大佬可以帮忙解惑。

下方是实验源码
实验24 485实验.zip (3.3 MB, 下载次数: 14) 2019-5-31 09:59 上传 点击文件名下载附件
实验源码





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
21条回答
郑忠毅
1楼-- · 2019-07-22 10:49
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"         
#include "rs485.h"


/************************************************
ALIENTEK精英STM32开发板实验24
485 实验
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/
                                        
int main(void)
{         
        u8 key;
        u8 i=0,t=0,j=0;
        u8 cnt=0;
        u8 rs485buf[8];
        u8 rs485bufA[8] = {0x01,0x03,0x00,0x01,0x00,0x02,0x95,0xCB};
       
        delay_init();                     //延时函数初始化          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(115200);                 //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
        LCD_Init();                                   //初始化LCD        
        KEY_Init();                                //按键初始化                          
        RS485_Init(9600);        //初始化RS485
        POINT_COLOR=RED;//设置字体为红 {MOD}
        LCD_ShowString(30,50,200,16,16,"ELITE STM32");
        LCD_ShowString(30,70,200,16,16,"RS485 TEST");       
        LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,110,200,16,16,"2015/1/15");       
        LCD_ShowString(30,130,200,16,16,"KEY0:Send");        //显示提示信息               

        POINT_COLOR=BLUE;//设置字体为蓝 {MOD}          
        LCD_ShowString(30,150,200,16,16,"Count:");                        //显示当前计数值       
        LCD_ShowString(30,170,200,16,16,"Send Data:");                //提示发送的数据       
        LCD_ShowString(30,210,200,16,16,"Receive Data:");        //提示接收到的数据               
                                                                          
        while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY0_PRES)//KEY0按下,发送一次数据
                {
                        LCD_ShowxNum(130,170,cnt,2,16,0X80);
                        LCD_ShowString(30,230,200,16,16,"-----------------------");//清空 Receive Data
                        //for(i=0;i<5;i++)
                        //{
                                //rs485buf=cnt+i;//填充发送缓冲区
                                //LCD_ShowxNum(30+i*32,190,rs485buf,3,16,0X80);        //显示数据
                        //}
                       
                        for(i=0;i<8;i++)
                        {
                                rs485buf=rs485bufA;
                                LCD_ShowxNum(30+i*30,190,rs485buf,3,16,0X80);        //显示数据
                        }
                        RS485_Send_Data(rs485buf,8);//发送8个字节
                        printf("S: %d ",key);       
                }                 
                RS485_Receive_Data(rs485buf,&key);
               
                //LCD_ShowString(30,230,200,16,16,"                          ");//清空 R
               
                if(key)//接收到有数据
                {
                       
                        printf("R: %d-- ",key);
                        if(key>8)key=8;//最大是5个数据.
                        for(i=0;i<key;i++)
                        {
                                printf(" %x ",rs485buf);
                                LCD_ShowxNum(30+i*32,230,rs485buf,3,16,0X80);        //显示数据
                        }
                        printf(" --");
                }
                t++;
                delay_ms(10);
                if(t==20)
                {
                        LED0=!LED0;//提示系统正在运行       
                        t=0;
                        cnt++;
                        LCD_ShowxNum(30+48,150,cnt,3,16,0X80);        //显示数据
                }                  
        }
}


郑忠毅
2楼-- · 2019-07-22 14:00
 精彩回答 2  元偷偷看……
郑忠毅
3楼-- · 2019-07-22 15:35
nashui_sx 发表于 2019-5-31 10:18
RS485_Receive_Data这个还是函数是你写的吧 ,感觉里面很多错误
buf=RS485_RX_BUF;地址不偏移吗

这里代码一点没动过, 我先按你说的试试看吧
郑忠毅
4楼-- · 2019-07-22 20:31
 精彩回答 2  元偷偷看……
郑忠毅
5楼-- · 2019-07-22 23:22
郑忠毅 发表于 2019-5-31 11:25
太痛苦了,我什么都没做,就是复制了一下代码,有重新编译了一下,就成功了,不管怎么样还是感谢你的帮助

成功了一次,然后又不行了。
nashui_sx
6楼-- · 2019-07-23 02:33
郑忠毅 发表于 2019-5-31 11:25
太痛苦了,我什么都没做,就是复制了一下代码,有重新编译了一下,就成功了,不管怎么样还是感谢你的帮助

不过那是不太可能的事,你要么改了啥,要么接线变了

一周热门 更多>