下面是下位机的主机源代码:
- /***************************************************************************
- 函数名称: AM2301多机通信主机部分
- 主控芯片: STC12C5A60S2,晶振11.0592MHz
- 功 能: 和从机及上位机通信,接收从机发送过来的温湿度,用1620显示出来并
- 将数据传送到上位机
- 创建日期: 2011.5.22
- 修改日志: 无
- ****************************************************************************/
- //#include <reg52.h>
- #include <STC12C5A.h>
- #include <intrins.h>
- #include "LCD1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define _Nop() _nop_()
- sbit RDE =P3^2; // 485控制输入输出控制(与从机)
- sbit RDE2=P1^4; //485控制输入输出控制(与上位机)
- #define SlaveNum 2 //从机数量
- uchar code dis1[]={"H: % T: C"} ;
- uchar code dis2[]={"h: % t: c"} ;
- #define num 8 //缓冲数据的长度
- char Revdata[num];//接收到的数据缓存
- uchar SLAVE_ID = 1;//从机地址
- uchar rc;//串口1接收到和数据缓存
- uchar Rev;//串口2接收数据
- //----------------------------------------
- uchar state = 0;//状态标志位。1-进入等待从机回应,2-更新显示数据
- uchar recv_length = 0;
- bit recving_flag = 0;
- bit recfinish=0;
- bit recflag=0;
- bit minusflag=0,addflag=0,stopflag=0;
- //----------------------------------------
- ////////////////////////////////////////////////////////////////////////
- //////////////////延时函数///////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- void Delay(unsigned int t)
- {
- while(t--);
- }
- /////////////////////////////////
- void Delay_10us(unsigned int us)
- {
- do{
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }while(--us);
- }
- //////////////////////////////////
- void Delay_ms(unsigned int ms)
- {
- do Delay_10us(131);
- while(--ms);
- }
- ////////////////////////////////////////////////////////////////////////
- //////////////////////串口1发送地址函数//////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- void senda(unsigned char adra) //发送地址
- {
- TB8 = 1;//发送地址帧
- RDE = 1;//允许发送
- Delay_10us(50);
- ES=0; //关串1口中断
- TI = 0; //清标志位
- SBUF = adra;
- while(!TI);
- TI = 0;//等待发送完毕
- ES=1; //开串口1中断
- RDE = 0;//485允许接收
- Delay_10us(50);
- }
- ////////////////////////////////////////////////////////////////////////
- //////////////////////串口1发送数据函数//////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /**/
- void sendata(unsigned char tdata) //发送地址
- {
- TB8=0;//发送数据帧
- RDE = 1;//允许发送
- TI = 0;
- SBUF = tdata;
- while(!TI);
- TI=0;
- RDE = 0;//485允许接收
- }
- //////////////////////////////////////////////////////////////////////
- //////////////////////串口2发送数据函数///////////////////////////////
- //////////////////////////////////////////////////////////////////////
- void Uart2_senbyte(uchar val)
- {
- RDE2=1;//485发送状态
- // Delay(50);
- IE2=0x00;//关串口2中断
- S2BUF=val;
- while ((S2CON & 0x02) == 0); //等待发送完毕
- S2CON &= 0xFD; //清标志位(S2TI=0)
- IE2=0x01;//开串口2中断
- RDE2=0;
- // Delay(50);
- }
- ////////////////////////////////////////////////////////////////////////
- ///////////////////////////////显示函数/////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- ///////////显示字符///////
- void showchar()
- { uchar string;
- //====显示字符1======
- string=0;
- writecmd(0x80);
- while(dis1[string] != '\0')//显示字符
- {
- writedata(dis1[string]) ;
- string++ ;
- }string = 0 ;
- //=====显示字符2=====
- writecmd(0xc0);
- while(dis2[string] != '\0')//显示字符
- {
- writedata(dis2[string]) ;
- string++ ;
- }string = 0 ;
- }
- //////////////显示数据/////////////
- void showdata()
- {
- if(SLAVE_ID==1)
- {
- //=====显示湿度=====
- writecmd(0x82);
- writedata(Revdata[1]+0x30);
- writedata(Revdata[2]+0x30);
- writedata('.');
- writedata(Revdata[3]+0x30);
- //=====显示温度=====
- writecmd(0x8b);
- writedata(Revdata[4]+0x30);
- writedata(Revdata[5]+0x30);
- writedata('.');
- writedata(Revdata[6]+0x30);
- Delay_ms(400);
- }
- if(SLAVE_ID==2)
- {
- //=====显示湿度=====
- writecmd(0xc2);
- writedata(Revdata[1]+0x30);
- writedata(Revdata[2]+0x30);
- writedata('.');
- writedata(Revdata[3]+0x30);
- //=====显示温度=====
- writecmd(0xcb);
- writedata(Revdata[4]+0x30);
- writedata(Revdata[5]+0x30);
- writedata('.');
- writedata(Revdata[6]+0x30);
- Delay_ms(1000);
- }
-
- }
- ////////////////////////////////////////////////////////////////////////
- ///////////////////串口初始化函数////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- void UARTinit()
- {
- //串口1初始化/////////
- TMOD|=0x21;//定时器1工作在方式2,定时器0工作在方式1
- TH1=0xfa;TL1=0xfa; //波特率9600
- SCON=0x50;//SCON:SM0,SM1,SM2,REN,TB8,RB8,TI,RI
- PCON|=0x80;//波特率倍增
- TR1=1;//开定时器1
- EA=1;//开总中断
- ES=1;//串口1中断
- //--------------------//
- //串口2初始化///////////
- BRT = 0XDC; //设置独立的波特率发生器的重载数值,此数值的波特率为9600
- AUXR = 0X14; //设置波特率的发生方式(允许波特率发生器运行,波特率不加倍,每个时钟计数一次)
- S2CON|=0x50;//串口2,方式1,允许接收
- IE2|=0X01;//允许串口2中断
- EA=1;//开总中断
- //--------------------//
- Delay(10000); //热机时间
- init_LCD(); //初始化液晶
- }
- //==========================================
- ////////////////////////////////////////////////////////////////////////
- ///////////////////////////////主函数///////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- void main()
- {
- // uchar i;
- UARTinit();//串口初始化
- Delay(40000);//热机
-
- while(1)
- {
- WDT_CONTR=0x3c;//启动看门狗,超过该时间未能喂狗则系统复位,
- //0011.1011---WDT_FLAG=0,EN_WDT=1,CLR_WDT=1,IDLE_WDT=0,PS2=1,PS1=1,PS0=0
- //IDLE_WDT=1时,"空闲模式"计数,IDLE_WDT=0时"空闲模式"不计数
- //0x38-71.1ms,0x39-142.2ms, 0x3a-284.4ms, 0x3b-568.8ms,
- //0x3c-1.1377s,0x3d-2.2755s,0x3e-4.5511s,0x3f-9.1022s
- showchar();//显示字符
- if(state == 0)
- {
-
- senda(SLAVE_ID++);
- if(SLAVE_ID>SlaveNum)SLAVE_ID = 1;
- if(addflag==1&&SLAVE_ID==1){sendata(0xf1);addflag=0;}//发送指令给从机1
- if(minusflag==1&&SLAVE_ID==2){sendata(0xf2);minusflag=0;}//发送指令给从机2
- if((stopflag==1&&SLAVE_ID==1)||(stopflag==1&&SLAVE_ID==2))
- {stopflag=0,sendata(0xf0);} // 发哦能够停止指令给从机1、2
-
- Delay_ms(30);
- state = 1;// 状态转为等待从机应答,在串口中断
- /* if(recfinish==1)
- { recfinish=0;
-
-
- if(recflag == 0)
- {// recflag =0;
- // senda(SLAVE_ID);
- senda(SLAVE_ID++); Delay_ms(4000);
- if(SLAVE_ID>SlaveNum)
- {
- SLAVE_ID = 1;
- senda(SLAVE_ID);
- Delay_ms(4000);
- }
-
- }//end of recving_flag =0
- }//end of recfinish=1
- */
- } //end of state=0
-
- if(state == 2) // 状态 转为 显示
- {
- showdata();//更新数据显示
- Delay_ms(800);
- //发送数据到上位机
- Uart2_senbyte('R');//上位机识别湿度的标志
- Uart2_senbyte(Revdata[1]+0x30);//
- Uart2_senbyte(Revdata[2]+0x30);
- Uart2_senbyte('.');
- Uart2_senbyte(Revdata[3]+0x30);
- Uart2_senbyte('T');//上位机识别温度的标志
- Uart2_senbyte(Revdata[4]+0x30);
- Uart2_senbyte(Revdata[5]+0x30);
- Uart2_senbyte('.');
- Uart2_senbyte(Revdata[6]+0x30);
- if(SLAVE_ID==1)Uart2_senbyte('A');//上位机识别从机的标志
- if(SLAVE_ID==2)Uart2_senbyte('B');
- /* ////////////////////////////////////////////////////////////////
- for(i = 1; i<num-1; i++)
- {
-
-
- senda(Revdata[i]); //把收到的数据往PC机回送(串口助手调试用)
- Delay_ms(20);
- }
- */ ////////////////////////////////////////////////////////////////
- Delay_ms(20);
- state = 0; // 状态转为0,重新查询从机
- }//end of state=2
- WDT_CONTR=0x3c;//喂狗,若超过时间不喂狗,则系统复位
- }//end of while(1)
-
-
- }//end of main()
- ////////////////////////////////////////////////////////////////////////
- ///////////////////串口 1接收 中断 函数//////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- void Recv_int(void)interrupt 4 //using 2
- {
- RDE=0;
- if(RI)
- {
- RI=0;
- rc=SBUF;
-
- if(state==1)
- {
-
- if((recv_length == 0)&&(rc == 0xf7 ) ) //这里判断发送的第一个字节
- {
- recving_flag = 1;
- recflag=1;
- }
-
- if(recving_flag == 1)
- {
- Revdata[recv_length++] = rc;
- if(rc == 0xf3)//判断结束帧
- {
- recv_length = 0;
- recving_flag = 0;
- recfinish=1;
- state = 2; //接收完毕,置标志位,准备显示
- }//end of rc=0xf3
-
- }//end of recving_flag = 1
-
- }//end of state=1
-
- }//end of RI
-
- }//end of interrupt
- //////////////////串口2中断服务子程序////////////////////////////
- void Uart2() interrupt 8 //using 1
- {
- RDE2=0;//485保持为接收状态
- if (S2CON & S2RI)
- {
- S2CON &= ~S2RI; //清除接收完成标志
- Rev = S2BUF;
- switch(Rev)
- {
- case 'a': //加大湿度
- addflag=1;
- break;
- case 'm': //降低湿度
- minusflag=1;
- break;
- case 's': //停止
- stopflag=1;
- break;
- default:
- break;
- }//end of swtich
- } //end of if
-
- RDE2=1;//485允许发送
-
- }
- ////////////////////////////////End/////////////////////////////////////
复制代码 |