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和單片機串口連接圖
圖中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沒用過,不過最好也連上,防止以後用到。下圖爲各個管腳的輸入輸出狀態:
   
複製代碼

  • #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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章