微控制器的GPRS无线上网
时间:04-02
来源:互联网
点击:
3 软件整体结构
3.1 软件层次结构
程序中的所有代码都是由C语言编写的,并采用分层的结构,从底到上分别为:串口驱动层、GPRS模块驱动层、PPP协议层、IP协议层、UDP协议层与应用层。上层函数的实现需要应用到底层函数,而底层函数的任务就是为上层函数提供服务,最终完成应用层任务——传送数据。各层的主要函数如图2所示。
图2 软件层次结构
3.2 驱动程序编写
首先是串行口驱动层。它实现打开串口(OpenComm)、关闭串口(CloseComm)、读串口数据(ReadComm)、写串口数据(WriteComm)等函数。例如 WriteComm函数向串口发送一个字节的数据,而transmit函数向串口发送一个字符串的数据:
void WriteComm(char c){
ES = 0;
SBUF = c;
while(TI==0);
TI=0;
ES = 1;
}
void transmit (char *data) {
Delay (250);
while (*data) {
WriteComm (*data++);
}
}
然后,在这些串口函数的基础上编写GPRS模块的驱动函数。微控制器通过串行口控制GPRS模块,进行拨号、设置等操作。控制的方法是采用 AT命令。在控制GPRS模块拨打移动梦网GGSN的登录号码“*99***1#”之后,GPRS模块就转入在线模式(On-Line)。此时微控制器向串行口发送的所有数据都透明地传送给了GGSN,同样GGSN的回答也传回单片机的串行口。当数据传送完成后,微控制器需要通知GPRS模块结束会话,并从在线模式转回普通的命令模式,这可以通过置高DTR线完成。同时,如果线路由于异常断开,CD线会回复到平常的低电平,所以处于在线模式下也要不断检测 CD线是否处于高电平。根据这些操作,可以编写GPRS驱动函数:初始化GPRS模块函数(GPRSInit)、拨号函数(GPRSDial)、断开连接函数(GPRSHangup)、检测是否处于在线状态函数(GPRSOnline)。其中,GPRS的拨号和挂断代码如下:
BYTE GPRSDial (void) {
signed char delayCount = 80;
transmit ("ATV0\r"); // 要求返回数字表示的回答
if (!Waitfor ("0", 30)) { // 等待 OK 回答
return -1;
}
DTR_ON;
transmit ("ATD*99***1#\r"); // 拨GGSN的号码
GPRSBuffFlush (); // 清空buffer
// 等待回答
while ((!GPRSBuffNotEmpty()) && (--delayCount > 0)) {
Delay (250);
}
if (delayCount) {
return GPRSGetch (); // 返回回答的数字
}
return -1; // 没有返回,错误
}
void GPRSHangup (void) {
DTR_ON; // 置高DTR
Delay (40); // 保持一定时间
DTR_OFF; // 完成连接的断开
}
这些底层的驱动函数将会使上层协议的编写很方便,更重要的是,它为我们提供了一个驱动抽象层。当底层硬件做出改动的时候,只需要对底层的驱动函数进行改动,而上层函数的代码不变。
4 PPP协议的实现
由于移动梦网的GGSN与GPRS模块通信时遵循PPP协议,所以要在微控制器中也实现一部分PPP协议才能与之对话。GPRS模块在拨号后首先要与GPRS网关进行通信链路的协商,即协商点到点的各种链路参数配置。协商过程遵守LCP(Link Control Protocol)、PAP(Password Authentication Protocol)和IPCP(Internet Protocol Control Protocol)等协议。其中LCP协议用于建立、构造、测试链路连接;PAP协议用于处理密码验证部分;IPCP协议用于设置网络协议环境,并分配 IP地址。协商机制用有限状态机的模型来实现。一旦协商完成,链路已经创建,IP地址已经分配就可以按照协商的标准进行IP报文的传输了。根据应用的不同,IP报文中可以携带UDP报文,也可以是TCP或ICMP报文。本系统正是采用UDP报文传送数据信息的。数据传输完成之后,微控制器会向GGSN发送LCP的断开连接报文,以终止网络连接。
PPP协议的帧结构如图3(左)所示。微控制器的串口中断接收程序首先以包起始和结束符来判断是否有完整的PPP包,并对PPP包的内容进行校验,以确定数据包的完整性和正确性。然后,在主循环中进入PPP报文解析模块,解析过程如图 3(右)所示。
图3 PPP报文解析
5 登录GGSN的过程
系统的一个难点是微控制器登陆GPRS网关(GGSN)并与网关通过LCP、PAP、IPCP协议进行协商的过程。LCP、PAP与IPCP协议的帧结构大同小异,最常用的为请求(REQ)、同意(ACK)和拒绝(NAK)三种帧。微控制器与GGSN各为一方进行协商,任何一方都可以发送REQ帧请求某方面的配制,另一方觉得配置不能接受会回应NAK帧,如果可以则回应ACK帧。为了节省资源,我们只处理这三种数据帧,其它链路问题都由微控制器在程序控制下自己重新拨号解决。
协商过程大致描述如下:在拨号成功连接后,GGSN首先会返回一个PAP REQ数据帧。我们发送一个空LCP REQ帧,以强迫进行协议协商阶段。随后,GGSN发送LCP设置帧,我们拒绝所有的设置并请求验证模式。GGSN选择CHAP或PAP方式验证,我们只接受PAP方式。然后,进行PAP验证用户名和密码过程,在GPRS中用户名与密码都为空,如果成功,GGSN会返回IPCP报文分配动态IP地址。此时,就完成了与GGSN的协商过程。协商过程的状态转换如图4所示。
图4 协商过程流程
协商完成后进入IP数据报通信阶段。此时,微控制器向GGSN发送的所有包含 IP报文的PPP报文都会被传送给Internet网中相应的IP地址;而远端所有向微控制器IP地址发送的报文也都会经GPRS网传送到微控制器上,从而完成微控制器与远程主机通过互联网的数据传输。
注:PPP报文解析程序和协商过程程序见本刊网站www.dpj.com.cn。
3.1 软件层次结构
程序中的所有代码都是由C语言编写的,并采用分层的结构,从底到上分别为:串口驱动层、GPRS模块驱动层、PPP协议层、IP协议层、UDP协议层与应用层。上层函数的实现需要应用到底层函数,而底层函数的任务就是为上层函数提供服务,最终完成应用层任务——传送数据。各层的主要函数如图2所示。
图2 软件层次结构
3.2 驱动程序编写
首先是串行口驱动层。它实现打开串口(OpenComm)、关闭串口(CloseComm)、读串口数据(ReadComm)、写串口数据(WriteComm)等函数。例如 WriteComm函数向串口发送一个字节的数据,而transmit函数向串口发送一个字符串的数据:
void WriteComm(char c){
ES = 0;
SBUF = c;
while(TI==0);
TI=0;
ES = 1;
}
void transmit (char *data) {
Delay (250);
while (*data) {
WriteComm (*data++);
}
}
然后,在这些串口函数的基础上编写GPRS模块的驱动函数。微控制器通过串行口控制GPRS模块,进行拨号、设置等操作。控制的方法是采用 AT命令。在控制GPRS模块拨打移动梦网GGSN的登录号码“*99***1#”之后,GPRS模块就转入在线模式(On-Line)。此时微控制器向串行口发送的所有数据都透明地传送给了GGSN,同样GGSN的回答也传回单片机的串行口。当数据传送完成后,微控制器需要通知GPRS模块结束会话,并从在线模式转回普通的命令模式,这可以通过置高DTR线完成。同时,如果线路由于异常断开,CD线会回复到平常的低电平,所以处于在线模式下也要不断检测 CD线是否处于高电平。根据这些操作,可以编写GPRS驱动函数:初始化GPRS模块函数(GPRSInit)、拨号函数(GPRSDial)、断开连接函数(GPRSHangup)、检测是否处于在线状态函数(GPRSOnline)。其中,GPRS的拨号和挂断代码如下:
BYTE GPRSDial (void) {
signed char delayCount = 80;
transmit ("ATV0\r"); // 要求返回数字表示的回答
if (!Waitfor ("0", 30)) { // 等待 OK 回答
return -1;
}
DTR_ON;
transmit ("ATD*99***1#\r"); // 拨GGSN的号码
GPRSBuffFlush (); // 清空buffer
// 等待回答
while ((!GPRSBuffNotEmpty()) && (--delayCount > 0)) {
Delay (250);
}
if (delayCount) {
return GPRSGetch (); // 返回回答的数字
}
return -1; // 没有返回,错误
}
void GPRSHangup (void) {
DTR_ON; // 置高DTR
Delay (40); // 保持一定时间
DTR_OFF; // 完成连接的断开
}
这些底层的驱动函数将会使上层协议的编写很方便,更重要的是,它为我们提供了一个驱动抽象层。当底层硬件做出改动的时候,只需要对底层的驱动函数进行改动,而上层函数的代码不变。
4 PPP协议的实现
由于移动梦网的GGSN与GPRS模块通信时遵循PPP协议,所以要在微控制器中也实现一部分PPP协议才能与之对话。GPRS模块在拨号后首先要与GPRS网关进行通信链路的协商,即协商点到点的各种链路参数配置。协商过程遵守LCP(Link Control Protocol)、PAP(Password Authentication Protocol)和IPCP(Internet Protocol Control Protocol)等协议。其中LCP协议用于建立、构造、测试链路连接;PAP协议用于处理密码验证部分;IPCP协议用于设置网络协议环境,并分配 IP地址。协商机制用有限状态机的模型来实现。一旦协商完成,链路已经创建,IP地址已经分配就可以按照协商的标准进行IP报文的传输了。根据应用的不同,IP报文中可以携带UDP报文,也可以是TCP或ICMP报文。本系统正是采用UDP报文传送数据信息的。数据传输完成之后,微控制器会向GGSN发送LCP的断开连接报文,以终止网络连接。
PPP协议的帧结构如图3(左)所示。微控制器的串口中断接收程序首先以包起始和结束符来判断是否有完整的PPP包,并对PPP包的内容进行校验,以确定数据包的完整性和正确性。然后,在主循环中进入PPP报文解析模块,解析过程如图 3(右)所示。
图3 PPP报文解析
5 登录GGSN的过程
系统的一个难点是微控制器登陆GPRS网关(GGSN)并与网关通过LCP、PAP、IPCP协议进行协商的过程。LCP、PAP与IPCP协议的帧结构大同小异,最常用的为请求(REQ)、同意(ACK)和拒绝(NAK)三种帧。微控制器与GGSN各为一方进行协商,任何一方都可以发送REQ帧请求某方面的配制,另一方觉得配置不能接受会回应NAK帧,如果可以则回应ACK帧。为了节省资源,我们只处理这三种数据帧,其它链路问题都由微控制器在程序控制下自己重新拨号解决。
协商过程大致描述如下:在拨号成功连接后,GGSN首先会返回一个PAP REQ数据帧。我们发送一个空LCP REQ帧,以强迫进行协议协商阶段。随后,GGSN发送LCP设置帧,我们拒绝所有的设置并请求验证模式。GGSN选择CHAP或PAP方式验证,我们只接受PAP方式。然后,进行PAP验证用户名和密码过程,在GPRS中用户名与密码都为空,如果成功,GGSN会返回IPCP报文分配动态IP地址。此时,就完成了与GGSN的协商过程。协商过程的状态转换如图4所示。
图4 协商过程流程
协商完成后进入IP数据报通信阶段。此时,微控制器向GGSN发送的所有包含 IP报文的PPP报文都会被传送给Internet网中相应的IP地址;而远端所有向微控制器IP地址发送的报文也都会经GPRS网传送到微控制器上,从而完成微控制器与远程主机通过互联网的数据传输。
注:PPP报文解析程序和协商过程程序见本刊网站www.dpj.com.cn。
- 嵌入式系统的定义与发展历史(11-15)
- 嵌入式系统亲密接触(11-22)
- 嵌入式系统设计中的USB OTG方案(02-01)
- 嵌入式线控驾驶系统开发过程中设计和测试考虑(02-02)
- 一个典型的嵌入式系统设计和实现 (02-02)
- DDR SDRAM在嵌入式系统中的应用(02-07)