摘要
隨著手機的廣泛使用,GSM網絡提供的短消息服務使得只需要增加少量投入便可以通過手機實現生活和生產中的遠程控制和告警通知成為可能。
本設計是基于32位LPC2138的一種短信收發系統。本系統主要實現英文短信收發。此方案以LPC2138為主控制器輔以GSM/GPRS模塊SIM900A,液晶屏1602等硬件,通過C語言編寫程序,用軟硬件結合的方法實現編輯三條短信,按一次鍵,發送一條短信,且顯示在LCD上,發送后收到反饋,且有收信息功能,收到短信后顯示在LCD上。
目錄
一、原理與總體方案 3
⒈總體方案 3
二、軟件與硬件設計 3
⒈元器件 3
2.模塊的介紹和功能 4
三、仿真與調試 6
⒈ 仿真 6
2. 調試 7
四、遇到的問題 9
五、心得體會 9
附錄 程序代碼
一、 原理與總體方案根據任務要求,設計一個按鍵按第一次就發送第一條編寫好的短信,按第二次則發送第二條編寫好的短信,按第三次就發送第三條短信,且顯示在LCD上,發送后收到反饋,且有收信息功能,收到短信后顯示在LCD上。即用LPC2138通過串口發出AT指令給SIM900a,使之發送短信給程序中設置好的電話,當用手機回復短信時,SIM900a收到短信內容且反饋給LPC2138,LCD上顯示其回復內容。
二、軟件與硬件設計
⒈元器件 如表1:
表1 ①Lpc2138特性和引腳功能:Philips公式的32位ARM7微控制器lpc2138具有強大的儲存空間,內嵌有32KB片內靜態ARM和512KB的Flash存儲器,可以實現在系統可編程(ISP),在應用可編程(IAP);2個8路10位A/D轉換器,1個D/A轉換器,轉換迅速準確;引腳資源豐富,多達47個可承受5V的通用I/O口;多個串行接口,包括2個16C550工業標準的UART,2個高速12C借口,SPI,以及具有緩沖作用和數據長度可變功能的SSP協議,lpc2138可以移植u C/COII操偶做系統,軟件的可移植性好,工作可靠。(如圖2) 圖2 管腳說明:V3、VBAT、VREP、供電電壓 VSS、VSSA、接地 p0.0,p0.1作為串口通信接口 p1.16-p1.26作為LCD顯示電路接口 p0.9作為按鍵接口
串口初始化:波特率設置為9600bps,8位數據位,一位停止位,無奇偶校驗位,無硬件流控制,用于與上位機通信。串口2波特率為115200bps,8位數據位,一位停止位,無奇偶校驗位,無硬件流控制,用于與GSM模塊通信。
②LCD的特性說明: LCD 顯示屏(圖3)可以采用字符顯示,當使用字符顯示方式時可以直接用外碼作為輸入數據,由顯示屏自動給出顯示字模數據而無需由微處理器提供字模。 
圖3
③SIM900a通信模塊 SIM900a工作的頻段為:EGSM900MHz和DCS 1800MHz。具有以下優點:鍵盤和SPI顯示接口可以讓使用者很靈活地設計定制應用;主串口和調試串口可以幫助用戶輕松地進行開發應用;一路音頻接口,包含一個麥克風輸入和一個揚聲器輸出;可編程的通用輸入/輸出接口( GPIO)。 SIM900a內嵌TCP/IP協議,擴展的TCP/IP AT命令讓使用者能夠很容易使用TCP/IP協議,這些在使用者做數據傳輸方面的應用時非常有用。 SIM900a的主要特性(如圖4) 圖4 SIM900a主要特性 SIM900A模塊初始化之前,先給模塊上電,由于SIM900A模塊在啟動注冊時,電流峰值會達到2A@4V,所以模塊是由12V 1A電源適配器供電的,避免由于模塊功耗的突升,造成的死機或啟動不起來。上電后,長按啟動按鍵,實現模塊的開機。在模塊開機后,模塊上的指示燈,先是快閃,如果手機注冊成功后,指示燈會慢閃。如果長時間快閃沒有變成慢,應長按啟動鍵會關機模塊,檢查天線, SIM卡片的固定情況,還有檢查SIM卡片是否能正常使用。當模塊指示燈變為慢閃時證明網絡注冊成功可以使用了。SIM900A實物如圖,在與單片機通信之前,我們可以通過電腦串口與SIM900A模塊通信調試,來檢測模塊是否能正常工作。 圖5 SIM900a實物 對外接口包括:RS232接口,語音接口,控制線接口、SIM卡接口等。
三、仿真與調試
1.仿真
Proteus實時仿真(如圖5-圖8)  圖5 圖6 圖7 圖8 2.調試 實物圖圖9 圖9 發短信 圖10 發短信 圖11 收短信 圖12 手機短信的接收與發送 四、遇到的問題在仿真的時候,老師說可以用虛擬串口與SIM900a連接來仿真,但是我們弄了很久都不行,指令并沒有從LPC2138發出去,最后就不了了之了,我們直接去進行了硬件的連接。一開始我們是準備用LPC2138板子上的RS232與SIM900a上的RS232電平接口相接來傳遞指令,之后才發現完全不對,我們用串口通信就應該直接用p0.0,p0.1與SIM900a的5V/3.3VTTL電平接口連接。最后把程序燒錄進去,給LPC2138和SIM900a供電后就實現了短信收發。 五、心得體會兩周的嵌入式課程設計結束了,雖然這次的時間比較短,但我卻收獲了很多。在課程設計一開始,由于嵌入式方面的理論知識是我們上學期期末學的,我又幾乎一點不懂,所以我幾乎不知道怎么入手。我通過上網查資料和請教老師,終于弄懂了它的原理以及通訊過程。但最困難的是寫程序這一部分,我通過看書,請教同學,很艱難的弄懂了一些皮毛。通過這次 ARM 課程設計,我對整個嵌入式程序的設計有了一定的理解,特別是有關函數調用這塊,老師發了一些模板,里面有很多的函數模板,我們只需要調用它就可以了。總之,這次課程設計不但讓我學到了很多的東西,提高了嵌入式方面的知識,同時也增強了我的動手能力,讓我知道了ARM世界是多么的神秘,我所學習的這些知識不過是九牛一毛。最后,感謝老師在課程設計中給予的幫助,以及組員們的通力合作。 - #include "Config.h"
- #include "Target.h"
- #include "UART.h"
- #include "lcd1602.h"
- #include "eint.h"
- #include "string.h"
-
-
- /****************************************************************************
- ** 函數名稱:Delay10MS()
- ** 函數功能:長軟件延時。
- ** 入口參數:dly 延時參數,值越大,延時越久 ****************************************************************************/
- void Delay10MS (uint32 dly)
- { uint32 i;
- for ( ; dly>0; dly--)
- for (i=0; i<34000; i++);
- }
- void Delay10MS (uint32 dly)
- { uint32 i;
- for ( ; dly>0; dly--)
- for (i=0; i<34000; i++);
- }
-
- //SIM900初始化函數
- uint8 SIM900Init(void)
- {
- //SendAT("ATE0\r\n","OK",2);//關閉回顯
- SendAT("AT+CSCS=\"GSM\"\r\n","OK",5);
- SendAT("AT+CMGF=1\r\n","OK",5);
- SendAT("AT+CNMI=2,1\r\n","OK",2);
- if(SendAT("AT+CMGD=1\r\n","OK",5)==0)
- {
- return 0;
- }
- return 1;
- }
-
-
- //發送AT指令函數
- //str :發送AT指令
- //target_str:期待收到的正常的字符串
- //time:最大允許時間S
-
- uint8 SendAT(uint8 *str,uint8 *target_str ,uint32 time)
- {
- uint8 *p=NULL; //00000000000000000000000000
- time = time*10; //將time的值轉換為100ms為刻度
- clear_recive_str();
- if((uint32)str <0xFF)
- {
- UART0_SendByte((uint8)str);
- }
- else
- {
- UART0_SendStr(str);
- }
- while(p==NULL)
- //0000000000000000
- {
- time--;
- Delay10MS(10);
- p=strstr((char *)recive_structure.recive_str,(char *)target_str);
- 收索字符串里面有沒有目標字符串 兩個變量
- if(time ==0 )
- return NULL;
- }
- return 1;
- }
-
-
-
- //短信發送函數
- uint8 sendMsg(uint8* str)
- {
- uint8 reslut =0;
- clear_recive_str();
- UART0_SendStr("AT+CMGS=\"15223191698\"\r\n");
- Delay10MS(10);
- clear_recive_str();
- UART0_SendStr(str);
- reslut=SendAT((uint8 *)0x1a,"OK",5);
- return reslut;
- }
-
- uint8 Msg[50];
-
-
- uint8 getMsg() //00000000000000
- {
- uint8 *p_start=NULL;
- uint8 *p_end = NULL;
- uint8 *temp=NULL;
- uint8 lenth=0;
-
- uint8 i =0;
- temp = (uint8 *)strstr((char *)recive_structure.recive_str,"OK"); //0000000000000000
-
- // temp = (uint8 *)strstr((char *)"+CMGR: \"REC
- READ\",\"+8613896155321\",\"\",\"18/01/03,19:11:39+32\"\r\naaaa\r\nOK","OK");
- if(temp!=NULL)
- {
- do
- {
- temp--;
- if(*temp!='\r'&&*temp != '\n')
- {
- p_end = temp;
- p_end++;
- do
- {
- temp--;
- if(*temp=='\r'||*temp == '\n')
- {
- p_start =temp+1;
- }
- }
- while(1);
- break;
- }
- }
- while(1);
- lenth = p_end-p_start;
- for(i=0;i<lenth;i++)
- {
- Msg[i] = *(p_start+i);
- }
- Msg[i]=NULL;
-
- return 1;
- }
- return 0;
-
- }
-
-
-
- void clear_Msg()
- {
- uint8 i =0;
- for(i=0;i<50;i++)
- {
- Msg[i] =0;
- }
- }
- uint8 a=0;
-
- /****************************************************************************
- * 函數名稱:main()
- * 功能描述: 向串口UART0發送字符串
- ****************************************************************************/
- int main(void)
- {
- uint8 last_a=a;
-
-
- PINSEL0 &= 0xFFFFFFF0;
- PINSEL0 |= 0x00000005; // 設置I/O連接到UART0
-
-
- UART0_Init(); // 調用自定義函數從UART0發送數據
- U0FCR = 0x81; // 使能FIFO,并設置觸發點為8字節
- U0IER = 0x01; // 允許RBR中斷,即接收中斷
- IRQEnable(); // 使能IRQ 中斷
- /* 使能UART0 中斷 */
- VICIntSelect = 0x00000000; // 設置所有的通道為IRQ 中斷
- VICVectCntl0 = 0x20 | 0x06; // UART0分配到IRQ slot0,即最高優先級
- VICVectAddr0 = (uint32)ISR_UART0; // 設置UART0 向量地址
- VICIntEnable = 1 << 0x06; // 使能UART0 中斷
-
- //初始化外部中斷
- Eint3_Init();
- IRQEnable();
- lcd_init();
- DisText(0x80,"Init...");
- if(SIM900Init()==0)
- {
- WrCMD(0x01);
- DisText(0x80,"Init fail");
- while(1);
- }
- WrCMD(0x01);
- DisText(0x80,"Init OK");
- DisText(0x80+0x40,"Waiting...");
- clear_recive_str();
-
- while(1)
- {
- if(last_a!=a)
- {
- last_a =a;
- WrCMD(0x01);
- switch(a)
- {
- case 0:
- DisText(0x80,"Waiting...");
- break;
- case 1:
- DisText(0x80,"Come on");
- if(sendMsg("Come on")==1)
- DisText(0x80+0x40,"success!");
- else
- DisText(0x80+0x40,"fail!");
- break;
- case 2:
- DisText(0x80,"Merry Christmas");
- if(sendMsg("Merry Christmas")==1)
- DisText(0x80+0x40,"success!");
- else
- DisText(0x80+0x40,"fail!");
- break;
- case 3:
- DisText(0x80,"We are family");
- if(sendMsg("We are family")==1)
- DisText(0x80+0x40,"success!");
- else
- DisText(0x80+0x40,"fail!");
- break;
- default:break;
- }
- clear_recive_str(); //清空緩存區
- }
- if(recive_structure.recive_lenth!=0) //00000000000000000000000000000000000
- {
- if(search_str("+CMTI:")!=0) //收到了短信
- //00000000000000000000000000000000
- {
- clear_recive_str();
-
- SendAT("AT+CMGR=1\r\n","OK",3);
- Delay10MS(5);
- if(getMsg()==0)
- {
- WrCMD(0x01);
- DisText(0x80,"fail");
- }
- else
- {
- WrCMD(0x01);
- DisText(0x80,"R:");
- DisText(0x80+0x40,Msg);
- }
- SendAT("AT+CMGD=1\r\n","OK",2); //刪除短信
- SendAT("AT+CMGD=1\r\n","OK",2); //刪除短信
- Delay10MS(5);
- clear_Msg();
- clear_recive_str();
-
- }
- }
-
-
- }
- }
復制代碼
完整的Word格式文檔51黑下載地址: |