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;
} 这个程序就是说aa 和55 是标志位,当标志位通过后,把后边的数据长度02,两个数据01,02,及校检和05存入数组,当写了三个printf想把长度位02及数据位01 02都显示出来后,串口显示的确实一大堆数据,而不是想要的三个数据即02 01 02 本帖最后由 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); lcw_swust 发表于 2015-5-15 10:58
如果串口助手选择的是"文本模式",那就会显示
2256256
看起来printf的执行没错,楼主却是不需要这种显 ...
我按照你说的改动了,然后发送串口上显示的如下,02 00 00 是HEX时,特殊符号是文本格式时,就是说 HEX格式时,是三个数据,这一步应该是对的,但是两个00是不对的
我觉得程序逻辑思路没问题,是不是数据类型有错?? xihua13104 发表于 2015-5-15 17:04
我按照你说的改动了,然后发送串口上显示的如下,02 00 00 是HEX时,特殊符号是文本格式时,就是说 HEX格 ...
其实我写这个print函数就是想看看存储在数组里的数据是不是我想要的020102,如果存储的都不对,接下来肯定也用不起 xihua13104 发表于 2015-5-15 20:43
其实我写这个print函数就是想看看存储在数组里的数据是不是我想要的020102,如果存储的都不对,接下来肯 ...
我也没看出什么大问题,
有个疑问: 串口中断为什么有个delay(1) lcw_swust 发表于 2015-5-17 20:53
我也没看出什么大问题,
有个疑问: 串口中断为什么有个delay(1)
当时觉得可能是中断接收数据紊乱了,就胡乱加了个delay(1);{:cry:}
页:
[1]