新闻  |   论坛  |   博客  |   在线研讨会
单片机控制GSM模块/GPRS工业模块的远程监控系统的设计C程序
szyth | 2008-08-15 10:50:58    阅读:1802   发布文章

随着移动通信的发展,手机在人们的生活中变得越来越普及,对人们的生活的影响越来越大。使用移动通信网络的SMS(短消息)/GPRS(通用分组无线业务)工业模块(即手机模块)在工业现场使用的越来越广泛,尤其是在远程监控领域更是得到了广泛的应用,比如北京08奥运场馆的火灾监控系统、泰山旅游景区的火灾监控系统、很多大中城市的公交车/出租车管理系统等等都使用了SMS/GPRS工业模块。随着移动通信网络的服务质量进一步提高,短消息延迟的进一步减小、GPRS资费进一步下调,手机模块必将得到更为广泛的使用。
手机在大学生中特别是在高年级大学生中基本已经普及,用单片机控制手机模块发短信、发送GPRS信息必将会提升他们极大的兴趣。本实验有助于电子信息类专业学生加深对电子电路的理解、对单片机的理解、对TCP/IP协议的理解、对移动通信相关知识的理解以及对使用可视化软件开发工具进行上位机开发的相关知识的理解。手机模块内置了短消息及GPRS的协议,对外接口仅为一UART串口,使用AT指令通过串口与外界交互,所以开发难度适中,有利于实现。能完整的做完本实验将会积累一定的工程经验,对学生找工作将会增加一个很重的砝码。
一、硬件设计方案
采用单片机+通信模块的形式,另外加4×3键盘和12864中文液晶作人机接口,如下图所示。
电路原理图如下图所示:
1、电源部分
系统采用5V/2A电源供电,带有电源指示LED。5V电源直接供给液晶,5V电源经LM1117-3.3产生3.3V电压供给单片机和MAX3232,5V电源经两个二极管降压后产生3.6V电压供给通信模块基频电源,此电源经II型滤波电路供给通信模块射频电源。
2、单片机最小系统
如下图所示
晶振采用22.1184M,复位采用上电复位与手动复位相结合的方式,带有一路测试用LED,测试LED接在P1.6上,低电平点亮。
3、串口通信电路
如下图所示
4、串口跳线电路
由于通信模块要使用串口,下载程序要使用串口,而单片机只有一个串口,所以必须有一定的逻辑控制,跳线电路如下图所示
下载程序时需短接23,56;单片机与通信模块通信的时候需短接34,78;PC与通信模块通信的时候需短接12,67。
5、键盘接口电路
如下图所示
 
三条行线分别接在P2.0-P2.2上,四条列线分别接在P2.4-P2.7上。
6、通信模块接口电路
如下图所示
电路设计了开机指示LED,开机后会以大约1HZ的频率闪烁,表示接入网络,此闪烁不受单片机控制,启动信号接在P0.0上。
7、液晶电路
如下图所示
片选信号接在P1.2上,时钟信号接在P1.4上,数据信号接在上P1.3上。
二、软件方案
1、串口部分
初始化部分
void  UartInit()
 {
 PCON=0x00;
 SCON=0x50;
 T2CON=0x30;
 RCAP2H=0xff;
 RCAP2L=0xb8;       //9600
 TR2=1;
 IP=0x10;//串口中断优先级最高
 ES=1;
 EA=1;
 }
中断接收部分
UartInt() interrupt 4
{
 RI=0;
 ReceiveBuffer[RecPointer%80]=SBUF;
 RecPointer++;
}
2、液晶显示部分
void sendBYTE(uchar dat)/*串行传送一字节数据*/
{
      uchar i;
      for (i=0;i<8;i++)
      {
          CLK = 0;
          if ((dat & 0x80)!=0)
          SID = 1;
          else 
          SID = 0;
          CLK = 1;
          dat = dat<<1;
      }
}
void sendCMD(uchar dat)/*写控制指令*/
{
      _CS = 1;
      sendBYTE(0xf8);
      sendBYTE(dat & 0xf0);
      sendBYTE((dat<<4)&0xf0);
      _CS = 0;
}
void sendDAT(uchar dat)/*写显示数据;也可以写一个单字节字符*/
{
      _CS = 1;
      sendBYTE(0xfa);
      sendBYTE(dat & 0xf0);
      sendBYTE((dat<<4)&0xf0);
      _CS = 0;
}
void display(uchar x_add,uchar *dat)
/*写汉字到LCD屏指定位置*/
/*x_add 显示RAM地址*/
/*dat/dat1 显示汉字编码*/
{      
      sendCMD(x_add);
         while(*dat)
        {
      sendDAT(*(dat++));
        }
        
}
 
void initlcm(void)/*初始化LCM*/
{
      sendCMD(0x30);/*功能设置:一次送8位数据,基本指令集*/
      sendCMD(0x04);/*点设定:显示字符/光标从左到右移位,DDRAM地址加一*/
      sendCMD(0x0e);/*显示设定:开显示,显示光标,当前显示位反白闪动关*/
      sendCMD(0x01);/*清DDRAM*/
      sendCMD(0x02);/*DDRAM地址归位*/
      }
3、按键扫描部分
uchar scankey()
{
 uchar keyvalue ,keyvalue1 ,i;
 
 for(i=0;i<3;i++) //第一次扫描
 {
   if(i==0)   //第一行
      P2=0xfe;
   if(i==1)   //第二行
      P2=0xfd;
   if(i==2)   //第三行
      P2=0xfb;
 //delay(10);
 keyvalue=P2;
 keyvalue&=0xf0;
 keyvalue>>=4;
 switch(keyvalue)
  {
  case 0x0e:keyvalue=0;break;
  case 0x0d:keyvalue=1;break;
  case 0x0b:keyvalue=2;break;
  case 0x07:keyvalue=3;break;
  default:     keyvalue=0x55;break;
  }
  if(keyvalue==0x55)  continue;    //本行无键按下继续扫描
  else 
    {
     keyvalue=keyvalue+i*4;
       break;                                //本行有键按下跳出扫描
       }
      
 }
 
   if     (keyvalue==0x55 ) return 0xaa;//没有键按下
   else //有键按下   第二次扫描
   { 
     //LED=~LED;
       delay(35000) ;      
         for(i=0;i<3;i++)
     {
       if(i==0)     //  第一行
          P2=0xfe;
       if(i==1)    // 第二行
          P2=0xfd;
       if(i==2)    // 第三行
          P2=0xfb;
 // delay(10);
       keyvalue1=P2;
       keyvalue1&=0xf0;
       keyvalue1>>=4;
         switch(keyvalue1)
              {
                case 0x0e:keyvalue1=0;break;
                case 0x0d:keyvalue1=1;break;
                case 0x0b:keyvalue1=2;break;
                case 0x07:keyvalue1=3;break;
                default:  keyvalue1=0x55;break;
              }
          if(keyvalue1==0x55)  
                     continue;  //本行无键按下继续扫描
          else 
               {
                keyvalue1=keyvalue1+i*4; 
               break;                                          //本行有键按下跳出扫描
                 }   
       }
         if(keyvalue==keyvalue1)
        {    LED=~LED;
           return keyvalue;} //两次扫描结果一致
       else       
           return 0xaa;
    }  
}
4、呼叫部分
void dial()
{
 uchar i;
 display(0x80,"请输入对方号码:");
 display(0x90,"(以#结束)");
 
 ReadKey(thirdadd);
 
  while(1)
  {
  SendString("ATD");
  ES=0;
  for(i=0;i<KeyPointer;i++)
  {
  SBUF=KeyBuffer[i]      ;
  while(TI==0) ;   TI=0;
  }
  SBUF=’’;’’  ;
  while(TI==0) ;   TI=0;
  SBUF=0x0d   ;
  while(TI==0) ;   TI=0; 
  SBUF=0x0a    ;
  while(TI==0) ;   TI=0;
   if(CheckAck())
   break;
  }
  display(fourthadd,"嘟………");
  KeyPointer=0;
    TR0=1;
   Timer0IntCount=0;
   ES=1;
  while(Timer0IntCount<30000)       //300s
   {
      
     if(strstr(ReceiveBuffer,"BUSY"))
       {
       display(fourthadd,"对方忙!");
       break;
       }
        if(strstr(ReceiveBuffer,"ANSWER"))
        {
       display(fourthadd,"无应答!");
       break;
       }
        if(strstr(ReceiveBuffer,"CARRIER"))
        {
       display(fourthadd,"号码有误!");
       break;
       }
   }
   Timer0IntCount=0; 
  while(Timer0IntCount<300);   //3s
   ES=0;
   TR0=0;
}
5、短信部分
void SMS()
 {
   uchar DesNumEndAdd,i;
   display(0x80,"请输入对方号码:");
   display(0x90,"(以#结束)");
   ReadKey(thirdadd);
   DesNumEndAdd=KeyPointer;//按键数据接收缓冲区中,
   if(DesNumEndAdd!=11)
   {
   display(fourthadd,"输入号码有误!");
    TR0=1;
   Timer0IntCount=0;
  while(Timer0IntCount<300)  ;  //3s
   TR0=0;  //关定时器0
   KeyPointer=0;
   return;
   }
 
   sendCMD(0x01);/*清DDRAM*/
   delay(200);
 
   display(0x80,"请输入短信内容:");
   display(0x90,"(以#结束)");
   ReadKey(thirdadd);
 
   while(1)
 {  
 SendATCMD("AT+CMGF=1"); 
   if(CheckAck())
   break;
   }
 
     while(1)
 {  
 SendATCMD("AT+CSCS=\"GSM\""); 
  if(CheckAck())
   break;
   }
 
        while(1)
 {  
 SendATCMD("AT+CSMP=17,168,0,0"); 
  if(CheckAck())
   break;
   }
 
     SendString("AT+CMGS=\"+86");
      ES=0;
     for(i=0;i<DesNumEndAdd;i++)
     {
           SBUF=KeyBuffer[i]  ;
           while(TI==0) ;   TI=0; 
     }
            SBUF=’’"’’;
          while(TI==0) ;   TI=0;
 
  SBUF=0x0d   ;
  while(TI==0) ;   TI=0; 
  SBUF=0x0a    ;
  while(TI==0) ;   TI=0;
  delay(20000);// 等待‘<’
 
            for(i=DesNumEndAdd;i<KeyPointer;i++)  
     {
           SBUF=KeyBuffer[i]  ;
           while(TI==0) ;   TI=0; 
     }
                delay(2000);//
             SBUF=0x1a;
           while(TI==0) ;   TI=0;
                KeyPointer=0;
                 sendCMD(0x01);/*清DDRAM*/
       delay(200); 
     display(secondadd+2,"发送成功!");
    TR0=1;
   Timer0IntCount=0;
  while(Timer0IntCount<300)  ;  //3s
   TR0=0;  //关定时器0  
 }
6、GPRS部分
单片机控制GSM模块的远程监控系统的设计C程序

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客