本帖最后由 ghye 于 2011-5-18 11:59 编辑
我的设计是:T/C1先工作在OVF和CAPT模式捕捉红外信号,捕捉完毕后按键就将T/C1切换到CTC模式发射一次信号(先做没载波的)。
现在调试的问题就是,当T/C1从OVF和CAPT模式切换至CTC模式时,第一次发送信号的第一个波形只有44us宽度。第二次按键再发射信号时,一切都是好的,第三次,第四次。。。。。。以后都是好的。
以下代码是第一次按键的第一个信号有问题的(init()函数是T/C1模式切换时的初始化):
ISR(TIMER1_COMPA_vect)
{
if(PORTC & _BV(IR_OUT_PIN))
{
PORTC &= ~_BV(IR_OUT_PIN);
}
else
{
PORTC |= _BV(IR_OUT_PIN);
}
if(ir_send_cnt <ir_data_cnt && ir_send_cnt < MAX_DATA)
OCR1A = ir_data[ir_send_cnt];
else if(ir_send_cnt >= ir_data_cnt)
{
TCCR1B = 0x00;//发完后停止发送
PORTC &= ~_BV(IR_OUT_PIN);
}
ir_send_cnt++;
}
void init(void)
{
TCCR1B = 0x00;
TIMSK = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
OCR1A = ir_data[0];
TIFR |= _BV(OCF1A);
PORTC &= ~_BV(IR_OUT_PIN);
TCCR1B |= _BV(WGM12) | _BV(CS11);//CTC mode, 时钟沿8分频
TIMSK |= _BV(OCIE1A);
ir_send_cnt = 0;
}
将上面的CTC中断修改时,即使第一次按键发射的信号也是正确的(就是说所有按键时发射的信号都正确):
char g_m=0;
ISR(TIMER1_COMPA_vect)
{
if(g_m==0)
{
g_m=1;
OCR1A=ir_data[ir_send_cnt];
}
else
{
if(PORTC & _BV(IR_OUT_PIN))
{
PORTC &= ~_BV(IR_OUT_PIN);
}
else
{
PORTC |= _BV(IR_OUT_PIN);
}
if(ir_send_cnt <ir_data_cnt && ir_send_cnt < MAX_DATA)
OCR1A = ir_data[ir_send_cnt];
else if(ir_send_cnt >= ir_data_cnt)
{
TCCR1B = 0x00;//发完后停止发送
PORTC &= ~_BV(IR_OUT_PIN);
}
ir_send_cnt++;
}
}
void init(void)
{
g_m = 0;
TCCR1B = 0x00;
TIMSK = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
OCR1A = ir_data[0];
TIFR |= _BV(OCF1A);
PORTC &= ~_BV(IR_OUT_PIN);
TCCR1B |= _BV(WGM12) | _BV(CS11);//CTC mode, 时钟沿8分频
TIMSK |= _BV(OCIE1A);
ir_send_cnt = 0;
}
总结问题:只有当在第一次进入该中断函数里面修改OCR1A的值为所需要的,并且在下次中断才执行所需操作,那么发射的信号才是正确的。
请教我的代码哪里有bugs,请指教。 |