MSP430与GPRS模块的串口通信硬件流控制

我选用的GPRS模块是西门子的MC52I,由于降低功耗要用到该模块的休眠模式(AT+CFUN=设置具体的休眠模式)。而休眠模式必须先使能RTS/CTS流控制(AT\Q3设置)。MC52I的RTS和CTS引脚直接连在MSP430F149的I/O口上,具体怎么实现流控制还不太明白,请大家多多指教

经过自己研究终于弄懂是怎么个回事了
现在发出来,有不对的地方望大家指正
    MC52I可以通过
AT\Q[num] (num=0/1/2/3)选择不使能流控制(num=0),XON/XOFF软件流控制(num=1),仅模块的CTS有效(num=2)和RTS/CTS硬件流控制四种方式。值得注意的是通常情况下MC52I不需要进行这方面的设置,直接默认为不使能流控制方式,但是当你需要使用MC52I的休眠模式时就必须要设置为RTS/CTS硬件流控制即发送AT指令AT\Q3。此时再发送AT指令AT+CFUN=[num] (num=0/5/6/7/8/9 休眠状态, 1表示全功能状态)设置成相关休眠模式即可。如果仅这样做,当你调试时会发现单片机串口收不到MC52I发送过来的数据,也就是说无法进行通信。这跟RTS/CTS没有设置好有关系。
    下面介绍下modem下的RTS和CTS定义:
    RTS有效(低电平)表示DTE(这里就是单片机)可以收,CTS有效表示modem可以收,这两个信号互相独立,分别表示一个方向的流量情况。具体处理如下(借鉴了别人的描述 dengm 发表于 2005-1-14 07:52 侃单片机)
    单片机端:
        发送数据—— 当发现(不一定及时发现)CTS无效时,停止发送;
        当发现(不一定及时发现)CTS有效时,恢复发送;

        接收数据—— 0<M<N<LEN_OF_RX_BUFFERS
        当接收buffers中的bytes<M 时,给 RTS 有效信号;
        当接收buffers中的bytes>N 时,给 RTS 无效信号;
    modem端:
        同上,但RTS与CTS交换
    在这里modem端我们无需处理,只需要监测CTS的电平即可,针对上述的单片机串口无法接收到数据的问题,使连接RTS的I/O口输出低电平(如果一直设为低电平表示单片机一直允许接收数据,当传输数据非常大的时候会造成数据丢失,因此需要按照上面给出的bytes>N时,使RTS无效),然后再调试就能够发现单片机接收到modem返回的数据了。
 
 
MC52I和单片机串口连接图MSP430与GPRS模块的串口通信硬件流控制_第1张图片
图中TXD、RXD直接连到430单片机上的串口即可,这里需要注意的是MC52I的RXD是发送数据的,TXD是接收数据的。所以要按照图中的RXD连接到单片机的RXD,TXD连接到单片机的TXD。我当时就是没注意连错了害的最后跳线,呵呵。RTS、CTS、DTR、DSR、DCD、RING都直接连到单片机的I/O口上即可,RING最好是连到具有中断功能的I/O口上,因为当MC52I接收到来电信号、短信以及上网传过来的数据时都会引起这个引脚产生中断,可以方便处理。RTS/CTS就是上面用的情况,DTR/DSR、DCD没用过,不过最好也连上,防止以后用到。下图为各个管脚的输入输出状态:
MSP430与GPRS模块的串口通信硬件流控制_第2张图片
   
复制代码

  • #include <msp430x14x.h> 
  • #include "string.h" 
  • //GPRS管脚定义 
  • #define  GPRS_IGT_HIGH  P1DIR|=BIT6,P1OUT|=BIT6//点火引脚 高电平 
  • #define  GPRS_IGT_LOW   P1DIR|=BIT6,P1OUT&=~BIT6//点火引脚 低电平 
  • #define  GPRS_RTS_H  P1DIR|=BIT2,P1OUT|=BIT2  //RTS输出高电平 
  • #define  GPRS_RTS_L  P1DIR|=BIT2,P1OUT&=~BIT2 //RTS输出低电平 
  • #define  GPRS_CTS_FLAG  P1DIR&=~BIT4         //设置CTS线为输入线 
  • #define  GPRS_CTS  (P1IN&BIT4) 

  • #define  Len 150 
  • typedef       unsigned int uint; 
  • typedef      unsigned char uchar; 

  • char recieve_data[150]; 
  • uint count = 0; 
  • uchar send_error = 0; 
  • //****************************************************** 
  • //延时函数 
  • void delay(uint time) 
  •   uint i,j; 
  •   for(i=0;i<1000;i++) 
  •     for(j=0;j<time;j++); 
  • //****************************************************** 
  • //初始化时钟 
  • void int_clk() 
  •     uchar i = 0; 
  •     BCSCTL1&=~XT2OFF;                 //打开XT振荡器 
  •     BCSCTL2|=SELM1+SELS;//MCLK 8M and SMCLK 1M   
  •     do 
  •      { 
  •         IFG1 &= ~OFIFG;                 //清除振荡错误标志 
  •         for(i = 0; i < 100; i++) 
  •        _NOP();                                   //延时等待 
  •         } 
  •     while ((IFG1 & OFIFG) != 0);                //如果标志为1继续循环等待 
  •     IFG1&=~OFIFG; 

  • //******************************************************* 
  • //串口:初始化函数,接收中断处理函数、发送数据函数 
  • //******************************************************* 
  • //初始化串口1 
  • void init_Usart1() 
  • {   
  •   U1CTL |= SWRST;                    //复位串口 
  •   U1CTL |= CHAR;                     //8位数据 
  •   U1TCTL |= SSEL1;                    //选择SMCLK作为时钟信号 
  •   UBR01 = 0x8a;                 
  •   UBR11 = 0x00;                       //使32KHz晶振时波特率为19200bps 
  •   UMCTL1 = 0xde;                       
  •   ME2 |= 0x30;                         //UART接收模块允许 
  •   UCTL1 &= ~SWRST;                  //SWRST复位,USART允许 
  •   IE2 |= URXIE1;                       //接收中断允许 
  •   P3SEL = 0xC0;                        //P3.6 P3.7 
  •   P3DIR = 0X40;                        //P3.6 输出,P3.7 输入   
  • //****************************************************** 
  • //串口1中断服务处理函数 
  • #pragma vector=UART1RX_VECTOR 
  • __interrupt  void UART1_RX_ISR(void) 
  •   char data = 0; 
  •   data = U1RXBUF; 
  •   recieve_data[count++] = data; 
  •   if(count>149) 
  •   { 
  •     count=0; 
  •   } 

  • //发送一个字符 
  • void SendByte(uchar data) 
  •   while((IFG2&UTXIFG1)==0);//判断发送缓冲区是否结束 
  •   U1TXBUF=data;   
  • //****************************************************** 
  • //清楚接收存储区内容 
  • void GPRS_Clearstring() 
  •       uchar len=0; 
  •       count=0; 
  •       //关闭中断 
  •       IE2 &= ~URXIE1;//禁止接收中断 
  •       for(;len<Len;len++) 
  •        recieve_data[len]='\0'; 
  •       //使能中断 
  •       IE2|=URXIE1;//使能接收中断 

  • //****************************************************** 
  • //将命令写入usart数据寄存器 
  • void Send_Data(char * strptr) 
  •   uchar i,j; 
  •   j = strlen(strptr); 
  •   for(i=0;i<j;i++) 
  •   { 
  •     SendByte(strptr[I]); 
  •   }                              

  • //******************************************************** 
  • //GPRS模块:启动函数、关闭函数、初始化函数 
  • //******************************************************** 
  • //GPRS启动函数 
  • void GPRS_Start(void) 
  •   GPRS_IGT_HIGH; 
  •   delay(1); 
  •   GPRS_IGT_LOW; 
  •   delay(100); 
  •   GPRS_IGT_HIGH; 

  • //****************************************************** 
  • //GPRS关闭函数 
  • void GPRS_Close(void) 
  •   delay(100); 
  •   Send_Data("AT^SMSO\r\n"); 
  •   delay(100); 

  • //****************************************************** 
  • //GPRS初始化函数 
  • void GPRS_Init(void) 
  •   Send_Data("AT\\Q3\r\n");//设置成RTS/CTS硬件流控制模式 
  •   delay(1000); 
  •   Send_Data("ATE0\r\n"); //关闭回显 
  •   delay(100); 
  •   Send_Data("AT+CMGF=1\r\n");//采用文本方式 
  •   delay(100); 
  •   Send_Data("AT+CFUN=7\r\n");//设置循环功耗节省模式7 
  •   delay(100); 
  •   Send_Data("AT+CFUN\?\r\n");//用于查询设置模式是否成功 
  •   delay(100); 

  • //****************************************************** 
  • //发送短信函数 
  • //****************************************************** 
  • void SendMessage(char *num,char *massge) 
  •   char instuct[]="AT+CMGS=\""; 
  •   char numinstuct[27]; 
  •   strcpy(numinstuct,instuct);       //字符串拷贝函数 
  •   strcat(numinstuct,num);           //字符串连接函数 
  •   strcat(numinstuct,"\"\r\n"); 
  •   Send_Data(numinstuct);            //AT+CMGS=\"13607088025\" 发送接收终端号码 
  •   Send_Data(massge);                //发送短信内容 
  •   SendByte(0x1a);                   //相当于Ctrl+Z 

  • //*********************************************************** 
  • //主函数:启动GPRS模块,设置为循环低功耗 
  • //模式(AT+CFUN=8),发送一条短信,关闭GPRS模块 
  • //*********************************************************** 
  • void main() 
  •   WDTCTL=WDTPW+WDTHOLD;//关闭看门狗 
  •   int_clk();           //系统时钟初始化 
  •   init_Usart1();       //初始化串口 

  •   GPRS_RTS_L;          //设置RTS为低电平,表示单片机一直可以接收数据 
  •                        //如果发送数据很大,请按照之前描述的对RTS进行适当处理 
  •   GPRS_Start(); 
  •   _EINT();//使能中断 
  •   delay(2000); 
  •   GPRS_Init(); 
  •   Send_Data("AT\r\n");//发送个AT测试下 
  •   SendMessage("13612345678","hello");//发送短信 
  •   GPRS_Close();//关闭模块 
  •   while(1); 
  • }

转自:http://bbs.21ic.com/icview-285499-1-1.html

你可能感兴趣的:(MSP430与GPRS模块的串口通信硬件流控制)