打印

PIC程序里遇到的一个问题,RCIE关了之后,不能可靠的打开。

[复制链接]
2247|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Helloafer|  楼主 | 2012-3-24 11:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
方法大概是这样。
main
{
    if(recv_ready_flag)
     {
           recv_ready_flag=0;
          //代码
         ……
        //代码
       RCIE=1;
     }
}
中断里
ISR()
{
   if(RCIE&&RCIF)
  {
      //代码
      ……
     //代码
    recv_ready_flag=1;
   RCIE=0;  //在这里关了之后,程序运行一段时间后,这里会打不开。打不开也是我的猜测,因为我把RCIE注释掉之后,程序就运行正常了。
  }
}

下面是一部分实际源码,太多了,就不全弄上来了。需要说明的是,在DS18B20的函数里,转换温度和读取温度里有有先关GIE再开GIE的代码。或者是这里的问题,但我想不出来是为什么。希望各位大虾帮住看看。我做的这个东西,总的来说就是上位机每秒读取单片机转换来的温度。还可以控制一个灯的亮灭。




void main(void)
{
com_init();
time0_init();
port_init();
while(1)
{
  //every time
  
  if(recv_ready_flag)
  {
  
   recv_ready_flag=0;
   switch(recv_data[2])
   {
    case LIGHT:   //开关灯
     RC4=!RC4;
     if(RC4) send_value(LIGHT,'o','0');//返回灯的状态,此处为开
     else  send_value(LIGHT,'c','0');////返回灯的状态,此处为关
     break;
    case TEMP://读取温度
     convert_data();
     send_value('t',temp_dataed[0],temp_dataed[1]);
     break;
    case '1':
   
     break;
    case '2':
     break;
    default:
     break;
   }
   RCIE=1;
  }
  //every_10ms
  if(flag_10ms)
  {
   flag_10ms=0;
  }
  //every_1000ms
  if(flag_1000ms)
  {
   
   flag_temp=!flag_temp;
   flag_1000ms=0;
   if(flag_temp)
   {
    convert_temp();//这里面有GIE=0;GIE=1;
   RA2=1;
   }
   else
   {
   RA2=0;
   get_temp(temp_undata,temp_undata+1);//这里面有GIE=0;GIE=1;

   }
  }
}
}

void interrupt isr()
{
if(RCIE&&RCIF)
{
  
  recv_data[recv_cnt]=RCREG;
  RA2=!RA2;
  //SEND();
  //TXREG=0x30+recv_cnt;
  //while(!TRMT);
  //RECV();
  if(recv_cnt==0)
  {
   if(recv_data[0]==':') recv_cnt++;
  }
  else if(recv_cnt==1)
  {
   if(recv_data[1]=='1') recv_cnt++;
   else recv_cnt=0;
  }
  else if(recv_cnt==5)
  {   
   //RA2=!RA2;
   recv_cnt=0;
   if(recv_data[5]==(recv_data[2]|recv_data[3]|recv_data[4]))
   {
    recv_ready_flag=1;
    //RCIE=0;
   }
  }
  else if(recv_cnt>5)
  {
   recv_cnt=0;
  }
  else
  {
   recv_cnt++;
  }
}
if(T0IE&&T0IF)
{
  TMR0=216;
  T0IF=0;
  flag_10ms=1;
  if(cnt_10ms++>100)
  {
   cnt_10ms=0;
   flag_1000ms=1;
  }
}
}
沙发
Ryanhsiung| | 2012-3-24 11:48 | 只看该作者
不一定是没找开,也可能是溢出了

使用特权

评论回复
板凳
Helloafer|  楼主 | 2012-3-24 11:56 | 只看该作者
溢出之后,程序还能正常运行吗?我在里面弄了个引脚变化控制LED来显示程序是否运行,这个LED是隔一秒变化一次的。

使用特权

评论回复
地板
yewuyi| | 2012-3-24 13:09 | 只看该作者
简直是废话,RCIE被置为0之后,recv_ready_flag永远也不可能再被置为1,此时if(recv_ready_flag){}怎么可能还会执行到{}里面的内容 ?

使用特权

评论回复
5
Helloafer|  楼主 | 2012-3-24 14:14 | 只看该作者
4# yewuyi
晕死,谁会犯这样低级的错误,recv_ready_falg后面跟着是RCIE被置0。之后肯定会进入if(recv_ready_falg) 的程序内部这里面才会把recv_ready_flag置0,并且把RCIE全能。我的程序是可能运行的,只是不可靠而已。

使用特权

评论回复
6
yewuyi| | 2012-3-24 14:35 | 只看该作者
你老是去操作GIE干啥?

你闲的没事老是去捣鼓GIE,RCIE这些标志干啥?

就那么点动作,直接初始化后GIE=1;RCIE=1,然后再也不要操作它了,设个计数器,想计时多少,就去读一下计数器就好了,瞎折腾啥啊?

使用特权

评论回复
7
tingletingle| | 2012-7-5 13:07 | 只看该作者
1.RCIE是进入RC中断的必要条件,无需在ISR()里判断,这个判断是多余的。
2.主程序里的if里面的内容是否执行依赖于ISR里的if里的内容,而ISR里的if里的内容是否执行依赖于主程序里的if里面的内容,这是一个循环套,举个例子,如果RCIE关闭的时候,recv_ready_flag恰巧被赋0那会发生啥事情?

使用特权

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

本版积分规则

0

主题

3

帖子

0

粉丝