xihua13104 发表于 2015-5-14 21:40:48

15的串口通信状态机的问题,写了三个printf,串口显示了一堆

/************************************
*函数名:void state(int i[],int o[])
*功能:满足通讯协议为   起始标志    数据长度   数据      校验和    校验和为数据长度位加数据位
                                          0xaa 0x55   0X02               0X01 0X02        0X06
*调用方式:1、 在串口中断中调用 serial_interrupt(int in_data);
                   2、 在主程序中定时调用int get_data_flag() 返回为1 数据成功接收,0不成功
*输入参数:             
*输出参数: rx_data[]
*
************************************/
#include<stc15.h>
#include<stdio.h>
#define fosc 12000000L
#define baud9600
#define rx_data_len 20       //状态机接收数组缓存大小
int state=0;//中断状态值
int rx_data={0};//接收数组
int serial_flag;       //状态机接收完成标志位
int datawidth,count=0;          //数据宽度输出数组指针
int over_flag=1;
unsigned char i,flag;
bit a;
void delay2s(void)   //误差 0us
{
    unsigned char a,b,c,n;
    for(c=142;c>0;c--)
      for(b=168;b>0;b--)
            for(a=250;a>0;a--);
    for(n=1;n>0;n--);
}
void delay(unsigned int xms)
{
        unsigned int c,d;
        for(c=xms;c>0;c--)
                for(d=110;d>0;d--);
}
void init()
{
                                    //定时器2工作模式固定为16位自动重装模式
SCON=0X50;            //串口1工作方式1,八位BART,波特率可变,波特率=定时器溢出率/4
AUXR=0X14;            //允许定时器2运行,且定时器2为传统8051的12倍
AUXR|=0X01;         //选择定时器2作为串口一的波特率发生器,此时定时器1得到释放
T2L=(65536-(fosc/baud/4));
T2H=(65536-(fosc/baud/4))>>8;
EA=1;
ES=1;
}
/*******************
串口中断中调用 每接收一次数据调用一次
输入参数:in_data 串口接收到的数据
*******************/
void serial_interupt(int in_data)
{
   if(serial_flag==0)
    {
          switch(state)
          {
          case 0: if(in_data==0xaa) state=1;
                        break;
                case 1: if(in_data==0x55) state=2;else state=0;
                              break;
          case 2: datawidth=in_data;state=3;rx_data=datawidth;        //rx_data存放数据长度
                                break;
                case 3: if(count>=rx_data_len-1)
                        {
                                   count--;
                                }
                                else
                                {
                                   count++;
                                }
                               rx_data=in_data;
                                                        if(count>=datawidth+1)       
                                                        {       
                                                                state=0;
                                                                count=0;
                                                                serial_flag=1;
                                                                over_flag=0;
                                                                if(flag==1)                  //串口显示
                                                                {
                                                                        flag=0;
                                                                        ES=0;
                                                                        TI=1;
                                                                        printf("%i",rx_data);        //问题所在!!!
                                                                        printf("%i",rx_data);        //!!!!!!!
                                                                        printf("%i",rx_data);        //!!!!!!!
                                                               
                                                                        while(!TI);
                                                                        TI=0;
                                                                        ES=1;
                                                                }
                                                        }
                                                        break;
                     default: state=0;
                                                count=0;
                                break;
          }
        }
        delay(1);
}
void Sum_check(void) //校验数据位 返回1校验成功 0不成功
{
unsigned int checksum=0;
    P0=0;                //1-8
    delay2s();
               
        if(serial_flag==1)
        {       
          P0=0xf8;          //123
      delay2s();
               
                serial_flag=0;
                for(i=0;i<=rx_data;i++)
                {
               checksum+=rx_data;
               delay(1);
                }
                if(Sum_check==rx_data+1])               
         a=1;
               else
               a=0;
        }
        else
        {
        a=0;
        }
          
}

void main()
{
init();
while(1)
{
    P0=0xfe;       //流水灯1
    if(over_flag==0)
           {
      Sum_check();
          if(a==1)
      {
          P0=0x01;        //1-7
      delay2s();
          break;
          }
      else
      {
          break;
          }
           }       
}
   while(1);
}

void Uart() interrupt 4 using 1
{
   delay(1);
       RI=0;
   serial_interupt(SBUF);
       flag=1;   
}

xihua13104 发表于 2015-5-15 10:12:29

这个程序就是说aa 和55 是标志位,当标志位通过后,把后边的数据长度02,两个数据01,02,及校检和05存入数组,当写了三个printf想把长度位02及数据位01 02都显示出来后,串口显示的确实一大堆数据,而不是想要的三个数据即02 01 02

lcw_swust 发表于 2015-5-15 10:58:35

本帖最后由 lcw_swust 于 2015-5-15 11:01 编辑

如果串口助手选择的是"文本模式",那就会显示
2256256
看起来printf的执行没错,楼主却是不需要这种显示,那就简单了,直接串口发送单字节就是了,何必用printf

void uart1_sendbyte(char ud)
{
        TI=0;//清发送标志
        SBUF=ud;
        while(TI==0);                                //等待它由0变为1                                       
}

uart1_sendbyte(rx_data);
uart1_sendbyte(rx_data);
uart1_sendbyte(rx_data);

xihua13104 发表于 2015-5-15 17:04:38

lcw_swust 发表于 2015-5-15 10:58
如果串口助手选择的是"文本模式",那就会显示
2256256
看起来printf的执行没错,楼主却是不需要这种显 ...

我按照你说的改动了,然后发送串口上显示的如下,02 00 00 是HEX时,特殊符号是文本格式时,就是说 HEX格式时,是三个数据,这一步应该是对的,但是两个00是不对的
我觉得程序逻辑思路没问题,是不是数据类型有错??

xihua13104 发表于 2015-5-15 20:43:48

xihua13104 发表于 2015-5-15 17:04
我按照你说的改动了,然后发送串口上显示的如下,02 00 00 是HEX时,特殊符号是文本格式时,就是说 HEX格 ...

其实我写这个print函数就是想看看存储在数组里的数据是不是我想要的020102,如果存储的都不对,接下来肯定也用不起

lcw_swust 发表于 2015-5-17 20:53:37

xihua13104 发表于 2015-5-15 20:43
其实我写这个print函数就是想看看存储在数组里的数据是不是我想要的020102,如果存储的都不对,接下来肯 ...

我也没看出什么大问题,
有个疑问: 串口中断为什么有个delay(1)

xihua13104 发表于 2015-5-18 18:55:31

lcw_swust 发表于 2015-5-17 20:53
我也没看出什么大问题,
有个疑问: 串口中断为什么有个delay(1)

当时觉得可能是中断接收数据紊乱了,就胡乱加了个delay(1);{:cry:}
页: [1]
查看完整版本: 15的串口通信状态机的问题,写了三个printf,串口显示了一堆