迪文DGUS屏通过单片机转发与欧姆龙PLC(hostlink mode-c协议)实现通讯

2 篇文章 0 订阅
1 篇文章 0 订阅

闲来无事,做个记录,触摸屏使用迪文DGUS-T5D2 10.1寸触摸屏,单片机STM32F013系列,欧姆龙CP1E-N40PLC,之所以通过单片机转发是因为迪文触摸屏价格的巨大优势,核算单片机成本后,10.1寸触摸屏价格不超过400元,其次就是迪文触摸屏质量还算可以,进入正题。

1.迪文触摸屏配置:

        1)串口配置:迪文触摸屏T5触摸屏串口配置在文件T5UID2.CFG文件,具体配置参看迪文手册:"T5UID2应用指南.PDF",我配置的串口参数:115200,8,1,N;

        2)  界面配置:根据使用的触摸屏分辨率,做一张相应分辨率的图片,做好按键,数据显示框,再做一张键盘页面,通过迪文软件转换成迪文屏幕可以使用的图片将两张图片加载到软件;

      注:T5屏的0x1000以上变量地址用户使用,这里需要注意。

                 (1)配置按键:在图片的按键部分放置一个“按键返回”控件,配置:按键地址0x1000,键值0,勾选“数据自动上传”;

                          键盘按键配置:在图片的按键部分放置多个“基础触控”控件,根据提示设定键值:0-9,退格,确认,取消等键值,设定好后放在对应位置;

                 (2)显示框配置:在图片显示框部分放置一个“数据变量显示”控件,变量地址0x1100;

                (3)输入框配置:这个需要做好键盘;在图片显示框部分放置一个“变量数据录入”控件,变量地址0x2100,勾选“数据自动上传”,键盘设置,选择做好的键盘,设置好对应的显示位置坐标(这里是控制用户输入的数据显示在屏幕那个位置)。

    至此,触摸屏配置完成;

2.STM32F103VCT6

配置:

     1)硬件:迪文T5触摸屏使用无壳体屏串口输出电平为TTL电平,由于传输距离有5米左右(单片机还有其他用途,距离较远),所以触摸屏端使用232芯片转换为232电平.

                 屏端:24V输入使用LM7805输出5V给屏和MAX232供电,屏幕供电的24地很干净,所以不做隔离;

                单片机和屏端:同样24V输入使用LM7805输出5V再通过LM1117-3.3输出3.3给STM32F103VCT6和SP3232EEN供电,单片机端232转换芯片使用兼容3.3V的SP3232EEN;

                 CP1E端:使用RS232或者RS485选件板;

                单片机对CP1E端:使用MAX3485或者SP3232EEN连接转口,芯片选择兼容3.3V;

   至此,硬件配置完成;

    2)软件:

                  1)PCL-CP1E:使用hostlink mode-c协议,为接收到命令后主动响应,所以PLC端不需要编程;

                  2)STM32软件使用“STM32CubeMX”配置,生成KEIL MDK5工程,很简单,网上有很多教程,需要使用什么功能可以去查;

3.通讯协议:

        1)STM32F103VCT6与T5屏按键的实现:

              按键下发给单片机的数据格式:  5A  A5  06 83 10 00 01 00 00

                      5A A5:帧头,可以在T5UID2.CFG文件修改;

                            06:该字节后接收的数据长度;

                            83:迪文指令;

                       10 00:变量地址;

                            01:数据长度,单位“字”;

                       00 00:数据,这里是前面按键控件键值设定多少,接收就是多少;

          然后根据接收的键值不同来控制PLC-CP1E的开关量,在这里我接收到上个按键之后,是控制PLC的H1.00的打开和关闭,

下面阐述开关PLC的H1.00;

         因为H区的写入是按字写入的,所以在写H1.00之前,需要保持H1.01--H1.15的状态不变,我们先读取H1整个字节的状态,然后对第0位取反后在写入PLC的H1寄存器,hostlink mode-c协议为ASCII码:   

          读H区的指令格式如下:@00RH+0001+0001+FCS校验(两字节)+*+结束码,对应单片机程序如下:

            usart2_txBuf[0]  = 0X40;//@  0X40
            usart2_txBuf[1]  = 0X30;//0  0X00
            usart2_txBuf[2]  = 0X30;//0     0X00
            usart2_txBuf[3]  = 0X52;//R     0X52
            usart2_txBuf[4]  = 0X48;//H     0X48
        
            usart2_txBuf[5]=(uint8_t)((start_addr>>12)&0x000f);
            usart2_txBuf[5]=HEX2ASCII(usart2_txBuf[5]);        
            usart2_txBuf[6]=(uint8_t)((start_addr>>8)&0x000f);
            usart2_txBuf[6]=HEX2ASCII(usart2_txBuf[6]);            
            usart2_txBuf[7]=(uint8_t)((start_addr>>4)&0x000f);
            usart2_txBuf[7]=HEX2ASCII(usart2_txBuf[7]);    
            usart2_txBuf[8]=(uint8_t)(start_addr&0x000f);
            usart2_txBuf[8]=HEX2ASCII(usart2_txBuf[8]);//4字节地址
            
            usart2_txBuf[9]=(uint8_t)((len>>12)&0x000f);
            usart2_txBuf[9]=HEX2ASCII(usart2_txBuf[9]);        
            usart2_txBuf[10]=(uint8_t)((len>>8)&0x000f);
            usart2_txBuf[10]=HEX2ASCII(usart2_txBuf[10]);            
            usart2_txBuf[11]=(uint8_t)((len>>4)&0x000f);
            usart2_txBuf[11]=HEX2ASCII(usart2_txBuf[11]);    
            usart2_txBuf[12]=(uint8_t)(len&0x000f);
            usart2_txBuf[12]=HEX2ASCII(usart2_txBuf[12]);//读取长度
            
            XORCheck(usart2_txBuf, 13);
            usart2_txBuf[13]=((FCS_CHECK>>4)&0x0f);
            usart2_txBuf[13]=HEX2ASCII(usart2_txBuf[13]);    
            usart2_txBuf[14]=(FCS_CHECK&0x0f);
            usart2_txBuf[14]=HEX2ASCII(usart2_txBuf[14]);//校验
            FCS_CHECK=0;
            
            usart2_txBuf[15]=0X2A;// "*"   0X2A
            usart2_txBuf[16]=0X0D;//   结束码

   单片机等待PLC返回数据后,返回数据为ASIIC码形式,处理数据后并对H1的第0位取反,在将对应数据写到PLC的H1寄存器;           写H区指令如下:@00WH+0001(写入的开始地址)+0001(写入数据)+FCS校验+*+结束码,对应单片机程序如下:

    usart2_txBuf[0]  = 0X40;//@   0X40
    usart2_txBuf[1]  = 0X30;//0   0X00
    usart2_txBuf[2]  = 0X30;//0     0X00
    usart2_txBuf[3]  = 0X57;//W     0X57
    usart2_txBuf[4]  = 0X48;//H     0X48
    
    usart2_txBuf[5]=(uint8_t)((start_addr>>12)&0x000f);
    usart2_txBuf[5]=HEX2ASCII(usart2_txBuf[5]);        
    usart2_txBuf[6]=(uint8_t)((start_addr>>8)&0x000f);
    usart2_txBuf[6]=HEX2ASCII(usart2_txBuf[6]);            
    usart2_txBuf[7]=(uint8_t)((start_addr>>4)&0x000f);
    usart2_txBuf[7]=HEX2ASCII(usart2_txBuf[7]);    
    usart2_txBuf[8]=(uint8_t)(start_addr&0x000f);
    usart2_txBuf[8]=HEX2ASCII(usart2_txBuf[8]);
    for(i=0;i<len;i++)
    {
        usart2_txBuf[i*4+9]=(uint8_t)(((*(cio_data+i))>>12)&0x000f);
        usart2_txBuf[i*4+9]=HEX2ASCII(usart2_txBuf[i*4+9]);
        
        usart2_txBuf[i*4+10]=(uint8_t)(((*(cio_data+i))>>8)&0x000f);
        usart2_txBuf[i*4+10]=HEX2ASCII(usart2_txBuf[i*4+10]);
        
        usart2_txBuf[i*4+11]=(uint8_t)(((*(cio_data+i))>>4)&0x000f);
        usart2_txBuf[i*4+11]=HEX2ASCII(usart2_txBuf[i*4+11]);
        
        usart2_txBuf[i*4+12]=(uint8_t)((*(cio_data+i))&0x000f);
        usart2_txBuf[i*4+12]=HEX2ASCII(usart2_txBuf[i*4+12]);
    }
    XORCheck(usart2_txBuf, 13);
    usart2_txBuf[len*4+9]=((FCS_CHECK>>4)&0x0f);
    usart2_txBuf[len*4+9]=HEX2ASCII(usart2_txBuf[len*4+9]);    
    usart2_txBuf[len*4+10]=(FCS_CHECK&0x0f);
    usart2_txBuf[len*4+10]=HEX2ASCII(usart2_txBuf[len*4+10]);
    FCS_CHECK=0;
            
    usart2_txBuf[len*4+11]=0X2A;// "*"   0X2A
    usart2_txBuf[len*4+12]=0X0D;//结束码

cio_data为定义的数组,里面存放需要写入的数据值,H1的第零位取反后放入这里,len位写入寄存器的长度;这里我们只写入H1,所以len=1;

至此,更改H1.00结束;

同理根,据上述操作使用WD和RD命令可以读取和写入PLC的D区;

       2)写入T5屏,使T5屏显示读取的PLC数据:

            使用WD命令读取PLC的数据后,将plc的数据处理,然后发送给触摸屏,发送触摸屏程序如下:

            com_buf[0] = 0x5a;
            com_buf[1] = 0xa5;
            com_buf[2] = 0x05;
            com_buf[3] = 0x82;


            com_buf[4] = 0x11;//写入触摸屏的地址
            com_buf[5] = 0x00;

      
           com_buf[6] = 0x00;

           com_buf[7] = 0x05;  写入的数据5

            HAL_UART_Transmit(&huart1,com_buf,8,20);//STM32F103发送函数;

触摸屏供电和RS232<-->TTL硬件电路如下图:

实物图,由于没有正好大小的电容,电感,所以看上去有点歪:

 

      

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 单片机迪文DGUS通信可以通过串口实现。下面是一个基本的通信例程: 首先,需要配置单片机的串口参数,确保其与DGUS的串口参数一致,例如波特率、数据位、校验位等。接下来,建立一个函数用于发送指令给DGUS,函数的输入参数为要发送的指令数据。在函数内部,将指令数据通过串口发送给DGUS。 接收DGUS的响应数据时,需要建立一个接收函数。该函数会不断监听串口接收缓冲区,检查是否有数据。当接收到数据时,将其存储在一个变量中,以便后续对数据的处理。 为了方便通信,可以定义一些常用的指令,如读取某个寄存器的值、写入某个寄存器的值等。这些指令可以通过发送指令函数实现,同时,可以通过接收函数获取DGUS的响应数据,从而实现对寄存器的读写操作。 在具体的应用中,可以根据需求编写相应的函数和逻辑来实现DGUS之间的通信。同时,需要注意在通信过程中及时处理错误,如发送数据超时、接收数据错误等,以确保通信的可靠性。 以上是一个简单的单片机DGUS通信的例程,具体实现还需要根据具体的硬件平台和软件开发环境来调整。 ### 回答2: 单片机迪文DGUS通信的例程,是指通过单片机DGUS进行数据传输和通信的代码示例。 首先,我们需要设置好单片机DGUS之间的通信接口,可以使用串口、I2C或SPI等通信协议。接下来,我们可以根据DGUS的通信协议,编写相应的代码进行通信。 以使用串口通信为例,以下是通信例程的大致步骤: 1. 初始化串口通信模块,设置波特率、数据位、停止位等参数。 2. 配置单片机的串口发送和接收引脚。 3. 编写相应的函数,将需要发送的数据打包成符合DGUS通信协议的格式。 4. 使用串口发送函数,将数据发送给DGUS。 5. 等待DGUS返回数据,可以使用中断方式进行接收或者定时轮询接收数据。 6. 解析接收到的数据,获取所需的信息,并进行相应的处理。 在编写通信例程时,需要注意的是,与DGUS通信的数据格式、命令和协议要符合DGUS的要求,并且需要根据实际需求进行相应的扩展和优化。 总体来说,通过单片机DGUS通信的例程,能够实现单片机DGUS之间的数据传输和通信,实现双方的数据交互和控制,为项目的开发和应用提供了方便和便利。 ### 回答3: 单片机迪文DGUS通信的例程可以通过串口通信实现。首先,我们需要在单片机中配置串口通信的参数,例如波特率、数据位、停止位等。然后,通过串口向DGUS发送指令,例如读取或写入寄存器的值。 通信的流程如下:首先,单片机发送启动信号给DGUS,告诉它即将进行通信。然后,单片机发送主机地址和命令码给DGUS,用于指定需要进行的操作。接下来,单片机发送数据给DGUS,例如需要写入的寄存器地址和相应的值。DGUS接收到数据后,进行相应的处理,并返回结果给单片机。 在编写通信例程时,我们需要先定义相关的寄存器地址和命令码。然后,编写相应的函数,用于发送和接收数据。例如,发送函数负责将数据发送到DGUS中,接收函数负责接收来自DGUS的数据。 在实际的例程代码中,我们可以使用相关的库函数,例如串口库函数、DGUS库函数,来简化编程过程。这些库函数提供了便捷的接口,可用于进行串口通信和DGUS操作。通过调用这些库函数,我们可以实现单片机DGUS之间的通信。 需要注意的是,在编写例程时,我们需要根据DGUS的通信协议和手册来进行相应的配置和操作。同时,还需要进行相应的错误处理和调试,确保通信的可靠性和稳定性。 总之,单片机迪文DGUS通信的例程可以通过串口通信实现,需要进行相关的配置和操作。编写例程时,我们可以使用库函数来简化编程过程,并注意进行错误处理和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值