[AVR单片机] mega128a T/C1模式切换问题

[复制链接]
 楼主| ghye 发表于 2011-5-18 11:56 | 显示全部楼层 |阅读模式
本帖最后由 ghye 于 2011-5-18 11:59 编辑

我的设计是:T/C1先工作在OVF和CAPT模式捕捉红外信号,捕捉完毕后按键就将T/C1切换到CTC模式发射一次信号(先做没载波的)。
现在调试的问题就是,当T/C1从OVF和CAPT模式切换至CTC模式时,第一次发送信号的第一个波形只有44us宽度。第二次按键再发射信号时,一切都是好的,第三次,第四次。。。。。。以后都是好的。

以下代码是第一次按键的第一个信号有问题的(init()函数是T/C1模式切换时的初始化):

  1. ISR(TIMER1_COMPA_vect)
  2. {
  3.                       if(PORTC & _BV(IR_OUT_PIN))
  4.                 {
  5.                           PORTC &= ~_BV(IR_OUT_PIN);
  6.                     }
  7.                 else
  8.                     {
  9.                           PORTC |= _BV(IR_OUT_PIN);
  10.                     }

  11.                     if(ir_send_cnt <ir_data_cnt && ir_send_cnt < MAX_DATA)
  12.                           OCR1A = ir_data[ir_send_cnt];
  13.                     else if(ir_send_cnt >= ir_data_cnt)
  14.                     {
  15.                           TCCR1B = 0x00;//发完后停止发送
  16.                           PORTC &= ~_BV(IR_OUT_PIN);
  17.                     }
  18.                       ir_send_cnt++;
  19. }

  20. void init(void)
  21. {
  22.           TCCR1B = 0x00;
  23.           TIMSK = 0x00;
  24.           TCNT1H = 0x00;
  25.           TCNT1L = 0x00;
  26.           OCR1A = ir_data[0];
  27.           TIFR |= _BV(OCF1A);
  28.           PORTC &= ~_BV(IR_OUT_PIN);

  29.           TCCR1B |= _BV(WGM12) | _BV(CS11);//CTC mode, 时钟沿8分频
  30.           TIMSK |= _BV(OCIE1A);
  31.           ir_send_cnt = 0;
  32. }
将上面的CTC中断修改时,即使第一次按键发射的信号也是正确的(就是说所有按键时发射的信号都正确):

  1. char g_m=0;
  2. ISR(TIMER1_COMPA_vect)
  3. {
  4.           if(g_m==0)
  5.           {
  6.                     g_m=1;
  7.                     OCR1A=ir_data[ir_send_cnt];
  8.           }

  9.           else
  10.           {
  11.                         if(PORTC & _BV(IR_OUT_PIN))
  12.                     {
  13.                                 PORTC &= ~_BV(IR_OUT_PIN);
  14.                         }
  15.                     else
  16.                         {
  17.                                 PORTC |= _BV(IR_OUT_PIN);
  18.      }

  19.                         if(ir_send_cnt <ir_data_cnt && ir_send_cnt < MAX_DATA)
  20.                                 OCR1A = ir_data[ir_send_cnt];
  21.                         else if(ir_send_cnt >= ir_data_cnt)
  22.                         {
  23.                                 TCCR1B = 0x00;//发完后停止发送
  24.          PORTC &= ~_BV(IR_OUT_PIN);
  25.      }
  26.      ir_send_cnt++;
  27.   }
  28. }

  29. void init(void)
  30. {
  31.   g_m = 0;
  32.   TCCR1B = 0x00;
  33.   TIMSK = 0x00;
  34.   TCNT1H = 0x00;
  35.          TCNT1L = 0x00;
  36.          OCR1A = ir_data[0];
  37.          TIFR |= _BV(OCF1A);
  38.          PORTC &= ~_BV(IR_OUT_PIN);

  39.          TCCR1B |= _BV(WGM12) | _BV(CS11);//CTC mode, 时钟沿8分频
  40.          TIMSK |= _BV(OCIE1A);
  41.          ir_send_cnt = 0;
  42. }
总结问题:只有当在第一次进入该中断函数里面修改OCR1A的值为所需要的,并且在下次中断才执行所需操作,那么发射的信号才是正确的。

请教我的代码哪里有bugs,请指教。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

25

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

6

主题

25

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部