摘要
随着手机的广泛使用,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黑下载地址:
|