找回密码
 立即注册

QQ登录

只需一步,快速开始

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

显控HMI与单片机通讯案例(含单片机底层程序源码)

  [复制链接]
跳转到指定楼层
楼主
看到51hei上面有多人需要给大家分享下显控HMI与单片机通讯案例(含单片机底层),显控触摸屏盒51单片机通过MODBUS协议通讯,读写数据和监视位状态,附触摸屏案例和单片机工程源码与快速接线模块。

还附带了单片机MODBUS通信测试.drw文件.



单片机源程序如下:
  1. /********************************************
  2.   samkoon深圳显控自动化技术
  3. **********************************************/
  4. /********文件信息*****************************
  5. 名称:main.c
  6. 功能:系统执行文件
  7. 创建者:徐思*
  8. 适用工程:MODBUS RTU SALVE 通信单片机底层案例
  9. ***********************************************/

  10. /********************************************************************************
  11. 本段程序用于和samkoon触摸屏使用MODBUS RTU协议通信,单片机作为从站,232连接
  12. samkoon MODBUS 主站功能码说明:
  13. 1、0x:读写位状态,读时发功能码 01 写时发功能码05;
  14. 2、1x:读输入位状态;发功能码 02;
  15. 3、3x:读输入寄存器,发功能码 04;
  16. 4、4x:读写寄存器,读时发功能码 03,写时发功能码 06,写32位时发功能码 10;
  17. 5、3X-D:读两个寄存器 功能码:03;
  18. 6、4X-D:写两个寄存器,功能码 10,读32位时读上来的数据和使用4X高低字节刚好相反
  19. 7、3x_bit:读输入寄存器的位,发功能码:04;
  20. 8、4x_bit:读写寄存器的位,读时发功能码:03,写时发功能码:06;
  21. **********************************************************************************/

  22. /*---如果要在程序使用该程序,请在程序中注明使用了显控公司资料---*/
  23. /*---如果要在文章使用该程序,请在文章中注明使用了显控公司资料---*/


  24. #include"main.h"

  25. u8 Reciver_Buf;
  26. u8 rece_index=0;
  27. u8 idata sendBuf[75];  //定义发送数组,最大允许发送32个字,64个字节
  28. u8 idata receBuf[75];        //定义接收数组,最大允许接收32个字,64个字节写入
  29. u8 *ps=sendBuf;
  30. u8 *pr=receBuf;
  31. u8 comm_END;
  32. u8 comm_time_out;
  33. u8 Reciver_bit=0;
  34. u16 R_ISP_L;
  35. u16 R_ISP_H;

  36. /*初始化函数*/
  37. void init()
  38. {
  39.   int i;

  40.   TMOD=0X21;   //设定定时器1的工作方式为2,及8位初值自动重装的8位定时器,用于产生波特率,T0工作方式1,用于判断通信帧结束
  41.   TH1=0XFD;    //设置定时器的初值为0xfd,是按照9600的波特率计算出来的数值
  42.   TL1=0XFD;    //定时器高低位数值一样,方式2下,定时器自动将高位的数值装入低位,所以设定的时间要一致
  43.   TH0=(65536-11111)/256;  //T0设定为1ms定时器, 用于判断通信帧结束,同时可用于其他的定时作用
  44.   TL0=(65536-11111)%256;  //T0低位
  45.   TR1=1;       //启动T1定时器

  46.   REN=1;      //运行串口接收数据,REN=1允许串口接收,REN=0禁止串口接收数据
  47.   SM0=0;      //设置串口工作方式为1,即10位异步通信,1起始位,8数据位,1停止位
  48.   SM1=1;      //同上,REN、SM0、SM1同属于SCON寄存器,但是SCON寄存器允许位寻址
  49.   EA=1;       //开总中断
  50.   ES=1;       //开串口中断
  51.   ET0=1;      //开定时器中断
  52.   TR0=1;       //启动T0定时器

  53.   P1=0xff;            //复位所有输出                  
  54.   relay=1;
  55.   bee=1;
  56.   
  57.   for(i=0;i<32;i++)          //复位所有
  58.   {
  59.    *(pb+i)=0;
  60.    *(pw+i)=0;
  61.    inputBit[i]=0;
  62.   }
  63.   for(i=0;i<32;i++)                   //读出存在内部E2PROM内的值
  64.   {
  65.      R_ISP_L=read_ISP(0x2000+i*2);     //读出数据低位
  66.          R_ISP_H=read_ISP(0x2000+i*2+1);   //读出数据高位
  67.     *(pw+i)=((R_ISP_H<<8)&0xff00)+(R_ISP_L&0Xff); //组合数据
  68.   }

  69. }

  70. /*********************************************************************************
  71. 手动调试函数,通过在触摸屏上操作相对应的位来控制单片机的手动输出
  72. 相对应的位说明:
  73. 0x0: 手动自动切换位,0:自动,1:手动
  74. 0x1-0x10;输出口1-10;
  75. ***********************************************************************************/
  76. void adj()
  77. {
  78.      u8 i,j=0;       //j要有初值=0;
  79.          for(i=1;i<9;i++)
  80.          {
  81.            j=(u8)((*(pb+i)&0x01)<<(i-1))+j;
  82.          }          
  83.          P1=~j;
  84.         relay=(~(*(pb+9)))&0x01;
  85.         bee=(~(*(pb+10)))&0x01;

  86. }

  87. /**********************************************************************************

  88. 将数值保存在内部E2PROM中
  89. 0x11:在触摸屏上的保存按钮
  90. ************************************************************************************/
  91. void saveData()
  92. {
  93.   u8 i;
  94.   sectorerase(0x2000);           //擦除扇区,这边写入的是第一扇区,在擦除是整个扇区被擦除
  95.   for(i=0;i<32;i++)
  96.   {
  97.     write_ISP((0X2000+i*2),(*(pw+i)&0xff));     //保存低8位数据
  98.         write_ISP((0x2000+i*2+1),((*(pw+i)>>8)&0xff));  //保存高8位数据
  99.   }
  100.     *(pb+11)=0;                   //保存按妞复位
  101.    
  102. }

  103. /*主函数*/
  104. void main()
  105. {

  106. init();                    //执行初始化程序
  107. while(1)                  //执行运行程序
  108. {
  109.    if(*(pb+0)) adj();         //手动调试
  110.    if(*(pb+11)) saveData();   //保存数值

  111. }
  112. }
  113. /*串口中断服务*/
  114. void ser() interrupt 4           //串口中断的序号是4
  115. {
  116.          RI=0;                        //产生串口中断时RI被硬件置1,在串口中断服务程序中需要用软件清0;
  117.          comm_END=4;                  //9600的波特率下,等待3.5个字节需要约4ms的时间
  118.          Reciver_bit=1;              //产生一次中断置一次位
  119.          Reciver_Buf=SBUF;                    //将接收到的数据赋给一个变量;
  120.          receBuf[rece_index++]=Reciver_Buf;   //将接收到的数据存入接收数组                  
  121. }

  122. /*T0中断服务程序*/

  123. void comm_stop() interrupt 1
  124. {
  125.   u8 i;
  126.   TH0=(65536-11111)/256;  //重装T0
  127.   TL0=(65536-11111)%256;  //T0低位
  128.   if(Reciver_bit&&comm_END!=0)
  129.     comm_END--;
  130.   if(comm_END==0)
  131.    {
  132.      Reciver_bit=0;                     //帧接收,对标志位清零                  
  133.      if((*(pr+0)==0x01||*(pr+0)==0x00)&&rece_index>=8)    //判断是否为本站地址或者是广播地址,有效报文的字节数量最少是8个字节
  134.        {
  135.               AnalyzeRecieve();                              //分析并生成响应报文
  136.                   if(*(pr+0)==0x01)                              //广播模式下不用返回
  137.               send_comm();                                   //发送响应报文
  138.        }             
  139.         comm_END=4;                                //重新赋延时初值
  140.         rece_index=0;                                   //数组长度清零
  141.         for(i=0;i<75;i++)                            //清空接收数组
  142.         receBuf[i]=0;
  143.         Reciver_Buf=0;                          
  144.    }
  145.          

  146. }                                       
复制代码
  1. /********************************************
  2.   samkoon
  3. **********************************************/
  4. /********文件信息*****************************
  5. 名称:main.h
  6. 功能:本段程序实现数据的E2PROM操作,实现数据断电保持功能
  7. 创建者:徐思坤
  8. 适用工程:MODBUS RTU SALVE 通信单片机底层案例
  9. ***********************************************/

  10. /*---如果要在程序使用该程序,请在程序中注明使用了显控公司资料---*/
  11. /*---如果要在文章使用该程序,请在文章中注明使用了显控公司资料---*/

  12. #include <intrins.h>
  13. #include"main.h"
  14. //#define _nop_()     //定义一个空函数

  15. /***************************************************************
  16. * 定义ISP/IAP操作命令,控制寄存器地址:ISP_CMD E5H             *
  17. * 1、0x00:  待机命令,ISP无操作;                              *
  18. * 2、0x01: 对用户的应用程序FLASH区及数据FLASH区字节读         *
  19. * 3、0x02:  对用户的应用程序FLASH区及数据FLASH区字节编程       *
  20. * 4、0x03:        对用户的应用程序FLASH区及数据FLASH区字节擦除       *
  21. ***************************************************************/
  22. #define RDCommand 0x01
  23. #define PRGCommand 0x02
  24. #define ERASECommand 0x03


  25. #define waittime 0x01       //定义CPU的等待时间

  26. /*开始ISP寄存器声明*/

  27. sfr ISP_DATA=0xE2;         //FLASH数据寄存区
  28. sfr ISP_ADDRH=0xE3;        //FLASH高字节地址寄存器
  29. sfr ISP_ADDRL=0xE4;        //FLASH低字节地址寄存器
  30. sfr ISP_CMD=0xE5;       //FLASH命令寄存器
  31. sfr ISP_TRIG=0xE6;       //FLASH命令触发寄存器
  32. sfr ISP_CONTR=0xE7;       //ISP/IAP控制寄存器


  33. /*打开ISP/IAP功能*/

  34. void ISP_enable(void)
  35. {
  36.        
  37. //        ISP_CONTR=ISP_CONTR&0X18;     //初始化SP/IAP控制寄存器;
  38.         ISP_CONTR=waittime;           //写入硬件延时,注意这边是“|”运算
  39.         ISP_CONTR=ISP_CONTR|0x80;      //打开ISPEN,运行写入,注意是“|”运算
  40.        
  41.          
  42. }

  43. /*关闭ISP/IAP功能*/

  44. void ISP_disable(void)
  45. {
  46.   ISP_CONTR=ISP_CONTR&0x00;      //关闭ISPEN,运行写入,注意是“&”运算
  47.   ISP_TRIG=0x00;                 //清空ISP命令控制触发器
  48.   ISP_CMD=0x00;
  49. // EA=1;                          //打开中断
  50. }

  51. /*建立公用触发函数*/

  52. void go_ISP(void)
  53. {

  54.   ISP_TRIG=0x46;         //触发ISP/IAP命令字节1,(固定)
  55.   ISP_TRIG=0xB9;         //触发ISP/IAP命令字节2,(固定)
  56.   _nop_();              //执行一个空函数
  57. }

  58. /*扇区擦除函数*/

  59. void sectorerase(u16 addr)
  60. {
  61.    ISP_ADDRH=(u8)(addr>>8);        /*取地址的高位*/
  62.    ISP_ADDRL=(u8)(addr&0xff);           //地址的低位
  63. //  EA=0;             //关闭总中断
  64.    ISP_enable();          //打开ISP/IAP功能
  65.    ISP_CMD=ERASECommand;   //从新给ISP命令寄存器赋值,这边赋的是0x03,表示擦除
  66.    go_ISP();                       //执行触发命令,将擦除命令写入
  67.    ISP_disable();                  //关闭ISP功能
  68. }

  69. /*写数据函数(单个字节写入)*/

  70. void write_ISP(u16 st_addr,u8 w_data)
  71. {
  72.   ISP_DATA=w_data;                //将要写入的数据存入ISP FLASH数据寄存区
  73.   ISP_ADDRH=(u8)(st_addr>>8);        /*取地址的高位*/
  74.   ISP_ADDRL=(u8)(st_addr&0xff);           //地址的低位
  75. // EA=0;             //关闭总中断
  76.   ISP_enable();          //打开ISP/IAP功能
  77.   ISP_CMD=PRGCommand;   //从新给ISP命令寄存器赋值,这边赋的是0x02,表示写入
  78.   go_ISP();                    //触发写入
  79.   ISP_disable();               //关闭ISP功能
  80. }

  81. /*读数据函数(读单个字节)*/

  82. u8 read_ISP(u16 rd_addr)
  83. {
  84.   ISP_ADDRH=(u8)(rd_addr>>8);        /*取地址的高位*/
  85.   ISP_ADDRL=(u8)(rd_addr&0x00ff);           //地址的低位
  86.   ISP_CMD=ISP_CMD&0xF8;           // 清空ISP命令寄存器的第三位
  87. //  EA=0;                          //关闭总中断
  88.   ISP_enable();                 //打开ISP/IAP功能
  89.   ISP_CMD=RDCommand;           //从新给ISP命令寄存器赋值,这边赋的是0x01,表示读出
  90.   go_ISP();                    //触发写入
  91.   ISP_disable();               //关闭ISP功能
  92.   return (ISP_DATA);          //返回读出的数据
  93. ……………………

  94. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:

显控HMI与单片机通讯案例(含单片机底层) (0).rar (809.72 KB, 下载次数: 431)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:53978 发表于 2018-5-19 21:55 | 只看该作者
谢谢 下载来学习学习
回复

使用道具 举报

板凳
ID:362603 发表于 2018-7-1 17:10 | 只看该作者
你好,我用功能代码1通讯,老是通讯超时,这个怎么办
回复

使用道具 举报

地板
ID:362603 发表于 2018-7-1 17:12 | 只看该作者
你好,我用功能代码01通讯,老是超时,怎么办了
回复

使用道具 举报

5#
ID:386692 发表于 2018-8-21 20:01 | 只看该作者
51单片机接收到01,02,03等会作出响应。那显控触摸屏是在哪里设置发送01,02,03等modbus码??
回复

使用道具 举报

6#
ID:150905 发表于 2018-10-22 14:54 | 只看该作者
还附带了单片机MODBUS通信测试.drw文件
回复

使用道具 举报

7#
ID:428974 发表于 2018-11-19 08:08 | 只看该作者
什么是特定用户啊 ,为什么我不能下载呢,我正在用一块显控屏 和AVr单片机的通信,正好借看下 先谢谢了
回复

使用道具 举报

8#
ID:430332 发表于 2018-11-21 08:41 | 只看该作者
好复杂
回复

使用道具 举报

9#
ID:307784 发表于 2018-11-29 20:24 | 只看该作者
过来学习了
回复

使用道具 举报

10#
ID:307784 发表于 2018-11-29 20:26 | 只看该作者
之前都是威纶通的,显控的modbus地址写不进去,不管从站或主站
各们可以说下是什么问题吗
回复

使用道具 举报

11#
ID:448641 发表于 2018-12-18 09:54 | 只看该作者
我正在用一块显控屏 和RL78单片机的通信,正好借看下 先谢谢了
回复

使用道具 举报

12#
ID:419837 发表于 2019-3-14 08:29 | 只看该作者
真好,正好要学习。
回复

使用道具 举报

13#
ID:138443 发表于 2019-3-17 19:39 | 只看该作者
支持支持,多谢
回复

使用道具 举报

14#
ID:544217 发表于 2019-5-21 21:38 | 只看该作者
非常好,支持
回复

使用道具 举报

15#
ID:138443 发表于 2019-7-20 00:09 | 只看该作者
太好了,支持一下,谢谢
回复

使用道具 举报

16#
ID:428400 发表于 2019-7-22 21:33 | 只看该作者
这个链接显控哪一款的触摸屏啊
回复

使用道具 举报

17#
ID:602115 发表于 2019-8-25 19:58 | 只看该作者
已下载,谢谢分享。
回复

使用道具 举报

18#
ID:398080 发表于 2019-9-2 19:37 | 只看该作者
一下载,感谢分享
回复

使用道具 举报

19#
ID:109277 发表于 2019-11-6 15:54 | 只看该作者
谢谢分享,看看
回复

使用道具 举报

20#
ID:428400 发表于 2019-11-7 18:54 | 只看该作者
怎么修改输出点?有大师请指点下!谢谢
回复

使用道具 举报

21#
ID:722051 发表于 2020-4-4 06:29 | 只看该作者
怎样下载
回复

使用道具 举报

22#
ID:1004539 发表于 2022-2-9 16:54 | 只看该作者
正在学习,很需要这方面的资料,谢谢
回复

使用道具 举报

23#
ID:228452 发表于 2022-4-7 04:42 | 只看该作者
Hello
What kind of HMI to use
回复

使用道具 举报

24#
ID:1045493 发表于 2022-10-25 23:09 | 只看该作者
单片机用的啥型号的啊?
回复

使用道具 举报

25#
ID:228452 发表于 2022-11-21 02:12 | 只看该作者
MCU is  C51 modbus code
回复

使用道具 举报

26#
ID:310569 发表于 2023-3-20 15:59 | 只看该作者
很好,这个正想学习
回复

使用道具 举报

27#
ID:1006852 发表于 2023-10-21 11:56 | 只看该作者
有没有指定具体需要用哪个型号的单片机?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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