0

我已经用 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);   
}

我不知道我哪里出错了。任何建议都会非常有帮助。

提前致谢。

4

0 回答 0