51单片机的定时器0和串口同时使用问题,急!

xsyxxxxx   2009-9-14 21:36 楼主
这是我的程序:当定时器打开后就接收不到数据了,屏蔽掉定时器就可以了!请大侠指教原因所在!
/*************************************************************/
/*本设计采用STC89C52单片机                                   */
/*                                                           */
/*晶振为11.0592M                                             */
/*************************************************************/
#include
#include

#define uchar unsigned char
/***************************变量定义***************************/
int timecount=0;            //定时器计数
uchar flag=0;               //是否超时未取走电池标志
uchar state=0;              //状态标志
uchar rec=0x00;             //接收数据
uchar f_rec=0;                   //接收标志
/***************************端口定义***************************/
sbit Battery=P1^0;               // 有无电池
sbit Hand=P1^1;                  //有无手阻挡
sbit Output=P1^2;                //夹具松开或闭合
/*************************************************************/
/*函数功能:初始化定时器0,定时时间设置为50ms                 */
/*入口参数:无                                               */
/*出口参数:无                                               */
/*************************************************************/
void init_timer0(void)
        {
         TMOD=0x01;               //定时器工作在方式1
         TH0=0x04;                //定时初值设置为定时50ms
     TL0=0xBF;
     ET0=1;
        }  
/*************************************************************/
/*函数功能:定时器0中断服务程序                              */
/*入口参数:无                                               */
/*出口参数:无                                               */
/*************************************************************/
void timer0() interrupt 1                       
        {
         TR0=0;
         timecount++;
         if(timecount==400)     //当从CTS接收停止信号1时或夹具关闭到达20s
                {
                 Output=1;          //松开夹具
                   TR0=0;             //关闭定时器
                 timecount=0;       //定时计数清零
                 flag=1;            //置位超时标志
                }
                else
                   {
                    init_timer0();
                        TR0=1;
                        }
       
        }

/*************************************************************/
/*函数功能:串行接收中断服务程序                             */
/*入口参数:无                                               */
/*出口参数:无                                               */
/*************************************************************/
void uart( ) interrupt 4
        {
                if(RI)
                 {
                  RI=0;
                    rec=SBUF;         //接收一个数据
                  if(rec==0x01)
                   f_rec=1;
                  
                 }
        }
/*************************************************************/
/*函数功能:延时函数,最小延时单位1ms                        */
/*入口参数:延时时间                                         */
/*出口参数:无                                               */
/*************************************************************/
void delay(int t)
        {
     int i=0,j=0,k=0;
         for(;t>0;t--)
                for(;i<100;i++)
                        for(;i<120;i++);
        }

void main()
        {
         TMOD=0x20;//设置定时器1为工作方式2
         TH1=0xfd;
         TL1=0xfd;
         TR1=1; //开定时器
         SCON=0x50;
         PCON=0x80;
         EA=1;//总中断
         ES=1;//串口中断允许位
         //IP=0x10;                               //设置串行中断为高优先级
         P1=0x03;                               //置平P1.0及P1.1为输入模式
         Output=1;
         init_timer0( );                      //默认情况下,夹具松开
     while(1)
                {
                 
                 if(Battery==1&&Hand==0)   
                             {
                         delay(500);                 //延时500ms以防止误判                                 
                                   if(Battery==1&&Hand==0)       //当夹具上有电池且手已经拿开,闭合夹具
                                {
                 
                                  while(flag)              //有超时未取走的电池时,等待将电池拿走     
                                        {
                                         if(Battery==0&&Hand==0) //超时电阻已经取走
                                                {
                                                 flag=0;
                                                 state=1;
                                                 f_rec=0;//清零f_rec
                                                }
                                        }
                                 if(state==0)
                                          {
                                         TR0=1;
                                            
                                         if(f_rec==1)

                                             {
                                                  
                                               ES=0;
                                               Output=1;          //松开夹具
                                                  TR0=0;             //关闭定时器
                                                timecount=0;       //定时计数清零
                                                flag=1;
                                     
                                             delay(10);
                                             SBUF=rec;
                                                 while(!TI);
                                                  TI=0;
                                                  ES=1;
                                                  }
                                           else  Output=0;         
                                        }
                                        else
                                                {
                                                 state=0;            //清状态标志
                                                 Output=1;
                                                }
                                }
                                else Output=1;
                        }
                        else Output=1;
                }
        }

回复评论 (4)

定时器中断占用CPU资源太多,应该只在定时器服务代码中设置计时标志字,在主代码中计时判断动作,否则定时器中断服务代码影响串口通信.  
点赞  2009-9-15 09:56
我没看你的程序
中断优先级是不是有问题?
点赞  2009-9-17 20:07
问题出在你的init_timer0函数里,每次启动定时器中断后会执行init_timer0中的TMOD=0x01,这样定时器1的模式就不是串口模式下所需模式了,自然串口接收不到数据。应该成 TMOD |= 0x01;
另外在你的串口接收中断函数中,跳入中断时最好把EA关掉,处理完后在将EA置位。
点赞  2009-9-18 10:13
学习了!
点赞  2009-12-14 00:11
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复