我已经用 C 语言编写了一个 PDU 到文本解码算法,它可以与开发 C 或代码块完美地编译和运行多个消息(我手动提供 PDU 消息)。现在我已将相同的算法应用于与 sim800c gsm 模块连接的 stm32f103rc,stm32f103rc sysclk 在 72MHz 上运行,stm 和 sim800c 之间的通信波特率为 115200。
当我发送简单消息(80 个字符以内)时,短信会被解码并完美显示,但是当我发送超过 80 个字符时,显示屏最多显示 80 个字符然后停止。我检查了终端中的解码消息,它在 80 个字符后给出了相同的结果,有垃圾。
我已经考虑了一些事情,比如终止一个字符串(因为我没有像在 dev c 中那样手动获取数据)然后删除回车和换行。但无法理解我的算法哪里出错了
编码
我在 stm32f103rc 上运行代码
/* Includes --------------------------------------------------------------*/
#include "PDU_Decode.h"
/* Private Variables -----------------------------------------------------*/
int concate;
/* Private Function Definition -------------------------------------------*/
/** @breif: Decode a PDU msg to TEXT
* @param: Destination Buffer to store converted data
* @retVal: None
*/
void PDU_to_TEXT(char *dest)
{
char Len[2];
char str[150];
int UserDataLen;
uint8_t msgNo,totalMsg;
msgNo = 1;
do
{
End_Things();
__enable_irq();
if (msgNo == 1) { Transmit_String("AT+CMGR=1\r"); }
else if(msgNo == 2) { Transmit_String("AT+CMGR=2\r"); }
else if(msgNo == 3) { Transmit_String("AT+CMGR=3\r"); }
else { Transmit_String("AT+CMGR=4\r"); }
_delay_ms(1000);
__disable_irq();
Uart_Buff[datapos] = '\0';
concate = CheckForConcate(Uart_Buff);
totalMsg = CheckForTotal_msg(Uart_Buff);
Remove_Carriag_LineFeed(Uart_Buff);
Eliminate_Extras(Uart_Buff);
uint8_t startingPoint = CheckStartingPoint(Uart_Buff);
GetUserData(Uart_Buff,Len,startingPoint);
UserDataLen = DecodeTwoBitData(Len);
Decode_PDU(Uart_Buff,str,UserDataLen);
if (msgNo == 1) { strcpy(dest,str); }
else
{
int i=0,j=0;
while(dest[i]!='\0') {i++;}
while(str[j]!='\0')
{
dest[i] = str[j];
i++;j++;
}
dest[i] = '\0';
}
Transmit_String(dest);
msgNo++;
End_Things();
__enable_irq();
if (totalMsg > 1 && msgNo <= totalMsg)
{
while (!strstr(Uart_Buff,"+CMTI"));
}
__disable_irq();
}while (msgNo <= totalMsg);
}
/** @breif: Check is message is having more than one part
* @param: The source message which is to be checked
* @retVal: Either true or false
*/
uint8_t CheckForConcate(char *src)
{
if (strstr(src,"050003")) { return 1; }
else { return 0; }
}
/** @breif: Check for total messages
* @param: the source message
* @retVal: total number of message
*/
uint8_t CheckForTotal_msg(char *src)
{
int i;
char temp[2];
uint8_t t_msg;
for (i = 0;i<strlen(src);i++)
{
if (src[i] == '0' && src[i+1] == '5' && src[i+2] == '0' && src[i+3] == '0' && src[i+4] == '0' && src[i+5] == '3')
{
i+=8;
temp[0] = src[i];
temp[1] = src[i+1];
t_msg = DecodeTwoBitData(temp);
return t_msg;
}
}
return 1; //if there is no other message dn source message is the only message
}
/** @breif: Get original hex from the character
* @param: the source message
* @param: The destination file to store hex
* @retVal: None
*/
void GetOriginalHex(char *src, uint8_t *hex)
{
int i;
for (i=0;src[i] != '\0';i++)
{
if (src[i] >= '0' && src[i] < 'A') { hex[i] = src[i] - '0'; }
else if (src[i] >= 'A') { hex[i] = src[i] - 'A' + 10; }
}
}
/** @breif: pack the hex in single position
* @param: the source message
* @param: length of the source message
* @retVal: None
*/
void PackHex(uint8_t *hex,int len)
{
int i,j;
for (i = 0,j = 0; i< len;i+=2,j++)
{
hex[j] = hex[i] << 4 | hex[i+1];
}
}
/** @breif: Decode the two bit data in single data
* @param: the source message
* @retVal: Decoded bit
*/
uint8_t DecodeTwoBitData(char *hex)
{
uint8_t newHex[2];
GetOriginalHex(hex,newHex);
PackHex(newHex,2);
return (newHex[0]);
}
/** @breif: Remove Carriage return and Line feed from the original message
* @param: the source message
* @retVal: None
*/
void Remove_Carriag_LineFeed(char *str)
{
int i,j;
for(i = 0, j = 0; str[i] != '\0'; i++)
{
if(str[i] != '\r' && str[i] != '\n')
str[j++] = str[i];
}
str[j] = '\0';
}
/** @breif: Eliminate Extra mesages from original message
* @param: the source message
* @retVal: None
*/
void Eliminate_Extras(char *src)
{
int copy = 0;
int i,j;
for (i = 0,j = 0; src[i] != '\0'; i++)
{
if (src[i] == '0' && src[i+1] == '7' && src[i+2] == '9' && src[i+3] == '1')
copy = 1;
if (copy)
{
src[j] = src[i];
j++;
}
}
src[j] = '\0';
}
/** @breif: Check the starting point of the original message
* @param: the source message
* @retVal: starting point
*/
uint8_t CheckStartingPoint(char *src)
{
uint8_t temp = 52,retVal = temp;
if (src[temp - 1] == '2' && src[temp - 2] == '2') retVal = 52;
else if (src[temp] == '2' && src[temp + 1] == '2') retVal = 54;
else if (src[temp + 2] == '2' && src[temp + 3] == '2') retVal = 56;
return retVal;
}
/** @breif: Get Original User data
* @param: the source message
* @retVal: None
*/
void GetUserData(char *src, char *len, uint8_t start)
{
int i,j,k;
for (i=start,j=0,k=0;src[i] != '\0';i++)
{
if (i < start + 2)
{
len[j] = src[i]; j++;
}
else if(concate == 1)
{
i+=11;
concate = 2;
len[j] = '\0';
}
else
{
len[j] = '\0';
src[k] = src[i];
k++;
}
}
src[k] = '\0';
}
/** @breif: Decode PDU Message
* @param: the source message
* @param: the Destination Buffer
* @param: the length of the message
* @retVal: None
*/
void Decode_PDU(char *src,char *str,int UserDataLen)
{
int data_len = strlen(src);
uint8_t OriginalHex[data_len];
GetOriginalHex(src,OriginalHex);
PackHex(OriginalHex,data_len);
if (IsLimited_Message(OriginalHex))
{
DecodeLimited_Message(OriginalHex,str,UserDataLen);
}
else
{
Decode_Original_Message(OriginalHex,str,UserDataLen);
}
}
/** @breif: Check if the message is limited message
* @param: the source message
* @retVal: true or false
*/
uint8_t IsLimited_Message(uint8_t *hex)
{
if (hex[0]==0 && hex[2]==0 && hex[4]==0 && hex[6]==0 && hex[8]==0) { return 1; }
else { return 0; }
}
/** @breif: Decode the limited message
* @param: the source message
* @param: the destination buffer
* @param: length of the data
* @retVal: None
*/
void DecodeLimited_Message(uint8_t *hex,char *dest,int UserDataLen)
{
int i,j;
for (i=1,j=0;i<UserDataLen;i+=2,j++) dest[j] = hex[i];
dest[j]='\0';
}
/** @breif: Decode the Original message
* @param: the source message
* @param: the destination buffer
* @param: length of the data
* @retVal: None
*/
void Decode_Original_Message(uint8_t *hex,char *dest,int UserDataLen)
{
int i,j;
uint8_t DecValue[UserDataLen];
Decode_Hex(hex,DecValue,UserDataLen);
for (i=0,j=0;i<UserDataLen;i++,j++)
{
if (DecValue[i] == 0x11) DecValue[j] = 95;
else if (DecValue[i] == 0x1B)
{
i++;
switch (DecValue[i])
{
case 0x28: DecValue[j] = 123; break;
case 0x29: DecValue[j] = 125; break;
case 0x14: DecValue[j] = 94; break;
case 0x2F: DecValue[j] = 92; break;
case 0x3C: DecValue[j] = 91; break;
case 0x3D: DecValue[j] = 126; break;
case 0x3E: DecValue[j] = 93; break;
case 0x40: DecValue[j] = 124; break;
}
}
else
DecValue[j]=DecValue[i];
}
UserDataLen = j;
if (concate == 2)
UserDataLen -= 7;
for (i=0;i<UserDataLen;i++)
dest[i] = (char)DecValue[i];
dest[i]='\0';
}
/** @breif: Decode the Hex
* @param: the source message
* @param: the destination buffer
* @param: length of the data
* @retVal: None
*/
void Decode_Hex(uint8_t *hex,uint8_t *dest,int len)
{
int i,j,l;
uint8_t temp = 0x00, mask = 0xFF;
int p = 0,q = 0;
if (concate == 2)
{
temp = hex[0] >> 1;
dest[0] = temp;
dest[1] = hex[1] & 0x7F;
temp = hex[1] >> 7;
len = len - 7;
p = 1; q = 1;
}
for (i=p,j=0,l=q;l<len;i++,j++,l++)
{
if (j==8)
{
dest[l] = temp & 0x7F;
temp = temp>>7;
j=1; l++;
}
dest[l] = ((hex[i] & (mask>>(j+1))) << j) | temp;
temp = hex[i] >> (7-j);
if (dest[l] == 0x00) dest[l] = 0x40;
}
}
唯一的改变
这是在 dev c 中完美运行的函数。我只为stm32更改了这个功能。
void PDU_to_Text(char *src,char *dest)
{
char Len[2];
char str[150];
int UserDataLen;
uint8_t msg_no,total_msg;
msg_no = 1;
do
{
printf("\n\nEnter message %d: \n",msg_no);
gets(src);
concate = CheckForConcate(src);
total_msg = CheckForTotal_msg(src);
Remove_Carriag_LineFeed(src);
Eliminate_Extras(src);
uint8_t startingPoint = CheckStartingPoint(src);
GetUserData(src,Len,startingPoint);
UserDataLen = DecodeTwoBitData(Len);
Decode_PDU(src,str,UserDataLen);
if (msg_no==1)
strcpy(dest,str);
else
{
int i=0,j=0;
while(dest[i]!='\0') {i++;}
while(str[j]!='\0')
{
dest[i] = str[j];
i++;j++;
}
}
msg_no++;
}while (msg_no <= total_msg);
}
我不知道我哪里出错了。任何建议都会非常有帮助。
提前致谢。