首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

串口收到字符后进展转换

2013-12-11 
串口收到字符后进行转换如果串口收到收据,如何进行格式转换?比如我想把每个数据都转成对应的16进制ascii,

串口收到字符后进行转换
如果串口收到收据,如何进行格式转换?
比如我想把每个数据都转成对应的16进制ascii,并且转完后,以固定格式发送出去,比如a,就是AT%IPSEND="61",比如b,就是AT%IPSEND="62",ab就是AT%IPSEND="6162"
下面是教科书上的程序:
#include <reg52.h>
#define uchar unsigned char ;
bit Flag;   //串口接收到字符的标志
unsigned char UartChar;

    
/*--------------------------------------------------------------
                           函数声明
--------------------------------------------------------------*/
void InitUART(void);
void SendByte(unsigned char dat);
void SendStr(unsigned char *s);

/*--------------------------------------------------------------
                            主函数
--------------------------------------------------------------*/
void main (void)
{
    //串口初始化
    InitUART();

    SendStr("\r\n\n SZ-51 UART test OK if you see these words!");
    SendStr("\r\n ARM技术论坛 神舟51开发板 单片机串口收发测试");
    SendStr("\r\n 神舟51开发板,中断方式接收,请输入字符:");
    
    Flag = 0;
    while (1)                       
    {
        if(Flag == 1) 
        {
            Flag = 0;
            SendByte(UartChar);
            if(UartChar == '\r')
            {
                SendByte('\n');
            }
        }
    }
}

/*--------------------------------------------------------------
                            串口初始化
--------------------------------------------------------------*/
void InitUART(void)
{

    SCON  = 0x50;   // SCON: 模式 1, 8-bit UART, 使能接收  
    TMOD |= 0x20;   // TMOD: timer 1, mode 2, 8-bit 重装
    //TH1 = 0xF3;   // 波特率4800、数据位8、停止位1。效验位无 (12M)
    TH1   = 0xFD;   // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
    TR1   = 1;      // TR1:  timer 1 打开                         
    EA    = 1;      //打开总中断
    ES    = 1;      //打开串口中断
}                            

/*--------------------------------------------------------------
                            发送一个字节
--------------------------------------------------------------*/
void SendByte(unsigned char dat)
{
    SBUF = dat;
    while(!TI);
    TI = 0;
}

/*--------------------------------------------------------------
                            发送一个字符串
--------------------------------------------------------------*/
void SendStr(unsigned char *s)
{
    //检测是否字符串末尾, '\0'表示字符串结束标志,
    while(*s != '\0')
    {
        SendByte(*s);
        s++;
    }
}

/*--------------------------------------------------------------
                     串口中断程序
--------------------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
    if(RI)                  //判断是接收中断产生


    {
        RI=0;               //标志位清零
        UartChar = SBUF;    //读入缓冲区的值
        Flag = 1;           //把值输出到P1口,用于观察
    }
    
    if(TI)                  //如果是发送标志位,清零
    {
        //TI=0;             //发送为查询方式
    }



串口中断接收到的数据都是一个字符一个字符的往回传的,中断通过收SBUF传给UartChar,UartChar再传给发的SBUF,然后就发出去了。
我现在想转换,但是UartChar进行操作,我是这么操作的,
                       uchar buf3[4],buffer[]="AT%IPSEND="",*buf4,buf1[32];
                        buf3[0]=UartChar;
buf4=buffer;
SendStr(buf3);
hextodstr(buf3);
strcat(buf3,""\n\r");
SendStr(buf3);
                        strcat(buf4,buf3);
        SendStr(buf4);   
               uchar  *hextodstr(uchar * src)
{
uchar i=0;
while(*src!=0)
{
   buf1[2*i]=*src/16+'0';
   buf1[2*i+1]=(*src%16)+'0';
   src++;
   i++;
   if(i>=16)
   {
//缓冲区不够
buf1[32]=0;
 //  return buf1;
   }
}
buf1[i*2]=0;//忘记给字符串补结束符了
return buf1;
}
这样做以后,我用DEBUG模式调试,也看不出来什么异常。while循环内我用的静态变量,那个几个buf都是静态的,这样下次调用就不会被累加了,但是结果是错误的。
[解决办法]

void trans(char* buff, char* str)
{
#define STR_HEAD "AT%IPSEND=""
#define HEAD_SIZE sizeof(STR_HEAD)-1
memcpy(buff, STR_HEAD, HEAD_SIZE);
buff+=HEAD_SIZE;
while (*str)
{
sprintf(buff,"%.2x", *str);
buff+=2;
str++;
}
*buff++ = '"';
*buff = 0;
}


http://ideone.com/7hTHCz
[解决办法]
错误较多
引用
uchar buf3[4],buffer[]="AT%IPSEND="",*buf4,buf1[32];
                        buf3[0]=UartChar;
buf4=buffer;
SendStr(buf3);             // buf[3]只给[0]置了UartChar,后面的都是随机数,是否该给[1]=0
hextodstr(buf3);
strcat(buf3,""\n\r");     // 比如buf3[0]='a',就算buf3[1]=0,这个拼接了"\n\r三个字符后buf3[4]
                           // 长度不够,没法放最后的结束0
SendStr(buf3);
                        strcat(buf4,buf3); // 同样的buf4在第一条语句中被你指向了buffer,而buffer
                                           // 在你定义时就初始化给了固定的大小,哪里还能strcat?
        SendStr(buf4);   
               uchar  *hextodstr(uchar * src)
{
uchar i=0;
while(*src!=0)
{
   buf1[2*i]=*src/16+'0';
   buf1[2*i+1]=(*src%16)+'0';
   src++;
   i++;
   if(i>=16)
   {
//缓冲区不够
buf1[32]=0;                     

// buf1定义的大小就是32,下标从 0-31 , [32]明显越界
 //  return buf1;
   }
}
buf1[i*2]=0;//忘记给字符串补结束符了
return buf1;
}



最后,给你一段代码参考:

uchar buf1[32], buf3[16];  // 根据你自己的长度设置
uchar ucChar[] = "A1&b";  // 这个例子有大小写字母和数字以及特殊符号
strcpy(buf1, "AT%IPSEND="");
sprintf(buf3, "%02x%02x%02x%02x", ucChar[0], ucChar[1], ucChar[2], ucChar[3]);
strcat(buf1, buf3);
strcat(buf1, """);



最后得到的buf1就是AT%IPSEND="41312662",包括双引号,是你要的结果。
[解决办法]
通常发送 是 不使用 中断的, 因为 何时要发送 你是 知道的,如果 使用 中断,
有时 会 发生 中断 丢失,(以后的 东西 就 发不出去了)。
 

热点排行