[求助] 小弟设计了一个模拟串口的发送接收程序,调试的时候第一个数据是错误的

sjz4167   2012-8-8 15:43 楼主
利用的单片机资源: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++;
               
}

回复评论 (2)

哎。。第一次发帖,就没人响应。。悲剧。。不知道为何。。
点赞  2012-8-17 16:40
这个时间应该是单片机压栈用的时间。不过感觉还是有点儿长,
点赞  2012-8-17 22:36
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复