加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 编写GSM调制解调器驱动程序?

发布时间:2020-12-16 07:49:53 所属栏目:百科 来源:网络整理
导读:我一直在使用一个应用程序,它使用GSM调制解调器作为两件事之一;通过向服务器发送GET请求或使用UDP发送数据到服务器,使用内置的HTTP协议栈检查其状态.我已经尝试了几种不同的方法来保持尽可能的可靠,我终于准备要求帮助. 我的应用程序是为SIMCOM908模块和PIC1
我一直在使用一个应用程序,它使用GSM调制解调器作为两件事之一;通过向服务器发送GET请求或使用UDP发送数据到服务器,使用内置的HTTP协议栈检查其状态.我已经尝试了几种不同的方法来保持尽可能的可靠,我终于准备要求帮助.

我的应用程序是为SIMCOM908模块和PIC18平台编写的(我正在使用PIC18 Explorer进行开发).

所以问题有时候调制解调器正忙着做点什么,错过命令.作为一个人,我会看到,只是重新发出命令.为我的MCU添加一个设备来超时和重新发送不是一个问题.

调制解调器在不同的事件之后发送未经请求的响应是什么问题.当调制解调器更改注册状态(使用单元塔)时,它将使用CGREG:1,…或GPS准备好GPS准备就绪.这些响应可能在任何时候发生,包括在命令中间(如创建IP连接).

这是一个问题,因为我没有想到有办法处理这个问题.我的应用程序需要发送一个命令(例如,连接到服务器,AT CIPSTART =“UDP”,“example.com”,5000)此命令将响应“OK”,然后当命令完成“CONNECT OK ”.然而,我需要能够对许多其他可能的反应做出反应,而我也没有想到这样做.我需要做什么我的代码;等待来自调制解调器的响应,检查响应,根据该响应执行一个操作?

我是代码限制(作为一个8位微控制器!),并希望保持重复的最小.我如何编写一个响应函数,该函数将从GSM模块(请求或现在)获得响应,然后让我的程序的其余部分知道发生了什么?

理想情况下,我想和这些回应做一些事情.像保持内部状态(当我听到GPS准备好,我知道我可以为GPS等电力

也许有一些事情我应该考虑,或者也许有一个开源项目已经解决了这个问题?

这是我到目前为止

/* Command responses */
enum {
    // Common
    OK = 0,ERROR,TIMEOUT,OTHER,// CGREG
    NOT_REGISTERED,// CGATT
    NOT_ATTACHED,// Network Status
    NO_NETWORK,// GPRS status
    NO_ADDRESS,// HTTP ACTION
    NETWORK_ERROR,// IP Stack State
    IP_INITIAL,IP_STATUS,IP_CONFIG,UDP_CLOSING,UDP_CLOSED,UDP_CONNECTING
} gsmResponse;

int gsm_sendCommand(const char * cmd) {
    unsigned long timeout = timer_getCurrentTime() + 5000;

    uart_clearb(GSM_UART); // Clear the input buffer
    uart_puts(GSM_UART,cmd); // Send the command to the module
    while (strstr(bf2,"r") == NULL) { // Keep waiting for a response from the module
        if (timeout < timer_getCurrentTime()) { // Check we haven't timed out yet
            printf("Command timed out: %srn",cmd);
            return TIMEOUT;
        }
    }
    timer_delay(100); // Let the rest of the response be received.

    return OK;
}

int gsm_simpleCommand(const char * cmd) {
    if (gsm_sendCommand(cmd) == TIMEOUT)
        return TIMEOUT;

    // Getting an ERROR response is quick,so if there is a response,this will be there
    if (strstr(bf2,"ERROR") != NULL)
        return ERROR;

    // Sometimes the OK (meaning the command ran) can take a while
    // As long as there wasn't an error,we can wait for the OK
    while (strstr(bf2,"OK") == NULL);
    return OK;
}

一个简单的命令是任何AT命令,专门寻找OK或ERROR作为响应.像AT这样的东西但是,我也使用它更高级的命令,如AT CPIN?因为这意味着我将捕获整个响应,并可以进一步搜索CPIN:READY.然而,没有一个实际上是对未经请求的回应的回应.实际上,gsm_sendCommand()函数将在收到非请求响应时提早返回.

管理复杂的偶尔不请自来的状态信息的好方法是什么?请注意,此应用程序是用C编写的,并运行在8位微控制器上!

解决方法

处理这两个未经请求的消息以及对相同数据流中的请求的响应是困难的,因为您需要对输入流进行解复用并将结果分派到适当的处理程序.这有点像一个中断处理程序,你必须放弃你正在做的事情,并处理你不一定期望的其他一些信息.

一些模块具有也可用于消息的辅助串行端口.如果可能,您可以将主动邮箱仅显示在单个串行端口上,而主端口则用于AT命令.这可能是不可能的,一些GSM模块将不支持辅助端口上的完整命令集.

也许更好的方法是禁用非请求的消息.大多数命令要求所有的状态.例如在等待注册时,而不是等待发出未经请求的注册消息,只需对当前注册状态的模块进行轮询.这允许您始终控制,您只需处理刚发送的命令的响应.如果您正在等待多个事件,您可以轮流对每个项目循环轮询.这通常会使代码更简单,因为您只需要一次处理单个响应.缺点是您的回应时间受到您的投票率的限制.

如果您继续采用未经请求的邮件方式,我建议为未经请求的邮件实施一个小队列.在等待命令的响应时,如果响应与命令不匹配,只需将响应推送到队列中即可.然后,当您收到AT命令的响应或超时时,您可以处理未经请求的消息队列.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读