打印
[经验分享]

8051串口中断嵌套如何写

[复制链接]
3898|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ASCLL|  楼主 | 2010-7-16 19:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ASCLL 于 2010-7-16 20:01 编辑

请教各位大虾如何修改本人要做一个电脑上位机遥控器界面,用串口控制51单片机模拟遥控器发送编码给红外接收头,现在程序如下,只见串口中断不见38K中断,请教各位大虾如何修改,谢谢
#include <AT89X51.h>   //12MHZ
bit irflag;
bit uartflag;
unsigned int a;
static bit OP;        //红外发射管的亮灭
static unsigned int count;       //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag;      //红外/串口发送标志
char iraddr1;  //十六位地址的第一个字节
char iraddr2;  //十六位地址的第二个字节
void SendIRdata(char p_irdata);
void delay();
void main(void)
{
      SCON = 0x50;      //REN=1允许串行接受状态,串口工作模式1
     IP|= 0x10;           
    TMOD|= 0x20;      //定时器工作方式2                    
  PCON|= 0x80;                                                         
  TH1 = 0xF3;  // //baud*2  /*  波特率4800、数据位8、停止位1。效验位无 (12M)
     TL1 = 0xF3;         
  TR1  = 1;                                                            
  ES   = 1;        //开串口中断                  
  EA   = 1;        // 开总中断   
   while(irflag)
   {
     irflag = 0;
   delay();
  SendIRdata(a);
   }
      
}
/****************************************************
               串口中断程序
******************************************************/
void ser_int (void) interrupt 4 using 1
{

//EA =0;
   if(RI == 1)        //RI接受中断标志
   {
  RI = 0;      //清除RI接受中断标志
a = SBUF;  //SUBF接受/发送缓冲器
  
   uartflag=1;

}
   if (uartflag)
   {
    SBUF=a;     //SUBF接受/发送缓冲器
    while(TI==0);
         TI=0;   
  irflag=1;      
  uartflag=0;
   }
  
  
EA=1;
   

}

//定时器0中断处理
void timeint(void) interrupt 1
{
  TH0=0xFF;
  TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  count++;
  if (flag==1)
  {
    OP=~OP;
  }
  else
  {
    OP = 0;
  }
  P3_2 = OP;
}

void SendIRdata(char p_irdata)
{
  int i;
  char irdata=p_irdata;
  count = 0;
  flag = 0;
  OP = 0;
  P3_2 = 0;
  EA = 1; //允许CPU中断
  TMOD = 0x01; //TMOD = 0x11; //设定时器0和1为16位模式1
  ET0 = 1; //定时器0中断允许

  TH0 = 0xFF;
  TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次  
  TR0 = 1;//开始计数
  iraddr1=3;
  iraddr2=252;
  //发送9ms的起始码
  endcount=223;
  flag=1;
  count=0;
  do{}while(count<endcount);
  //发送4.5ms的结果码
  endcount=117;
  flag=0;
  count=0;
  do{}while(count<endcount);
  //发送十六位地址的前八位
  irdata=iraddr1;
  for(i=0;i<8;i++)
  {
     //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
    //停止发送红外信号(即编码中的高电平)
     if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
     {
       endcount=41;  //1为宽的高电平
     }
    else
     {
     endcount=15;   //0为窄的高电平
     }
    flag=0;
    count=0;
    do{}while(count<endcount);
    irdata=irdata>>1;
  }
  //发送十六位地址的后八位
  irdata=iraddr2;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
        endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据
  irdata=p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据的反码
  irdata=~p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
     if(irdata-(irdata/2)*2)
     {
         endcount=41;
     }
     else
     {
       endcount=15;
     }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  endcount=10;
  flag=1;
  count=0;
  do{}while(count<endcount);
  flag=0;
// ET0=0;
}
void delay()
{
  int i,j;
  for(i=0;i<400;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}
沙发
jimoxinl| | 2010-7-24 09:35 | 只看该作者
:L顶起,感觉很费劲

使用特权

评论回复
板凳
xiaohuai| | 2010-7-24 09:42 | 只看该作者
bit irflag;
bit uartflag;
是什么用法呢

使用特权

评论回复
地板
tcc8073| | 2010-7-28 12:35 | 只看该作者
定义二个位变量

使用特权

评论回复
5
McuPlayer| | 2010-7-28 18:38 | 只看该作者
这个似乎跟“串口中断嵌套”关系不大

使用特权

评论回复
6
watsoncheung| | 2010-9-3 09:58 | 只看该作者
while(irflag)
   {
     irflag = 0;
   delay();
  SendIRdata(a);
   }
你主程序一直在循环加载启动,还有 irflag一开始没有赋值,运行不知道如何

使用特权

评论回复
7
ASCLL|  楼主 | 2010-9-16 21:33 | 只看该作者
感谢各位大哥的帮助,呵呵很久没时间上来了 ,这个问题已经解决了。
因为没仿真器,后来弄个LED一段段的插入调试终于发现问题了,是定时0中断没有结束。
TO watsoncheung:
while(irflag)
   {
     irflag = 0;
   delay();
  SendIRdata(a);
   }
是因为一直在检测串口有无发送数据过来的,串口优先级,才能模拟遥控把串口数据发送出去。

使用特权

评论回复
8
yao1314520shi| | 2010-9-27 15:59 | 只看该作者
顶起顶起,好几层楼高啊

使用特权

评论回复
9
罗菜鸟| | 2010-9-30 15:52 | 只看该作者
中断里死循环?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

44

帖子

1

粉丝