This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:将 SIM900 GSM 模块连接到 TM4c (通过 UART)-接收和解析 SMS 时出现问题

Guru**** 2328790 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/591858/tm4c123gh6pm-interfacing-sim900-gsm-module-to-tm4c-via-uart---issue-with-receiving-and-parsing-sms

器件型号:TM4C123GH6PM

您好!

我一直在尝试(不太成功)通过 SIMCom Sim900 GSM 模块将 SMS 发送到我的 TM4C MCU。

它们通过 UART2 (PD6和 PD7)进行连接、向 GSM 模块发送 UART 数据时不会出现问题、还会发送 SMS 消息...

我设法将一个程序组合在一起、以接收(读取)和解析 SMS 消息、它可以工作、但有很多错误、它没有可预测的输出、在我想集成此功能的应用中、它非常重要。

正如我迄今为止看到的、RX 数据的内容是问题所在。

我将把我的初始化函数和 SMS 处理函数粘贴到这里。 也许有人可以给我一些提示。

UART2 Init 函数、该函数使用 TIVAWARE 的 UART stdio

void UART2_Init (void){
UINT32_t UART_CONFIG_READ = 0;
SysCtlPeripheralEnable (SYSCTL_Periph_UART2);//启用 UART2
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD)上的时钟
;//启用端口 D 上的时钟// PD6和 PD7将 RX 和 TX 发送到 GSM 模块,而 SYSCTL_Periph_GPIOD= 0x4TO/SYSCTRL (SYSCTRL_POL0_TOL);
// UART0_TOOL_TOOL4TOOL0_TOOL0_TOOL0_TOOL0_TOOL0_TOOL0_GPIOR

= 0x4TOOL0_TOOL0_TOOL0_TOOL0_TOOL0_TOOL0_TOOL0_GPIOR
(0x4);// //允许更改为 PD6、7

IntDisable (INT_UART2);
UARTIntDisable (UART2_base、UART_INT_RX|UART_INT_TX|UART_INT_RT);//禁用 UART2中断
UARTDisable (UART2_base);//在配置

GPIOPinConfigure (GPIO_PD6_INT_UART7_GPIO

)时禁用 UART2;//配置 UART2_PRINT7_GPIOPT_GPT PAD、

UARTClockSourceSet (UART2_base、UART_CLOCK_SYSTEM);//设置 UART2
UARTParityModeSet (UART2_base、UART_CONFIG_PAR_NONE)的时钟源;
//设置 UARTFIFOEnable (UART2_base)的时钟源;//启用 FIFO
UARTSysStdioConfig (GSM_CONFIG (UART2_BASE
)
;UARTUART (UART2_UARTCCUSTRUARTOBAUD)寄存器(UART2_BASE);UARTDIOPTCT_UARTAULATE (UARTOPART (UARTAUD
UARTConfigGetExpClk (UART2_base、SysCtlClockGet ()、&GSM_Baud_RATE_READ、&UART_CONFIG_READ);//获取波特率
} 

GSM 模块的初始化功能:

void PowerOnGSM (void){
uint8_t lineCount = 0;
uint16_t I = 0;
uint8_t uart2_dump[1024]="";

UARTprintf ("AT+CMGf=%u\r\n"、1);//消息格式文本
SysCtlDelay (stopis2Ticks (100)在延迟期间未被禁用/中断!
lineCount = GSMgetResponse ();

UARTprintf ("AT+CSDH=%u\r\n"、0);//不显示完整的消息标题
SysCtlDelay (Millis2Ticks (100));






Count = GSMgetResponse ();USMCtl("AT+CNMI=%u);Message n (Millise2Tu (100);n) n) n (n) n) n (n);n n (n) n n n n n (n) n (n) n (n) n) n (n (n) n) n) n (n) n (n) n (n) n (n) n (n (n) n) n (n (n) n (n) n (n) n (n) n (n) n (n) n (n) n (n) n (n) n (n (n) n (n

SMS 处理函数: void GSMprocessMessage (uint8_t msgNum)、 uint8_t GSMgetResponse (void)、 bool GSMparseMessage (uint8_t lineCount)

//
//
处理信封和内容的短信
//
//*********
void GSMprocessMessage (uint8_t msgNum){
bMillmsgPresent = 0;//标记以忽略已删除的消息
int lineCount=0;//保留行数


//请求消息并获取响应的行(包括包络、Millls、SIM 响应)
Uprintf ("AT+CMGR=%u\r\n\r);TmsgCtl(用于读取)
;

//开始消息检索
lineCount = GSMgetResponse ();

//确保有消息内容、信封处理和内容
msgPresent = GSMparseMessage (lineCount);

//向用户显示我们找到
的 PC_Display_Message ("\n\n\r\n>>> message:"、msgNum、");
if (

Message Sender (lineCount);//显示为 PC、msg0);尝试从显示:
PC_Display_Message (">打开:"、0、msgTime);
PC_Display_Message (">文本:"、0、msgContent);
}
否则 PC_Display_Message (">不存在!"、0、");
}

//*********
//
//将 GSM 响应存储到阵列响应线[]///

*********
uint8_t GSMgetResponse (void){
bool readResponse = true; //在获取消息
int readline = 0时保持循环打开; //计算消息
字符的行*GSMResponse = NULL; //用于抓取输入
字符 g_cInput[128]; // UART

PC_Display_Message 的字符串输入(">开始消息读取"、0、");
while (readResponse &(readline <10)){//too、请勿硬编码、使用宏
//抓取行
// UART2 _GetString(g_cInput、sizeof (g_cInput);// unchrom_enr_intrue/intrue/intrue/intrue/intrue/intrue/intrue/intrue/intrue/intrue/intrue/nrx (nrx)




//PC_Display_Message (">>>行'nr:",readline,ResponseLine[readline]);
//如果此行显示为“正常”,我们将收到整条消息
if ((strncmp (responseLine[readline],"OK",2)=0)||
(strncmp (respondseLine[readline],"+
);"reviewline = 0+)






;(readus+)
//
//解析用于包络和消息内容的 GSM 消息
//将消息包络和常量存储到全局变量中,或返回 true
//表示消息存在,返回 false 表示无消息
//
*********
bool GSMparseMessage (uint8_t lineCount){
uint8_t activeLine = 0;//正在处理的行的计数
器 char * msgEnvelope = NULL;//消息包络保持器

msgContent = NULL; //清除旧消息
//解析新消息
,同时(activeLine < lineCount)// lineCount 比响应行[index]
{
PC_Display_Message ("已处理行:"、activeLine、responseLine[activeLine])大1;
//信封的大小写(如下所示)
//+CMGR: "REC read"、"+40712334501"、""、"17/04/12,22:53:48+12"
if (strstrstr (responseLine[activeLine]、"+CMGR:")!='\0')//如果收到消息
{
//开始解析
msgEnvelope = responseLine[activeLine]、"+CMGR:"!='\0')、//如果收到消息,


则跳过 msgmsgmsgEnvelope =
1
、'senders/gmsgmsgmsgmsgmsgveLine'、'ser = 1、'sender'ser、's's's's's's'/'、'sender's's's's's's's's's //从电话号码和录音标记中跳过前缀
msgSender [10]='\0';//存储号码(带空终结器)

msgDate = strtok (NULL、"、");//转到下一个逗号、跳过电话簿条目
msgDate = strtok (NULL、"、");//抓取日期
= msg8';删除 msgauestation = 1;
// msgDate= 1;msg8';msgestation = msgestation = 1 //存储日期(使用 null 终结器)

msgTime = strtok (NULL、"、");//获取时间
msgTime[8]='\0';//存储时间(使用 null 终结器)
}

//消息内容的大小写
//如果我们已经找到信封,行不为空...
否则,如果(((msgEnvelope != NULL)&&(responseLine[activeLine]!= NULL))
{//
... 我们没有找到任何内容、这是第一行。
if (msgContent =NULL){msgContent =responseLine[activeLine];}

//... 否则、添加空格并附加此行。
否则,如果(activeLine+2 <= lineCount){//+2是由于在 OK 之前的 EMPLY 行和最后一行带有 OK。
strcat (msgContent、");
strcat (msgContent、responseLine[activeLine]);
}

activeLine++; //继续到下一行
}
如果(msgEnvelope =NULL ){//如果我们没有找到信封,就没有消息
返回 false;
}
否则{//返回 true。
返回 true;
}

全局数据并定义:

//此处存储的最新传入消息的数据
char responseLine[10][160];//用于存储 UART 输入
静态 char * msgContent = NULL;//消息内容保留
器静态 char * msgSender = NULL;//消息发送
器静态 char * msgDate = 空;//消息日期
静态字符*msgTime = 空;//消息时间

#define BAUD_RATE (115200)
#define GSM_BAUD_RATE (115200)
#define GSM_UART_PORT (2)
#define UART2_INT_PRIO (2) 

当 我想读取 SMS (指定要读取的 msgNum)时、我从 GPIO ISR 调用 GSMprocessMessage (msgNum)。

程序正常工作、但获得有效结果(正确的 SMS 重新检索和解析)~ 2 (共10次)。

如果您有任何建议、请告诉我。

此致、

Alex Gaal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Alex。 不用担心。 您的代码正常,但请执行以下操作:使用 putty over serial*连接到 GSM/GPRS 模块。 将所有需要的 at+命令发送到模块并等待响应。 记下响应时间和响应消息。 然后在源代码内部创建一些时间相关的读取循环、并在通过代码发送 AT +命令时等待已知答案。 如果您只是仔细地执行它、那么您的代码将会滚动。 SIM900/800模块和另一个已知模块、当通过串行触发时、会出现这些延迟问题。 您可以编写适当的等待时间和检查循环代码、或者进一步下载模块的 SDK 并编写一个小程序、该小程序直接加载到 GSM/GPRS 模块的闪存中、从而创建您自己的确定性串行通信架构。 但是、还应记住、有一组 AT +命令可最大限度地减少 GSM 模块的无用响应、而且仅此一项就能使事情加快速度、并使整个通信架构更具确定性。
    请注意、GSM 模块的 TTL 大约为3.5伏、而 PC 的串行电压为+/- 12伏。 您需要一个 RS-232转 TTL 3.3V 转换器、以便直接将模块与 PC 的串行端口相连。

    祝你好运、
    John

    P.S. 而 strncmp 使用 indexof