找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5705|回复: 5
收起左侧

工控设备串口及485调试模块电路原理图与单片机源码等资料

[复制链接]
ID:280979 发表于 2018-2-1 12:09 | 显示全部楼层 |阅读模式
【简要说明】
一、 尺寸:长170mmX宽72mmX高18mm
二、 主要芯片:单片机,MAX485,MAX232
三、 工作电压:6V40V,功耗小于1W
四、  特点:1、具有稳压电路,输入电压广,具有电源指示灯
            2、具有485通信和232通信及TTL通信
            3、具有数码管数据显示,蜂鸣器提示音
            4、波特率可调分别是 2400 4800  9600 19200
            5、采用大按键,机械寿命长
            6、单片机编程,客户可以自己更改,提供源代码
            7、可发送20组数据
            8、具有系统复位按键
            9、端子采用螺旋压接端子           
            10、工作温度-40度至 +70度
            11、工作湿度 40%  ~ 80%RH
            12、板子静态功耗小于1W
            13具有续流保护
            14、具有电磁抗干扰能力
            15、板子稳定工作可靠
            16、板子可安装在DIN导轨上面

工控设备串口及485调试模块的电路原理图:
0.png 0.png

pcb:
0.png

GYJ-0023_工控设备串口及485调试模块波特率设置:

1上2下 2400
1下2上 4800
1上2上 9600
1下2下 19200
01 2400
10 4800
00 9600
11 19200

模块的元件清单:
0.png 0.png
应用举例2.JPG 应用举例.JPG 接线说明.JPG 标示图.JPG

GYJ-0023_工控设备串口及485调试模程序:
rs485.c单片机源程序如下:

  1. #include <STC12C5A60S2.H>
  2. #include <intrins.h>

  3. sbit RS485_DIR = P1^4;  //RS485方向选择引脚
  4. sbit feng = P3^7;       //蜂鸣器引脚

  5. bit flagFrame = 0;  //帧接收完成标志,即接收到一帧新数据
  6. bit flagTxd = 0;    //单字节发送完成标志,用来替代TXD中断标志位
  7. unsigned char cntRxd = 0;   //接收字节计数器
  8. unsigned char pdata bufRxd[64];  //接收字节缓冲区

  9. extern void UartAction(unsigned char *buf, unsigned char len);

  10. /* 串口配置函数,baud-通信波特率 */
  11. void ConfigUART(unsigned int baud)
  12. {
  13.     RS485_DIR = 0; //RS485设置为接收方向
  14.     SCON  = 0x50;  //配置串口为模式1
  15.     TMOD &= 0x0F;  //清零T1的控制位
  16.     TMOD |= 0x20;  //配置T1为模式2
  17.     TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
  18.         PCON = 0x00;         //注意  每次变化都要更改,他会保存
  19.     TL1 = TH1;     //初值等于重载值
  20.     ET1 = 0;       //禁止T1中断
  21.     ES  = 1;       //使能串口中断
  22.     TR1 = 1;       //启动T1
  23. }
  24. /* 串口配置函数,19200baud-通信波特率 */
  25. void ConfigUART1(unsigned int baud1)
  26. {
  27.     RS485_DIR = 0; //RS485设置为接收方向
  28.     SCON  = 0x50;  //配置串口为模式1
  29.     TMOD &= 0x0F;  //清零T1的控制位
  30.     TMOD |= 0x20;  //配置T1为模式2
  31.     //TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
  32.    // TL1 = TH1;     //初值等于重载值
  33.    PCON = 0x80;
  34.    TH1 = 0xFD;
  35.    TL1 = 0xFD;
  36.     ET1 = 0;       //禁止T1中断
  37.     ES  = 1;       //使能串口中断
  38.     TR1 = 1;       //启动T1
  39. }
  40. /* 软件延时函数,延时时间(t*10)us */
  41. void DelayX10us(unsigned int t)
  42. {
  43.     do {
  44.         _nop_();
  45.         _nop_();          //注意如果是52rc就是8个nop   如果是60s2就多加12个nop
  46.         _nop_();
  47.         _nop_();
  48.         _nop_();
  49.         _nop_();
  50.         _nop_();
  51.         _nop_();
  52.                 _nop_();
  53.         _nop_();
  54.         _nop_();
  55.         _nop_();
  56.         _nop_();
  57.         _nop_();
  58.         _nop_();
  59.         _nop_();
  60.                 _nop_();
  61.         _nop_();
  62.         _nop_();
  63.         _nop_();
  64.     } while (--t);
  65. }
  66. /*
  67. void Send( char dat){//发送一字节数据
  68.                            //标志位置1
  69.           SBUF=dat;           //数据装入SBUF
  70.         while(TI==0);
  71.         TI=0;
  72. }

  73. //向串口发送字符串

  74. void SendString(char *s)

  75. {
  76.   while(*s)            //字符串发送完否

  77.   {
  78.     Send(*s++);    //发送字符并指针指向下一字符
  79.   }
  80. }
  81. */

  82. // 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  83. void UartWrite(unsigned char *buf, unsigned char len)
  84. {
  85.     RS485_DIR = 1;  //RS485设置为发送
  86.     while (len--)   //循环发送所有字节
  87.     {
  88.         flagTxd = 0;      //清零发送标志
  89.         SBUF = *buf++;    //发送一个字节数据
  90.         while (!flagTxd); //等待该字节发送完成
  91.     }
  92.     DelayX10us(5);  //等待最后的停止位完成,延时时间由波特率决定
  93.     RS485_DIR = 0;  //RS485设置为接收
  94. }




  95. /* 串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 */
  96. unsigned char UartRead(unsigned char *buf, unsigned char len)
  97. {
  98.     unsigned char i;
  99.    
  100.     if (len > cntRxd)  //指定读取长度大于实际接收到的数据长度时,注意  发送的数据长度不能大于 sizeof(buf)-2)
  101.     {                  //读取长度设置为实际接收到的数据长度
  102.         len = cntRxd;
  103.     }
  104.     for (i=0; i<len; i++)  //拷贝接收到的数据到接收指针上
  105.     {
  106.         *buf++ = bufRxd[i];
  107.     }
  108.     cntRxd = 0;  //接收计数器清零
  109.    
  110.     return len;  //返回实际读取长度
  111. }
  112. /* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
  113. void UartRxMonitor(unsigned char ms)
  114. {
  115.     static unsigned char cntbkp = 0;
  116.     static unsigned char idletmr = 0;

  117.     if (cntRxd > 0)  //接收计数器大于零时,监控总线空闲时间
  118.     {
  119.         if (cntbkp != cntRxd)  //接收计数器改变,即刚接收到数据时,清零空闲计时
  120.         {
  121.             cntbkp = cntRxd;
  122.             idletmr = 0;
  123.         }
  124.         else                   //接收计数器未改变,即总线空闲时,累积空闲时间
  125.         {
  126.             if (idletmr < 30)  //空闲计时小于30ms时,持续累加
  127.             {
  128.                 idletmr += ms;
  129.                 if (idletmr >= 30)  //空闲时间达到30ms时,即判定为一帧接收完毕        注意这是485协议规定的
  130.                 {
  131.                     flagFrame = 1;  //设置帧接收完成标志
  132.                 }
  133.             }
  134.         }
  135.     }
  136.     else
  137.     {
  138.         cntbkp = 0;
  139.     }
  140. }
  141. /* 串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用 */
  142. void UartDriver()
  143. {
  144.     unsigned char len;
  145.     unsigned char pdata buf[40];         //记住  pdata 这个关键词很重要,他能将变量存在xdata中  节省data的空间

  146.     if (flagFrame) //有命令到达时,读取处理该命令
  147.     {
  148.         flagFrame = 0;
  149.         len = UartRead(buf, sizeof(buf)-2); //将接收到的命令读取到缓冲区中         注意  接收的数据数量是由bufRxd[64]的大小决定的,发送的数据数量是由buf[40]决定的,因为要与moudebus校验做配合,所以发送少两位做为校验位
  150.         UartAction(buf, len);  //传递数据帧,调用动作执行函数
  151.     }
  152. }
  153. /* 串口中断服务函数 */
  154. void InterruptUART() interrupt 4
  155. {
  156.     if (RI)  //接收到新字节           当字节发送到结束位的一半的时候RI接收标志变为1  进入窜口中断
  157.     {
  158.         RI = 0;  //清零接收中断标志位
  159.         if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
  160.         {                            //保存接收字节,并递增计数器
  161.             bufRxd[cntRxd++] = SBUF;        // cntRxd++这个很重要,一开始 cntRxd < sizeof(bufRxd)当进入函数的次数增加,cntRxd慢慢变大,当传入的数据不满的时候就        用时间检测,判断是否是传输完成
  162.         }
  163.     }
  164.     if (TI)  //字节发送完毕
  165.     {
  166.         TI = 0;   //清零发送中断标志位
  167.         flagTxd = 1;  //设置字节发送完成标志
  168.     }
  169. }
  170. /*蜂鸣器函数*/
  171. void fengming()
  172. {
  173.         feng = 0;
  174.         DelayX10us(10000);
  175.         DelayX10us(10000);
  176.         feng = 1;

  177.                
  178. }
复制代码

手持通讯板 - 发送字符:
  1. #include <STC12C5A60S2.H>
  2. #include <intrins.h>
  3. #define uchar unsigned char//宏定义无符号字符型
  4. #define uint unsigned int  //宏定义无符号整型
  5. sbit RS485_DIR = P1^4;  //RS485方向选择引脚
  6. sbit boma1 = P1^1;
  7. sbit boma2 = P1^0;
  8. bit flagFrame = 0;  //帧接收完成标志,即接收到一帧新数据
  9. bit flagTxd = 0;    //单字节发送完成标志,用来替代TXD中断标志位
  10. unsigned char cntRxd = 0;   //接收字节计数器
  11. unsigned char pdata bufRxd[64];  //接收字节缓冲区
  12. void UartRxMonitor(unsigned char ms);
  13. void UartWrite(unsigned char *buf, unsigned char len);
  14. void DelayX10us(unsigned int t);
  15. void ConfigUART1(unsigned int baud);
  16. void ConfigUART(unsigned int baud);
  17. sbit ka=P2^4;//按键矩阵
  18. sbit kb=P2^5;
  19. sbit kc=P2^6;
  20. sbit kd=P2^7;
  21. sbit k1=P2^0;
  22. sbit k2=P2^1;
  23. sbit k3=P2^2;
  24. sbit k4=P2^3;
  25. xdata uint k4val,k4num,keyval=0,keyval1=0,keyval2=0;
  26. void kabcd();//矩阵按键公共
  27. void Getch();//矩阵按键
  28. void Delay_us(uint i); //us延时
  29. code uchar seg7code[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};
  30. sbit display=P3^6;
  31. void BaudRate();//波特率选择
  32. uint keynum=0;
  33. static uchar presstime=0;//时间值按键用到的
  34. bit kf0=1,kf1=1,kf2=1;
  35. bit kt0=0,kt1=0,kt2=0;
  36. sbit key1=P1^5;
  37. sbit key2=P1^6;
  38. uchar sendval[20]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
  39. uint empty=0;//清空
  40. sbit buzzer=P3^7;
  41. bit buzzerf=0;
  42. void main(){
  43.         TMOD = 0x01;
  44.         TH0  = 0xfc;
  45.         TL0  = 0x67;
  46.         TR0  = 1;
  47.         EA   = 1;
  48.         ET0  = 1;
  49.         display=0;
  50.         keyval=16;
  51.         keyval2=16;
  52.         while(1){
  53.                 Getch();//矩阵按键
  54.                 BaudRate();//波特率选择
  55.                 if(keyval!=16){
  56.                         if(kf0){kf0=0;kt0=1;
  57.                                 buzzerf=1;
  58.                                 keyval2=keyval;
  59.                                 sendval[keynum]=keyval1;
  60.                                 keynum++;
  61.                         }
  62.                         keyval=16;
  63.                 }else{if(kt0){kf0=1;kt0=0;}}        
  64.                 P0=seg7code[keyval2];//传到数码管显示
  65.         if(keynum>20){
  66.                 buzzerf=1;
  67.         }
  68.     if(key1==0){if(kf1){if(presstime>100){kf1=0;kt1=1;presstime=0;//当按键1按下 清空数据
  69.                 keynum=0;keyval2=16;buzzerf=1;
  70.                 for(empty=0;empty<20;empty++){sendval[empty]='0';}
  71.         }}}else{if(kt1){if(presstime>100){kf1=1;kt1=0;presstime=0;//当按键1松开
  72.         }}}//按键1结束               
  73.     if(key2==0){if(kf2){if(presstime>100){kf2=0;kt2=1;presstime=0;//当按键2按下 发送数据
  74.                 if(keynum<21){
  75.                         buzzerf=1;
  76.                         UartWrite(sendval,keynum);
  77.                 }
  78.         }}}else{if(kt2){if(presstime>100){kf2=1;kt2=0;presstime=0;//当按键2松开
  79.         }}}//按键2结束               
  80.         if(buzzerf){
  81.                 buzzer=0;//蜂鸣器响        
  82.                 Delay_us(20000);
  83.                 Delay_us(20000);
  84.                 Delay_us(20000);
  85.                 buzzer=1;
  86.                 buzzerf=0;
  87.         }
  88.         }
  89. }
  90. void InterruptTimer0() interrupt 1{//T0中断服务函数,执行串口接收监控
  91.    TH0  = 0xfc;
  92.    TL0  = 0x67;
  93.    presstime++;
  94.    UartRxMonitor(1);  //串口接收监控
  95. }
  96. /* 串口配置函数,baud-通信波特率 */
  97. void ConfigUART(unsigned int baud){
  98.     RS485_DIR = 0; //RS485设置为接收方向
  99.     SCON  = 0x50;  //配置串口为模式1
  100.     TMOD &= 0x0F;  //清零T1的控制位
  101.     TMOD |= 0x20;  //配置T1为模式2
  102.     TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
  103.         PCON = 0x00;         //注意  每次变化都要更改,他会保存
  104.     TL1 = TH1;     //初值等于重载值
  105.     ET1 = 0;       //禁止T1中断
  106.     ES  = 1;       //使能串口中断
  107.     TR1 = 1;       //启动T1
  108. }
  109. /* 串口配置函数,19200baud-通信波特率 */
  110. void ConfigUART1(unsigned int baud){
  111.         RS485_DIR = 0; //RS485设置为接收方向
  112.         SCON  = 0x50;  //配置串口为模式1
  113.         TMOD &= 0x0F;  //清零T1的控制位
  114.         TMOD |= 0x20;  //配置T1为模式
  115.         PCON = 0x80;
  116.         TH1 = 0xFD;
  117.         TL1 = 0xFD;
  118.         ET1 = 0;       //禁止T1中断
  119.         ES  = 1;       //使能串口中断
  120.         TR1 = 1;       //启动T1
  121. }
  122. /* 软件延时函数,延时时间(t*10)us */
  123. void DelayX10us(unsigned int t){
  124.     do {
  125.         _nop_();_nop_();_nop_();_nop_();
  126.         _nop_();_nop_();_nop_();_nop_();
  127.                 _nop_();_nop_();_nop_();_nop_();
  128.         _nop_();_nop_();_nop_();_nop_();
  129.                 _nop_();_nop_();_nop_();_nop_();
  130.     } while (--t);
  131. }
  132. // 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度
  133. void UartWrite(unsigned char *buf, unsigned char len){
  134.     RS485_DIR = 1;  //RS485设置为发送
  135.     while (len--){   //循环发送所有字节
  136.         flagTxd = 0;      //清零发送标志
  137.         SBUF = *buf++;    //发送一个字节数据
  138.         while (!flagTxd); //等待该字节发送完成
  139.     }
  140.     DelayX10us(5);  //等待最后的停止位完成,延时时间由波特率决定
  141.     RS485_DIR = 0;  //RS485设置为接收
  142. }
  143. /* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
  144. void UartRxMonitor(unsigned char ms){
  145.     static unsigned char cntbkp = 0;
  146.     static unsigned char idletmr = 0;
  147.     if (cntRxd > 0){  //接收计数器大于零时,监控总线空闲时间
  148.         if (cntbkp != cntRxd){  //接收计数器改变,即刚接收到数据时,清零空闲计时
  149.             cntbkp = cntRxd;
  150.             idletmr = 0;
  151.         }else{                 //接收计数器未改变,即总线空闲时,累积空闲时间
  152.             if (idletmr < 30){  //空闲计时小于30ms时,持续累加
  153.                 idletmr += ms;
  154.                 if (idletmr >= 30){  //空闲时间达到30ms时,即判定为一帧接收完毕        注意这是485协议规定的
  155.                     flagFrame = 1;  //设置帧接收完成标志
  156.                 }
  157.             }
  158.         }
  159.     }else{
  160.         cntbkp = 0;
  161.     }
  162. }
  163. /* 串口中断服务函数 */
  164. void InterruptUART() interrupt 4{
  165.     if (RI){  //接收到新字节           当字节发送到结束位的一半的时候RI接收标志变为1  进入窜口中断
  166.         RI = 0;  //清零接收中断标志位
  167.         if (cntRxd < sizeof(bufRxd)){ //接收缓冲区尚未用完时,保存接收字节,并递增计数器
  168.             bufRxd[cntRxd++] = SBUF;        // cntRxd++这个很重要,一开始 cntRxd < sizeof(bufRxd)当进入函数的次数增加,cntRxd慢慢变大,当传入的数据不满的时候就        用时间检测,判断是否是传输完成
  169.         }
  170.     }
  171.     if (TI){  //字节发送完毕
  172.         TI = 0;   //清零发送中断标志位
  173.         flagTxd = 1;  //设置字节发送完成标志
  174.     }
  175. }
  176. void BaudRate(){//波特率选择
  177.         if((boma1 == 0)&&(boma2 != 0)){ConfigUART(2400);}  //配置波特率为1200        
  178.         if((boma2 == 0)&&(boma1 != 0)){ConfigUART(4800);}  //配置波特率为4800        
  179.         if((boma1 == 0)&&(boma2 == 0)){ConfigUART(9600);}  //配置波特率为9600        
  180.         if((boma1 != 0)&&(boma2 != 0)){ConfigUART1(19200);}//配置波特率为19200        
  181. }

  182. void Delay_us(uint i){ //us延时
  183.         for(;i>0;i--){
  184.                 _nop_();
  185.         }
  186. }
  187. void kabcd(){
  188.         Delay_us(10000);
  189.         if(ka==1){k4val|=0x80;}else{k4val&=0x7f;}
  190.         if(kb==1){k4val|=0x40;}else{k4val&=0xbf;}
  191.         if(kc==1){k4val|=0x20;}else{k4val&=0xdf;}
  192.         if(kd==1){k4val|=0x10;}else{k4val&=0xef;}
  193.         k4num=k4val;
  194.         k4num&=0xf0;
  195. }
  196. void Getch(){//矩阵按键
  197.         k1=0;//矩阵1开始
  198.         ka=kb=kc=kd=k2=k3=k4=1;
  199.         kabcd();
  200.         if(k4num!=0xf0){
  201.                 kabcd();
  202.                 if(k4num!=0xf0){
  203.                         switch(k4num){
  204.                                 case(0x70):keyval=1;keyval1=49;break;//s1                        
  205.                                 case(0xb0):keyval=2;keyval1=50;break;//s2
  206.                                 case(0xd0):keyval=3;keyval1=51;break;//s3
  207.                                 case(0xe0):keyval=4;keyval1=52;break;//s4
  208.                         }
  209.                 }        
  210.         }//矩阵1结束
  211.         k2=0;//矩阵2开始
  212.         ka=kb=kc=kd=k1=k3=k4=1;
  213.         kabcd();
  214.         if(k4num!=0xf0){
  215.                 kabcd();
  216.                 if(k4num!=0xf0){
  217.                         switch(k4num){
  218.                                 case(0x70):keyval=5;keyval1=53;break;//s5                        
  219.                                 case(0xb0):keyval=6;keyval1=54;break;//s6
  220.                                 case(0xd0):keyval=7;keyval1=55;break;//s7
  221.                                 case(0xe0):keyval=8;keyval1=56;break;//s8
  222.                         }
  223.                 }        
  224.         }//矩阵2结束
  225.         k3=0;//矩阵3开始
  226.         ka=kb=kc=kd=k2=k1=k4=1;
  227. ……………………

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

所有资料51hei提供下载:
GYJ-0023_工控设备串口及485调试模块发货资料.rar (4.35 MB, 下载次数: 68)
回复

使用道具 举报

ID:26811 发表于 2018-5-22 11:27 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:228452 发表于 2018-5-27 00:43 | 显示全部楼层
Thank you for schematics and source code
回复

使用道具 举报

ID:413389 发表于 2018-10-22 01:56 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:428400 发表于 2019-11-7 19:01 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

ID:727588 发表于 2020-4-13 09:26 | 显示全部楼层
继续学习,感谢大师分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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