求助:stc串口程序遇到00后面的数据丢失,急!急!
请教各位高手,我的程序2为什么从机接受数据遇到0x00后,后面的数据接受不到了?急!急!急!
void main()
{
uint i = 0;
//定时器0初始化
Timer0Init();
// 调整输入函数的加载值可以改变串口波特率
Uart1Init(0,1,253);//初始化串口1,设置波特率115200
Uart2Init(1,0,1,220);//初始化串口2,设置波特率9600
Uart2SendStr("AT1#/r");
//主机发送AT1#,测距仪从机应答:ATD+3字节距离数据+校验和+结束符#
//例如:测距距离6692.4mm,距离大于6553.6mm接受正常
//主机发送Hex:41 54 31 23,从机应答Hex:41 54 44 011A 03 1E 23
//41 54 44 01 05 6C 72 23
// A T D 6692.4mm 校验和 # 十六进制数:1056c = 66924 结束符:#
// 校验和(只取后2位):01+05+6c=72
//当距离小于6553.6mm接受不正常,即3字节高位为00时就不正常只能显示4154 44
//比如5763.1mm测距仪直接接串口调试助手程序1显示41 54 44 00 E1 1F 00 23
//程序2显示41 54 44
//以下是相关联程序:
/*------------------------------------------------------------------*/
/*----------------------程序1-------------------------*/
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 11059200L //System frequency
#define BAUD 9600 //UART baudrate
/*Define UART parity mode*/
#define NONE_PARITY 0 //None parity
#define ODD_PARITY 1 //Odd parity
#define EVEN_PARITY 2 //Even parity
#define MARK_PARITY 3 //Mark parity
#define SPACE_PARITY 4 //Space parity
#define PARITYBIT EVEN_PARITY //Testing even parity
/*Declare SFR associated with the UART2 */
sfr AUXR = 0x8e; //Auxiliaryregister
sfr S2CON = 0x9a; //UART2 control register
sfr S2BUF = 0x9b; //UART2 data buffer
sfr BRT = 0x9c; //Baudrate generator
sfr IE2 = 0xaf; //Interruptcontrol 2
#define S2RI 0x01 //S2CON.0
#define S2TI 0x02 //S2CON.1
#define S2RB8 0x04 //S2CON.2
#define S2TB8 0x08 //S2CON.3
bit busy;
void SendData(BYTE dat);
void SendString(char *s);
void main()
{
#if (PARITYBIT == NONE_PARITY)
S2CON = 0x50; //8-bitvariable UART
#elif (PARITYBIT == ODD_PARITY) ||(PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
S2CON = 0xda; //9-bitvariable UART, parity bit initial to 1
#elif (PARITYBIT == SPACE_PARITY)
S2CON = 0xd2; //9-bitvariable UART, parity bit initial to 0
#endif
BRT = -(FOSC/32/BAUD); //Setauto-reload vaule of baudrate generator
AUXR = 0x14; //Baudrategenerator work in 1T mode
IE2 = 0x01; //EnableUART2 interrupt
EA = 1; //Openmaster interrupt switch
SendString("STC12C5A60S2\r\nUart2 Test !\r\n");
while(1);
}
/*----------------------------
UART2 interrupt service routine
----------------------------*/
void Uart2() interrupt 8 using 1
{
if (S2CON & S2RI)
{
S2CON &= ~S2RI; //Clearreceive interrupt flag
P0 = S2BUF; //P0 show UARTdata
P2 = (S2CON & S2RB8);//P2.2 show parity bit
}
if (S2CON & S2TI)
{
S2CON &= ~S2TI; //Cleartransmit interrupt flag
busy = 0; //Cleartransmit busy flag
}
}
/*----------------------------
Send a byte data to UART
Input: dat (data to be sent)
Output:None
----------------------------*/
void SendData(BYTE dat)
{
while (busy); //Wait forthe completion of the previous data is sent
ACC = dat; //Calculate the even parity bit P (PSW.0)
if (P) //Set theparity bit according to P
{
#if (PARITYBIT == ODD_PARITY)
S2CON &= ~S2TB8; //Setparity bit to 0
#elif (PARITYBIT == EVEN_PARITY)
S2CON |= S2TB8; //Set paritybit to 1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
S2CON |= S2TB8; //Set paritybit to 1
#elif (PARITYBIT == EVEN_PARITY)
S2CON &= ~S2TB8; //Setparity bit to 0
#endif
}
busy = 1;
S2BUF = ACC; //Senddata to UART2 buffer
}
/*----------------------------
Send a string to UART
Input: s (address of string)
Output:None
----------------------------*/
Void Uart2SendStr (char *s)
{
while (*s) //Checkthe end of the string
{
SendData(*s++); //Send currentchar and increment string ptr
}
}
/********************程序1结束****************/
/********************程序段2开始****************/
#include "systerm.h"
uchar GsmRcv[MAXRCV] = {0};
uchar DebugBuf_U2[MAXBUF] = {0};
uchar DebugBuf_U1[MAXBUF] = {0};
uchar GsmRcvCnt = 0;
uchar GsmAtFlag = 0;
uchar GsmAtFlag2 = 0;
uchar Debug2RcvCnt = 0;
uchar Debug1RcvCnt = 0;
bit uart2Sending = 0;
bit uart1Sending = 0;
uchar receive_number[13]={0};//接收串口发送来的数据的数组
uchar i=0;
uchar j;
/***************************串口2初始化函数函数*****************************/
/*函数原型:charUart2Init(char s2smod,char brtx12,unsigned char reload)
/*函数功能:初始化用于连接gprs的串口2 ,串口2只能设置为独立波特率提供波特率
并打开串口2中断和全局中断
/*输入参数: S2_P4 S2_P4位 0/1 0:RXD2(P1.2)TXD2(P1.3) 1:RXD2(P4.2)TXD2(P4.3)
smod s2smod位 0/1
brtx12 brtx12位 0/1
reload reload寄存器数值 0-255
/*输出参数: -1 s2smod位错误,没有写入0/1
-2 brtx12位错误,没有写入0/1
0 微波
/********************************************************************/
char Uart2Init(char s2_p4,char s2smod,charbrtx12,unsigned char reload)
{
S2CON= 0X50;//8位可变波特率,无奇偶位
BRT = reload;//设置独立波特率发生器波特率
if(s2_p4== 1)
{
AUXR1|= S2_P4; //S2_P4 = 1;//将串口2映射到P4口,1:RXD2(P4.2)TXD2(P4.3)
}
elseif(s2_p4 == 0)
{
AUXR1&= (~S2_P4); //S2_P4 = 0;//将串口2映射到P1口,0:RXD2(P1.2)TXD2(P1.3)
}
else
{
return-4;
}
if(s2smod== 1)
{
AUXR|= S2SMOD; //S2SMOD = 1;//波特率倍速位
}
elseif(s2smod == 0)
{
AUXR&= (~S2SMOD); //S2SMOD = 0;//取消波特率倍速位
}
else
{
return-1;
}
if(brtx12== 1)
{
AUXR|= BRTx12;//BRTx12 = 1;1T模式
}
elseif(brtx12 == 0)
{
AUXR&= (~BRTx12);//BRTx12 = 0;12T模式
}
else
{
return-2;
}
AUXR|= BRTR;//开启波特率发生器
//设置串口2中断优先级
IP2H|= PS2H; //设置串口2优先级为3(最高)
IP2|= PS2;
if(UART2_PRIO & 0x02)
{
IP2H|= PS2H;
}
else
{
IP2H&= ~PS2H;
}
if (UART2_PRIO & 0x01)
{
IP2|= PS2;
}
else
{
IP2&= ~PS2;
}
IE2|= ES2;// ES2 = 1; //允许串口2中断
EA= 1; //开总中断
return0;
}
/***************************串口2发送字符函数************************/
/*函数原型:voidUart2SendHex(uchar i)
/*函数功能:串口2发送函数,发送单一数据
/*输入参数:数据
/*输出参数:无
/********************************************************************/
void Uart2SendHex(uchar i)
{
while(uart2Sending== 1);
uart2Sending= 1;
S2BUF= i;//装入数据
}
/***************************串口2发送字符串函数**********************/
/*函数原型:void Uart2SendStr(char*data_at)
/*函数功能:串口2发送函数,发送字符串
/*输入参数:字符串指针
/*输出参数:无
/********************************************************************/
void Uart2SendStr(char* data_at)
{
while(*data_at)
{
Uart2SendHex(*data_at++);
}
}
/***************************串口1初始化函数**********************/
/*函数原型:charUart1Init(char smod,char brtx12,unsigned char reload)
/*函数功能:串口1初始化
/*输入参数: smod smod位 0/1
brtx12 brtx12位 0/1
reload reload寄存器数值 0-255
/*输出参数: -1 smod位错误,没有写入0/1
-2 brtx12位错误,没有写入0/1
0
/*备注:串口设置位独立波特率提供波特率,和串口2使用同一个波特率,也可以使用定时器1来提供波特率
/********************************************************************/
char Uart1Init(char smod,charbrtx12,unsigned char reload)
{
SCON= 0X50;//8位可变波特率,无奇偶位(SM0=0,SM1=1),使能串口接收模块(REN=1)
BRT = reload;//设置独立波特率发生器波特率
if(smod== 1)
{
PCON|= SMOD; //SMOD = 1;//波特率倍速位
}
elseif(smod == 0)
{
PCON&= (~SMOD); //SMOD = 0;//取消波特率倍速位
}
else
{
return-1;
}
if(brtx12== 1)
{
AUXR|= BRTx12;//BRTx12 = 1;1T模式
}
elseif(brtx12 == 0)
{
AUXR&= (~BRTx12);//BRTx12 = 0;12T模式
}
else
{
return-2;
}
AUXR |= S1BRS;//串口1设置为使用独立波特率发生器
AUXR|= BRTR;//开启波特率发生器
//设置串口1中断优先级
if(UART1_PRIO & 0x02)
{
IPH|= PSH;
}
else
{
IPH&= ~PSH;
}
if (UART1_PRIO & 0x01)
{
PS= 1;
}
else
{
PS= 0;
}
ES= 1; //开串口中断
EA= 1; //开总中断
return0;
}
/***************************串口1发送函数**********************/
/*函数原型:voidUart1SendHex(char i)
/*函数功能:串口1发送函数
/*函数功能:串口1发送函数,发送单一数据
/*输入参数:数据
/*输出参数:无
/**************************************************************/
void Uart1SendHex(char i)
{
while(uart1Sending);//等待发送完毕
uart1Sending= 1;
SBUF= i;//将数据放入寄存器发送
}
/***************************串口1发送字符串函数**********************/
/*函数原型:voidUart1SendStr(char* data_at)
/*函数功能:串口1发送函数,发送字符串
/*输入参数:字符串指针
/*输出参数:无
/********************************************************************/
void Uart1SendStr(char* at)
{
while(*at) //判断一串数据是否结束
{
Uart1SendHex(*at++);//发送数据
}
}
/***************************串口1发送接收中断函数********************/
/*函数原型:voidUart1InterruptReceive(void) interrupt 4
/*函数功能:串口2发送接收中断函数
/*输入参数:无
/*输出参数:无
/*备注:接收函数内部不可以放入其他的中断或者发送函数,否则影响接收数据
/********************************************************************/
void Uart1InterruptReceive(void) interrupt4
{
chartmp = 0;
if(RI)
{
ES=0;//关串行口中断
RI=0;//接收中断信号清零,表示将继续接收
tmp= SBUF;//接收数据
#ifdef UART1_DEBUG
//将接收到的数据放入DebugBuf_U1,在定时器内,DebugBuf_U1会被串口2发送给GSM模块。
//这样通过串口1发送到单片机的数据GSM模块就可以收到了,主要为了调试的方便。
DebugBuf_U1[Debug1RcvCnt]= tmp;
Debug1RcvCnt++;
if(Debug1RcvCnt>=MAXBUF-1)
{
Debug1RcvCnt= 0;
}
#endif
ES=1;//开串行口中断
}
if(TI)
{
TI= 0;
uart1Sending= 0;
}
}
/***************************串口2发送接收中断函数**********************/
/*函数原型:voidUart2InterruptReceive(void) interrupt 8
/*函数功能:串口2发送接收中断函数
/*输入参数:无
/*输出参数:无
/*备注:接收函数内部不可以放入其他的中断或者发送函数,否则影响接收数据
用于接收GPRS模块传输来的数据,将数据保存到GsmRcv[],在函数中使用strstr判断数据。
/********************************************************************/
void Uart2InterruptReceive(void) interrupt8
{
unsignedchar tmp = 0;
uchari = 0;
ucharm = 0;
IE2&= (~ES2); //关闭串口2中断//ES2 = 0;
if(S2CON& S2RI) //if(S2RI == 1)
{
S2CON&= (~S2RI);//S2RI = 0;
tmp= S2BUF;
#ifdef UART1_DEBUG
//将接收到的数据放入DebugBuf_U2,在定时器内,DebugBuf_U2会被串口1发送给PC机。
//这样GSM发送给单片机的数据也可以在电脑上观察到了。
//H1005071 1597422124 2000-01-01 01:01:01 0a0d
DebugBuf_U2[Debug2RcvCnt]= tmp;
Debug2RcvCnt++;
if(Debug2RcvCnt>=MAXBUF-1)
{
Debug2RcvCnt= 0;
}
#endif
GsmRcv[GsmRcvCnt]= tmp;
GsmRcvCnt++;
if(GsmRcvCnt> MAXRCV)
{
GsmRcvCnt= 0;
GsmAtFlag2= 1;
// m= 0;
}
}
if(S2CON& S2TI)
{
S2CON&= ~S2TI;
uart2Sending= 0;
}
IE2|= ES2;//ES2 = 1;
}
/***************************初始化定时器0****************************/
/*函数原型:Timer0Init
/*函数功能:初始化定时器0
/*输入参数:无
/*输出参数:无
/********************************************************************/
voidTimer0Init(void)
{
TMOD=0x01; //设置定时器0为工作方式1
//AUXR|=T0x12;
TH0=T0H; //放入初值,11.0592M,1ms
TL0=T0L;
// 设置定时器0中断优先级(优先级1)
IPH &= ~PT0H;
PT0 = 1;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
}
/***************************定时器0中断******************************/
/*函数原型:Timer0
/*函数功能:每1ms执行一次中断,中断内部重新赋值
/*输入参数:无
/*输出参数:无
/********************************************************************/
void timer0()interrupt 1
{
uchar i = 0;
TH0=T0H;
TL0=T0L;
#ifdefUART1_DEBUG//发送数据用于调试。
timer0_debug_cnt++;
if(timer0_debug_cnt== 20)
{
timer0_debug_cnt= 0;
for(i=0;i<MAXBUF; i++)
{
DebugBuf_U2 =0;
}
Debug2RcvCnt = 0;
Uart2SendStr(DebugBuf_U1);
for(i=0;i<MAXBUF; i++)
{
DebugBuf_U1 =0;
}
Debug1RcvCnt = 0;
}
#endif
timer0_cnt++;
if(timer0_cnt ==1000)
{
timer0_cnt = 0;
sec_cnt++;
}
#ifdefSHOW_TIME_DEBUG
if(timer0_cnt ==500)
{
//显示时间
ShowTime(0, 4);
//显示日期
ShowDate(0, 5);
}
#endif//SHOW_TIME_DEBUG
}
/***************************程序段2结束**************************/
很明显的问题,你根本不可能发送0