OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9858|回复: 21

stm32与PLC(或者显控触摸屏通讯问题)

[复制链接]

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
发表于 2016-3-2 17:21:28 | 显示全部楼层 |阅读模式
5金钱
    最近在弄stm32与PLC的ModBus通讯问题,现在问题是单片机和ModBus Poll调试助手通讯成功了,比如说调试助手给单片机发的数是01 03 00 00 00 01 84 0A单片机回发的数据帧是01 03 02 00 00 B8 44,但是用显控的触摸屏就不行了,我现在在触摸屏上设置了一个数值输入框,用的是功能码03的测试程序,每当点输入框写数进去时触摸屏上提示的是0x43错误代码,进仿真查看单片机收到和发出的数据帧,发现单片机收到的数据帧为01 03 00 00 00 00 84 0A,第6个字节(寄存器数量的低字节)和调试助手时不同,然后我转而用调试助手看单片机收到的数据,发现单片机收到的数据帧也是01 03 00 00 00 00 84 0A,如果是这样单片机怎么能和调试助手通讯上的?不知道怎么回事了,求原子哥解答,附上部分程序如下:(  码字好困难  求大神们好心解决  程序段后面的注释都是自己敲的啊啊!!!==!)
         void Usart2_Init(void)  //用的是USART2复用
{                                                                       
        GPIOD->CRL&=~0xeb400000;         
        GPIOD->CRL|=0x14b00000;
        USART2->BRR=0x1D4C;  //波特率4800  之所以用4800  因为我发现用其他的波特率单片机收到的数据帧都是乱码  目前还不知道是什么原因?
              USART2->CR1=0x202c;  //一个起始位 8个数据位 1个停止位
        NVIC_SetPriority(USART2_IRQn,10);        
        NVIC->ISER[1]|=(u32)1<<(38-32);                                  //开中断                                                                                                                                                                                                  
        Set_485_In();                                  //设置为485接收
}

void USART2_IRQHandler(void)  //中断服务函数
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //判断接收缓存区为非空
        {
         if (CommIndex < CommIndexEnd)                  //  CommIndex字节数量索引号初值0  CommIndexEnd为字节数初始值为8  
        {
                   aRxBuff[CommIndex]=USART2->DR;  //aRxBuff[]是接收缓存数组
                 if(aRxBuff[0]!= SlaveID)                           //判断主机设置的从站ID号是否正确
                                {
                                        CommIndex = 0;
                                        return ;
                                }
                        CommIndex++;
        }
        else                                                                   // 如果接收完毕
        {                    
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
                {                                                        
                    aRxBuff[CommIndexEnd]=USART2->DR;
                }
                    RecFinishF=1;                                     //  接收完成标志置1                                                                               }
                if(aRxBuff[0]== SlaveID)
        {
                 ParseRecieve();                                    //数据帧解析处理函数         
        }
                CommIndex=0;
                RecFinishF=0;         
        }
        }
}
void ParseRecieve()   //从主站读取的数据帧处理函数
{
        unsigned int  uIndex ;
        unsigned int crc16tem;
        unsigned char i = 0;
        if (aRxBuff[0] == SlaveID)  //判断从站地址是否正确
        {
    crc16tem=((unsigned int)(aRxBuff[CommIndexEnd-1]) << 8) | aRxBuff[CommIndexEnd]; // calculate CRC check, erase two CRC byte

    uIndex=crc16(aRxBuff,CommIndexEnd-1);//(((unsigned int)(temp[0]) *256) | temp[1]) ;  //计算CRC校验码

                if(crc16tem==uIndex)//如果计算的校验码和收到的校验码一致
                {
                        switch (aRxBuff[1])                                // 判断功能码
                          {

                        case PresetMulReg:        {Delay_my(5);Receive_10();}break;  //10功能码是写多字  这个函数是我所需要的  目前是拿03功能码做测试  还没有通讯上
                        case ReadHoldReg:   {Delay_my(5);Receive_03();}break;  //03功能码处理函数               
                        default:
                        for (i=0;i<=80;i++)
                                        Delay_my(15);
                        break;
                          }
                }
                else
                    {
                          for (i=0;i<=80;i++);  // delay
                                Delay_my(1);
                    }
          }
        }

void Receive_03() //03功能码是处理函数  感谢该贴吧一哥们提供
{
  u8 sendnum;
        u16  usDataLen;
        u16 crcDataHi;
        u16 crcDataLo;
        u8 count;
        u8 i;
if(aRxBuff[0] == SlaveID)   
        {       
                    sendnum = 5+(2*((aRxBuff[4] * 256)+ aRxBuff[5]));//回发的字节数
                                                        usDataLen = sendnum - 2;
                                                        aTxBuff[0] = aRxBuff[0];//从站地址
                                                        aTxBuff[1] = aRxBuff[1];//功能码
                                                        aTxBuff[2] = sendnum - 5;//回发的字节数
                                                        for(count = 3;aRxBuff[5]>0;aRxBuff[5]--)
                                                        {
                                                                aTxBuff[count] =  XBuf[count - 3]/256;//回发数据高字节
                                                                aTxBuff[count+1] = XBuf[count - 3]%256;//回发数据低字节
                                                                count = count + 2;
                                                        }
                                                        crcData = crc16(aTxBuff,usDataLen);
                                                        crcDataLo = crcData/256; //校验码低字节
                                                        crcDataHi = crcData%256; //校验码高字节
                                                        aTxBuff[sendnum -1] = crcDataHi;//CRC高
                                                        aTxBuff[sendnum -2] = crcDataLo;//CRC低
                                                        for(i = 0;i < sendnum;i++)
                                                        {       
                                                                Set_485_Out();
                                                               USART2_SendByte(aTxBuff[i]);
                                                                while(!(USART2->SR & USART_FLAG_TXE));
                                                        }
                                                        Set_485_In();         //复位 485接收状态
                                                        sendnum = 0;
  }
}




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-2 20:21:57 | 显示全部楼层
PLC--调试助手。
单片机--调试助手。
分别调通这两个,就可以了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-3 08:42:46 | 显示全部楼层
正点原子 发表于 2016-3-2 20:21
PLC--调试助手。
单片机--调试助手。
分别调通这两个,就可以了。

呵呵   有这么简单就好咯   PLC已经和调试助手通讯上了的  单片机也已经和它通讯上了   换成PLC就不行了  出现的问题如上了
回复

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2016-3-3 08:58:15 | 显示全部楼层
那要看是不是硬件电路的原因了,按道理是调通信程序时,只要能和调试助手通信成功,肯定程序没有问题。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-3 09:14:44 | 显示全部楼层
xuyan021 发表于 2016-3-3 08:58
那要看是不是硬件电路的原因了,按道理是调通信程序时,只要能和调试助手通信成功,肯定程序没有问题。

不会这样吧亲  如果是硬件问题的话那单片机和调试助手能通讯上吗?我试试其他的板子看能不能行吧  
回复

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2016-3-4 09:37:03 | 显示全部楼层
我的意思是看PLC的通信接口的电平和单片机的电平是不是匹配的。注意:单片机是3.3V的。
回复

使用道具 举报

4

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2015-4-22
在线时间
3 小时
发表于 2016-3-4 19:28:49 来自手机 | 显示全部楼层
看看触摸屏接受发送字节顺序设置,用modscan32测试一下modbus,要是能通的话程序基本没问题,那就是触摸屏的串口设置了。我用过昆仑通泰的屏,它就有个字节顺序设置。不知道你的屏是什么情况。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-5 14:26:36 | 显示全部楼层
xuyan021 发表于 2016-3-4 09:37
我的意思是看PLC的通信接口的电平和单片机的电平是不是匹配的。注意:单片机是3.3V的。

485的通信接口电平不都是2~6V(逻辑1)或者-2~-6V(逻辑0)吗?
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-5 14:28:54 | 显示全部楼层
shy77210 发表于 2016-3-4 19:28
看看触摸屏接受发送字节顺序设置,用modscan32测试一下modbus,要是能通的话程序基本没问题,那就是触摸屏 ...

显控的触摸屏,昨天调试一整天已经通讯上了,但是把显控触摸屏换成PLC还是通讯不上,这俩都是标准的ModBus协议啊?快崩溃了!!!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-5 22:52:41 | 显示全部楼层
wan-der 发表于 2016-3-3 08:42
呵呵   有这么简单就好咯   PLC已经和调试助手通讯上了的  单片机也已经和它通讯上了   换成PLC就不行了  ...

那估计时电路问题。电平匹配问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-6 11:16:36 | 显示全部楼层
正点原子 发表于 2016-3-5 22:52
那估计时电路问题。电平匹配问题。

原子哥   按您的想法  单片机和PLC通讯   只要分别把单片机和显控触摸屏通讯上以及PLC和显控触摸屏通讯上那就行了吧   单片机和PLC做主站我需要的是PLC做主站   现在显控触摸屏做主站能和单片机通讯上   那PLC和显控触摸屏通讯需要PLC做主站这样理解是对的吧?  您说的电平匹配问题是什么问题呢?485的电平不都是-2~-6V或者2-6V吗?
回复

使用道具 举报

2

主题

686

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
10817
金钱
10817
注册时间
2014-6-12
在线时间
1036 小时
发表于 2016-3-6 14:14:26 | 显示全部楼层
有的PLC不完全按照modbus协议,一种办法你和PLC售后了解他们通信的特点,另一种用调试工具测一下PLC的通信实际情况。
回复

使用道具 举报

2

主题

686

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
10817
金钱
10817
注册时间
2014-6-12
在线时间
1036 小时
发表于 2016-3-6 14:16:58 | 显示全部楼层
PLC一般情况是做从机。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-6 22:24:01 | 显示全部楼层
wan-der 发表于 2016-3-6 11:16
原子哥   按您的想法  单片机和PLC通讯   只要分别把单片机和显控触摸屏通讯上以及PLC和显控触摸屏通讯上 ...

我都是一个个调试的.从简单的开始.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-6 22:25:15 | 显示全部楼层
我说的电平匹配问题.
比如,MAX232,很多假芯片.
某个产品用了MAX232芯片,和电脑通信正常.
我开发板,也是用RS232口,和电脑通信业正常.
但是我的开发板和这个产品RS232通信就不正常.
这样,就是电平不匹配了.
换一个MAX232,也许就解决了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-9 08:31:19 | 显示全部楼层
xuyaqi 发表于 2016-3-6 14:16
PLC一般情况是做从机。

单片机和PLC通讯PLC做从机?不是吧亲?PLC是标准的ModBUS协议呀,配置库文件就行,但是单片机不行啊,单片机得收到ModBus数据帧了才能发出去啊,这样的话不是PLC主单片机从么?再说了我这个项目确实要求PLC做主站呀,我快蒙圈了
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-9 08:34:07 | 显示全部楼层
正点原子 发表于 2016-3-6 22:25
我说的电平匹配问题.
比如,MAX232,很多假芯片.
某个产品用了MAX232芯片,和电脑通信正常.

这个问题应该不至于吧?板子都是我自己焊的,芯片都测试过了呀
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-9 23:16:10 | 显示全部楼层
wan-der 发表于 2016-3-9 08:34
这个问题应该不至于吧?板子都是我自己焊的,芯片都测试过了呀

很多这样的情况.
你可以慢慢研究下.最终可能就是这个问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2016-3-9 23:16:10 | 显示全部楼层
wan-der 发表于 2016-3-9 08:34
这个问题应该不至于吧?板子都是我自己焊的,芯片都测试过了呀

很多这样的情况.
你可以慢慢研究下.最终可能就是这个问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-2-23
在线时间
20 小时
 楼主| 发表于 2016-3-19 22:17:16 | 显示全部楼层
正点原子 发表于 2016-3-9 23:16
很多这样的情况.
你可以慢慢研究下.最终可能就是这个问题.

原子哥  现在终于通讯上了  但是PLC的40001这种地址对应的是写双字   怎么让单片机的变量和接收到的这个双字的地址一一对应    比如说我接收到的数据放在aRxBuffer[8] aRxBuffer[9]
aRxBuffer[10] aRxBuffer[11] 怎么让这4个字节分别与40001  40002  40003  40004一一对应呢
回复

使用道具 举报

11

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2016-9-29
在线时间
24 小时
发表于 2016-10-6 16:14:09 | 显示全部楼层
wan-der 发表于 2016-3-19 22:17
原子哥  现在终于通讯上了  但是PLC的40001这种地址对应的是写双字   怎么让单片机的变量和接收到的这个 ...

你程序里面有考虑3.5T这些时间吗
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-10-15
在线时间
0 小时
发表于 2017-10-15 23:54:00 | 显示全部楼层
wan-der 发表于 2016-3-5 14:28
显控的触摸屏,昨天调试一整天已经通讯上了,但是把显控触摸屏换成PLC还是通讯不上,这俩都是标准的ModBu ...

能把与显控触摸屏的程序借我看下吗?参考下、、biwfnso@163.com
谢谢!!
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-18 19:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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