Embedded 如何在微控制器上处理GSM缓冲区?
我有一个连接到PIC18F87J11的GSM模块,它们通信很好。我可以从微控制器发送AT命令并读取响应。但是,我必须知道响应中有多少个字符,这样我才能让PIC等待那么多字符。但是如果发生错误,响应长度可能会改变。处理这种情况的最佳方法是什么 例如:Embedded 如何在微控制器上处理GSM缓冲区?,embedded,microcontroller,gsm,at-command,Embedded,Microcontroller,Gsm,At Command,我有一个连接到PIC18F87J11的GSM模块,它们通信很好。我可以从微控制器发送AT命令并读取响应。但是,我必须知道响应中有多少个字符,这样我才能让PIC等待那么多字符。但是如果发生错误,响应长度可能会改变。处理这种情况的最佳方法是什么 例如: AT+CMGF=1 将导致以下响应 \r\nOK\r\n 所以我不得不告诉照片等6个字符。但是,如果有响应,则显示错误消息。应该是这样的 \r\nERROR\r\n 如果我已经告诉PIC只等待6个字符,那么它将弄乱其余的字符,因此它们可能会
AT+CMGF=1
将导致以下响应
\r\nOK\r\n
所以我不得不告诉照片等6个字符。但是,如果有响应,则显示错误消息。应该是这样的
\r\nERROR\r\n
如果我已经告诉PIC只等待6个字符,那么它将弄乱其余的字符,因此它们可能会在下次我告诉PIC读取新AT命令的响应时出现
自动查找行尾并处理任何错误消息的最佳方法是什么?
谢谢 让我们将问题分解为一些抽象层 最顶层是您的应用程序。应用层将响应消息作为一个整体处理,并理解消息的含义。它不应该被诸如预期接收多少字符这样的细节所困扰 下一层负责从字符流中构建消息。框架是通过标识消息的开头和结尾从流中提取消息 底层负责从端口读取单个字符 应用程序可以调用一个函数,如GetResponse(),它实现了框架层。GetResponse()可以调用GetChar(),它实现了底层。听起来你已经控制了底层,你的问题是关于框架层 将字符流框架化为消息的一个好模式是使用状态机。在您的情况下,状态机包括诸如BEGIN_DELIM、MESSAGE_BODY和END_DELIM等状态。例如,对于更复杂的串行协议,其他状态可能包括消息头和消息校验和 下面是一些非常基本的代码,让您了解如何在GetResponse()中实现状态机。您应该添加各种类型的错误检查,以防止缓冲区溢出并处理丢弃的字符等
void GetResponse(char *message_buffer)
{
unsigned int state = BEGIN_DELIM1;
bool is_message_complete = false;
while(!is_message_complete)
{
char c = GetChar();
switch(state)
{
case BEGIN_DELIM1:
if (c = '\r')
state = BEGIN_DELIM2;
break;
case BEGIN_DELIM2:
if (c = '\n')
state = MESSAGE_BODY:
break;
case MESSAGE_BODY:
if (c = '\r')
state = END_DELIM;
else
*message_buffer++ = c;
break;
case END_DELIM:
if (c = '\n')
is_message_complete = true;
break;
}
}
}
让我们把这个问题分解成一些抽象层 最顶层是您的应用程序。应用层将响应消息作为一个整体处理,并理解消息的含义。它不应该被诸如预期接收多少字符这样的细节所困扰 下一层负责从字符流中构建消息。框架是通过标识消息的开头和结尾从流中提取消息 底层负责从端口读取单个字符 应用程序可以调用一个函数,如GetResponse(),它实现了框架层。GetResponse()可以调用GetChar(),它实现了底层。听起来你已经控制了底层,你的问题是关于框架层 将字符流框架化为消息的一个好模式是使用状态机。在您的情况下,状态机包括诸如BEGIN_DELIM、MESSAGE_BODY和END_DELIM等状态。例如,对于更复杂的串行协议,其他状态可能包括消息头和消息校验和 下面是一些非常基本的代码,让您了解如何在GetResponse()中实现状态机。您应该添加各种类型的错误检查,以防止缓冲区溢出并处理丢弃的字符等
void GetResponse(char *message_buffer)
{
unsigned int state = BEGIN_DELIM1;
bool is_message_complete = false;
while(!is_message_complete)
{
char c = GetChar();
switch(state)
{
case BEGIN_DELIM1:
if (c = '\r')
state = BEGIN_DELIM2;
break;
case BEGIN_DELIM2:
if (c = '\n')
state = MESSAGE_BODY:
break;
case MESSAGE_BODY:
if (c = '\r')
state = END_DELIM;
else
*message_buffer++ = c;
break;
case END_DELIM:
if (c = '\n')
is_message_complete = true;
break;
}
}
}
一行
没有单一的最佳方式,只有取舍
详细地
该问题可分为两个相关的子问题
1.接收任意有限长度的消息
权衡:
- 可用内存与实现复杂性李>
- 带宽开销与实现复杂性