找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 272|回复: 2
打印 上一主题 下一主题
收起左侧

STM32f103单片机与威纶通触摸屏modbus485通讯兼容上位机PLC程序

[复制链接]
跳转到指定楼层
楼主
     最近在改一个数控电源。主板保留有485通讯端口,无显示屏 主控stm32f103rc,没有原通讯协议,就依照电路重写了程序,加装oled显示器和时钟芯片,编码器,实现数字控制和库仑计,通讯,电源各种保护。调试中初期没写菜单系统相当头大。于是就利用modbus485通讯接触摸屏或串口助手调试。原机485部分为隔离式,使用485方便调试也保证了安全。电源完整代码暂时不公布。先公布modbus部分与触摸屏部分。程序可直接使用。程序兼容工控上位机,触摸屏,PLC。
    触摸屏例子程序太难找,对初学者很不友好。触摸屏我是一边学一边做,本程序包含一般项目完整功能。主屏显示,IO状态,系统设置,趋势图记录,
报警记录,密码项目,快捷分组,宏指令。可做简易模板使用,只有UI设计不尽如意。抛砖引玉。触摸屏细节我会在工控区另开一贴详细说明
   接线较简单可以使用串口转485模块,1-2元的模块很多。485模块A B 接威纶通触摸屏 com2的1,2孔   
   我非专业人士用到的知识都是大多来源与论坛,回馈论坛。
    完整单片机代码在最后
    部分代码:
    #ifndef _modbus_
#define _modbus_
//发送使能DE 接受使能RE 可短接使用一条线,也可使用2线,
//双工模块可不接使能只使用VDD GND RXD TXD


//4810通讯电源主控通讯芯片接线
//   收发芯片为             ADM2483
//  USART1_TXD  PA9    Pin6 TXD
//  USART1_RXD  PA10  Pin3 RXD
//   USART1_DE  PA0   Pin5 DE
//   USART1_RE  PA2      Pin4 RE
#include "stm32f10x_conf.h"
#define RS485_DE_1 GPIO_SetBits  (GPIOA, GPIO_Pin_0)     //DE:驱动使能,高电平使能发送功能。
#define RS485_DE_0 GPIO_ResetBits(GPIOA, GPIO_Pin_0)   //
#define RS485_RE_1 GPIO_SetBits  (GPIOA, GPIO_Pin_2)     //RE*:接收使能,低电平使能接收功能。
#define RS485_RE_0 GPIO_ResetBits(GPIOA, GPIO_Pin_2)     //
#define RS485_RT_0  RS485_RE_0; RS485_DE_0;
#define RS485_RT_1  RS485_RE_1; RS485_DE_1;
typedef struct
{
u8 myadd;//本设备的地址
u8 rcbuf[256]; //MODBUS接收缓冲区
u16 timout;//MODbus的数据断续时间

通讯测试.png (94.51 KB, 下载次数: 0)

通讯测试.png

历史.png (49.82 KB, 下载次数: 0)

历史.png

主屏.png (54.73 KB, 下载次数: 0)

主屏.png

校正分项.png (141.44 KB, 下载次数: 0)

校正分项.png

状态.png (53.14 KB, 下载次数: 0)

状态.png

modbus485通讯触摸屏.7z

11.33 MB, 下载次数: 14, 下载积分: 黑币 -5

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:344848 发表于 2024-9-10 16:07 | 只看该作者
没有看到通讯协议的内容:例如帧头、帧尾、校验方式等信息。
回复

使用道具 举报

板凳
ID:309610 发表于 2024-9-11 15:37 | 只看该作者
void Modbud_fun6()  //6号功能码处理
{
  u16 Regadd;
        u16 val;
        u16 i,crc,j;
        i=0;
  Regadd=modbus.rcbuf[2]*256+modbus.rcbuf[3];  //获取要修改的寄存器地址
        val=modbus.rcbuf[4]*256+modbus.rcbuf[5];     //获取修改后的值
        Reg[Regadd]=val;  //修改本设备相应的寄存器
       
        //以下为回应主机
       
        modbus.Sendbuf[i++]=modbus.myadd;//添加本设备地址到发送缓冲区
  modbus.Sendbuf[i++]=0x06;        //添加功能码到发送缓冲区
  modbus.Sendbuf[i++]=Regadd/256;  //添加寄存器地址的高字节到发送缓冲区
        modbus.Sendbuf[i++]=Regadd%256;  //添加寄存器地址的低字节到发送缓冲区
        modbus.Sendbuf[i++]=val/256;     //添加修改后的值的高字节到发送缓冲区
        modbus.Sendbuf[i++]=val%256;     //添加修改后的值的低字节到发送缓冲区
        crc=crc16(modbus.Sendbuf,i);     //计算CRC校验码
        modbus.Sendbuf[i++]=crc/256;     //添加CRC校验码的高字节到发送缓冲区
        modbus.Sendbuf[i++]=crc%256;     //添加CRC校验码的低字节到发送缓冲区
       
        RS485_RT_1;  //设置RS485为发送模式
       
        for(j=0;j<i;j++)  //发送缓冲区中的所有数据
        {
         RS485_byte(modbus.Sendbuf[j]);
        }
       
        RS485_RT_0;  //设置RS485为接收模式
}
Modbus协议中,CRC16校验用于检测通信数据的完整性。它通过对传输的数据进行循环冗余校验(CRC),生成一个16位的校验码,附加到数据的末尾,接收方根据相同算法计算CRC码,判断数据是否有误。
CRC校验方式说明:
1. CRC16多项式:采用的是0xA001,即Modbus协议中常用的CRC16-IBM算法,初始值为0xFFFF。
2. 查表法优化:代码使用了查表法来提高效率,通过auchCRCHi[]和auchCRCLo[]两个数组存储CRC的高位和低位预计算值。这样避免了逐位移位运算,减少了处理时间。
3. 计算过程:
初始化高位和低位CRC字节为0xFF。
遍历数据缓冲区的每一个字节,计算出当前CRC字节与当前数据字节异或的索引uIndex。
根据uIndex在auchCRCHi[]和auchCRCLo[]查找对应的高位和低位CRC值,更新uchCRCHi和uchCRCLo。
4. 结果组合:最终返回时,将高位字节uchCRCHi左移8位,与低位字节uchCRCLo合并,形成最终的16位CRC值。
这个方法有效地验证Modbus通信中的数据完整性,一旦接收方计算出的CRC值与附加的CRC码不一致,就说明数据传输过程中出现了错误。

在 Modbus 通信协议中,主机与设备之间通常使用 CRC16 校验 来确保通信数据的完整性。因此,主机与上面代码通信时,默认使用的校验方式也是 CRC16。

具体来说,Modbus 协议有两种主要的传输模式,每种模式的校验方式不同:

1. Modbus RTU 模式:
使用 CRC 校验:Modbus RTU(Remote Terminal Unit)是二进制通信格式,使用 CRC16 校验。如上代码所示,发送数据时,会计算数据的 CRC16 校验值,并将其附加在数据帧的末尾。接收方再通过相同的算法计算出 CRC 值,验证数据是否正确。
2. Modbus ASCII 模式:
使用 LRC 校验:在 Modbus ASCII 模式下,校验方式为 LRC(纵向冗余校验,Longitudinal Redundancy Check)。这是通过对数据帧中的每个字节进行异或运算,生成一个校验字节。
因此,如果通信采用 Modbus RTU 模式,则使用的是 CRC16 校验,这也是上述代码所实现的校验方式。如果是 Modbus ASCII 模式,则会使用 LRC 校验。
总结:
主机与上述代码进行通信时,通常使用的是 Modbus RTU 模式的 CRC16 校验。



触摸屏通讯设置的485通讯参数波特率,奇/偶/N效验,这些都是基本物理传输协议。 与程序中串口设置对应
        /*USART初始化*/
        USART_InitTypeDef USART_InitStructure;                                        //定义结构体变量
        USART_InitStructure.USART_BaudRate = 115200;                                //波特率
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //硬件流控制,不需要
        USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;        //模式,发送模式和接收模式均选择
        USART_InitStructure.USART_Parity = USART_Parity_No;                //奇偶校验,不需要
        USART_InitStructure.USART_StopBits = USART_StopBits_1;        //停止位,选择1位
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;                //字长,选择8位
        USART_Init(USART1, &USART_InitStructure);                                //将结构体变量交给USART_Init,配置USART1


完成物理协议才是软件协议触摸屏选择的是 Modbus RTU 模式也就决定了数据格式,效验方式为CRC,具体数据协议为标准协议
按标准写就行了,具体通讯报文分析我提供的文档内都有
                           威纶通自由协议报文
地址        通讯                       
4x    15      01        03                        00 0F            00 01         B4 09
数字元件    站号1、功能码03 读多个寄存器、 地址15 、    数量1、     效验码
5x    10      01        03                       00 0A           00 01          A4 08
数字元件    站号1、功能码03 读多个寄存器、 地址10 、    数量1、     效验码
       





评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表