|
小弟设计了一个模拟串口的发送接收程序,调试的时候第一个数据是错误的
[复制链接]
利用的单片机资源:P1_0用来接收PC机下发的数据(一个起始位,八个数据位,一个结束位),P1_1用来发送数据,外部中断0,定时器1(用来接收数据),定时器中断0(用来发送数据)。波特率9600bps
实现的功能:单片机能正确返回PC机下发的数据。
现在的问题:通过串口调试助手调试,单片机复位后,总是第一个返回的数据是错误的,后面的数据就正确了。(数据的发送函数部分通过测试调试,没有问题)。
目前发现存在的问题:通过修改程序,示波器观察,第一次的数据采样点位置不对,后发数据的采样点就对了。应该是PC机下发数据后,单片机检测到下降沿后,立马触发外部中断,单片机接着就执行数据采集的动作。。可是通过示波器观察后,发现采样点在下降沿后面延迟了300us。延迟了一个位还多才进行的数据采集动作。。
*****************************************************************************************
感觉逻辑上没有出现问题,现在把程序贴上来,希望大神帮我看看,哪里出的问题,小弟感激不尽,先表示感谢啦!!
*****************************************************************************************
# include
//# include
sbit P1_3 = P1^3; //数据输出使能控制管脚
sbit P1_0 = P1^0; //数据输出管脚
sbit P1_1 = P1^1; //数据出入管脚
//unsigned char temp[8];
unsigned char Flag = 0;
unsigned char TxdCnt=0;
unsigned char TxdData;
unsigned char RxdData;
unsigned char RxdFlag;
unsigned char JudgeBit(void);
void SimTxd(unsigned char TData);
//此函数是用来发送数据的
void SimTxd(unsigned char TData)
{
TH0 = 0xA0;
TR0 = 1;
ET0 = 1;
EX0 = 0;
TxdData = TData;
while(TxdCnt<=9)
{
}
TxdCnt = 0;
TR0 = 0;
ET0 = 0;
EX0 = 1;
}
//此函数是用来判断串口发出的每一位是0还是1
//判断规则:每一位中四次取值(把每一位平均分成四段),
//最后一次值舍去,只取前三次的值
unsigned char JudgeBit(void)
{
unsigned char i = 0;
unsigned char Cnt = 0;
TH1 = 0xE8;
TR1 = 1;
TF1 = 0;
for(i=0;i<=3;i++)
{
while(!TF1)
{}
if(P1_1&&(i<=2))
Cnt++;
TF1 = 0;
}
if(Cnt>=2)
return 1;
else
return 0;
}
//初始化
void MCU_Init(void)
{
IT0 = 1;
TMOD = 0x22;
EA = 1;
ET1 = 0;
EX0 = 1;
ET0 = 0;
}
void main()
{
MCU_Init();
RxdFlag = 0;
while(1)
{
if(RxdFlag)
{
SimTxd(RxdData);
RxdFlag = 0;
}
// delay(1000);
}
}
//PC机下发的数据接到P1_1,并一块接到INT0,利用起始位下降沿信号触发外部中断0,
//进入到数据接收处理
void INT0_Rxd(void) interrupt 0
{
EX0 = 0;
Flag = JudgeBit();
if(!Flag)
{
unsigned char j;
unsigned char b[8];
for(j=0;j<=7;j++)
b[j] = JudgeBit();
for(j=0;j<=7;j++)
{
RxdData>>=1;
if(b[j])
RxdData|=0x80;
else
RxdData|=0x00;
// Rdata>>=1;
}
RxdFlag = 1;
}
EX0 = 1;
}
//通过定时器0中断,用来发送数据,波特率9600bps
void time0(void) interrupt 1
{
// TxdCnt ++;
switch(TxdCnt)
{
case 0:
P1_0 = 0;break;
case 9:
P1_0 = 1;break;
default:
if(TxdData&0x01)
P1_0 = 1;
else
P1_0 = 0;
TxdData>>=1;
break;
}
TxdCnt++;
}
|
|