闲来无事,做个记录,触摸屏使用迪文DGUS-T5D2 10.1寸触摸屏,单片机STM32F013系列,欧姆龙CP1E-N40PLC,之所以通过单片机转发是因为迪文触摸屏价格的巨大优势,核算单片机成本后,10.1寸触摸屏价格不超过400元,其次就是迪文触摸屏质量还算可以,进入正题。
1.迪文触摸屏配置:
1)串口配置:迪文触摸屏T5触摸屏串口配置在文件T5UID2.CFG文件,具体配置参看迪文手册:"T5UID2应用指南.PDF",我配置的串口参数:115200,8,1,N;
2) 界面配置:根据使用的触摸屏分辨率,做一张相应分辨率的图片,做好按键,数据显示框,再做一张键盘页面,通过迪文软件转换成迪文屏幕可以使用的图片将两张图片加载到软件;
(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
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硬件电路如下图:
实物图,由于没有正好大小的电容,电感,所以看上去有点歪: