打印
[51单片机]

C51和GSM模块之间串口通讯问题,求算法

[复制链接]
925|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我们知道要判断串口传过来的是不是某个字符好办, if (SBUF=='1'),就成,

如果要判断一个单词,或者判断GSM模块向C51串口,一段话传完了没有。就不知道怎么好了。。。
比如下面截图所示,有很多个段落,我具体量化一下我的问题。

下面截图显示的是GSM模块传给80C52串口的16进制经转换后的内容。
我的问题在下面几个方面:
1.如何判断GSM模块传回来的某一行中,具有CALL这个单词?
2.每次80C52向GSM模块发送一条指令后,GSM模块都会有回应。它的回应可能不止一句,有时是一句,比如返回OK,有时返回若干行。
我怎么知道GSM模块已经反馈完了呢?



GSM模块图如下:


相关帖子

沙发
xyz549040622| | 2017-3-12 07:00 | 只看该作者
1.只能挨个判断了,把数据放缓存区中,碰到换行符就是一行到了,再在这行的数据中分割单词,查找你需要的单词。
2.返回OK,应该是有个固定的协议的,比如连续几个固定的字符,比如回车换行符等,找到结束帧就好了。

使用特权

评论回复
板凳
dirtwillfly| | 2017-3-12 10:15 | 只看该作者
也可以直接用c标准库里的字符串查找函数,或者自己实现一个函数

使用特权

评论回复
地板
Gameparkwing| | 2017-3-12 14:40 | 只看该作者
本帖最后由 Gameparkwing 于 2017-3-12 15:16 编辑

程序可以分为两部分,读取一行和解析一行。
串口读入的字符保存到 str_from_uart[] 数组中,用变量 p_from_uart 做数量指示。
串口每接收到一个字节,调用一次 RespondReadLine() 函数。

变量 respond_string 和 respond_value 为每一次读取到的返回的数据值。
变量 respond_done 默认为 -1 ,表示无应答内容, respond_done == 0/1/2... 时,读取到一行返回的数据,程序中做相应的处理。

unsigned int p_from_uart;
unsigned char str_from_uart[255];
unsigned char respond_string[16];
unsigned int respond_value;
signed int respond_done;

/* 解析一行应答数据。 */
void RespondParser()
{
    if (strstr(str_from_uart, "+CIEV") != NULL) {                                             // 存在有效应答值。
        sscanf(str_from_uart, "%*[^\"]\"%[^\"]\"%*[^0-9]%d", respond_string, &respond_value); // 提取应答值。
        respond_done = 2;                                                                     // 提取到应答数据。
    } else {
        // 判断应答结果, OK 或 ERROR。
        if (strstr(str_from_uart, "OK") != NULL) {
            respond_done = 1;                                                                 // 返回值为 OK 的情况。
        } else if (strstr(str_from_uart, "ERROR") != NULL) {
            respond_done = 0;                                                                 // 返回值为 ERROR 的情况。
        } else {
            respond_done = -1;                                                                // 无内容,不处理。
        }
    }
}

/* 读取一行应答数据。 */
void RespondReadLine()
{
    if (str_from_uart[p_from_uart] == '\n') {                                                 // 遇到换行符,读取一行。
        RespondParser();                                                                      // 解析一行应答数据。
        p_from_uart = 0;                                                                      // 串口接收游标清零。
    } else {
        p_from_uart ++;                                                                       // 串口接收游标递增。
    }
}


使用特权

评论回复
5
lnulibin| | 2017-3-12 20:02 | 只看该作者
一般有AT命令的模块,比如WIFI转串口模块,语音播放/录制模块.都会有反馈信息.

从你给出的反馈字符截图来看.(当然你可能没有给出所有可能的反馈),只有"CALL"这个单词里面有A这个字母,其它单词中没有字母A,所以,你只要判断接收寄存器中是否为0X41即可.如果是0X41就说明收到了CALL.

当然,如果反馈信息中的其它单词中也有字母A,那这一招就不灵了.呵呵.

如果要搜索反馈信息中某一个单词,假设这个单词是8个字节,你只要构造一个队列数据结构来存放接收的数据即可.注意队列的长度大于8.

每接收到一个字节数据,要把新数据入队,挤出最老的数据.保证最后接收到的8个数据在队列中.搜索队列中有无你要的那个单词.(方法不说了)

使用特权

评论回复
6
ac62| | 2017-3-13 10:58 | 只看该作者
学习了

使用特权

评论回复
7
vincent.liu|  楼主 | 2017-3-13 16:05 | 只看该作者
Gameparkwing 发表于 2017-3-12 14:40
程序可以分为两部分,读取一行和解析一行。
串口读入的字符保存到 str_from_uart[] 数组中,用变量 p_from_ ...

谢谢,分数给你,请问如何结贴?

使用特权

评论回复
8
Gameparkwing| | 2017-3-15 23:57 | 只看该作者
vincent.liu 发表于 2017-3-13 16:05
谢谢,分数给你,请问如何结贴?

我还没发过帖,还真不知道如何结帖。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

63

帖子

2

粉丝