用avrM16做連續頻率采集,采集同時輸出500HZ,占空比任意(我用50%)的pwm。我用T1捕獲,端口接ICP1。PB3輸出pwm。現在問題是,我同時開啟T0,T1輸出不是500HZ,而是隨著輸入頻率改變,并且中間我加了ADC程序,輸出頻率也會改變。但是我只開T0,不加捕獲,輸出的一直是500HZ。 #include <iom16v.h> #include <macros.h> #include "delay.h" #define uint unsigned int #define uchar unsigned char #define PWM_0 PORTB&=~(1<<PB3) #define PWM_1 PORTB|=(1<<PB3) signed int wendu,flag,flag1,jd,count,flag4,flag3; signed int yanwu=10; volatile unsigned int CAPi=0,CAPj=0; volatile unsigned intCAP[10]={0,0,0,0,0,0,0,0,0,0}; //TIMER1 initialize - prescale:1 // WGM: 0) Normal, TOP=0xFFFF // desired value: 1mSec // actual value: 1.000mSec (0.0%) void timer0_init(void) { TCCR0 = 0x00; //stop TCNT0 = 0x00; TCNT0 = 0x9c; OCR0 =0xF0; //改變此值可改變占空比 TCCR0 = 0x02; //設置為快速PWM模式,匹配時OC0置1,分頻系數8 } void main(void) { uint dianya; DDRC=0xFF; jd=10; DDRB= 0Xff; PORTB=0XFF; DDRD&=~(1<<PD6); PORTD|=1<<PD6; TCCR1B=(1<<ICNC1)|(1<<ICES1); TCCR1B|=0x03; TIMSK=1<<TICIE1; MCUCR = 0x00; GICR =0x00; timer0_init(); TIMSK = 0x21; //timer interrupt sources SEI(); //re-enable interrupts 等價與SREG=0x80 while(1) { DDRA&=~BIT(0); ADMUX=0x40;//低4位是通道號 參考是AVCC ADCSRA=0x87; //使能ADC,單次轉換,預分頻為128 ADCSRA|=(1<<ADSC); //啟動首次轉換 while(!(ADCSRA&(1<<ADIF))); //等待轉結束循環 ADCSRA|=(1<<ADIF); //清除ADIF位 dianya=ADCL;//先讀 低位 這個必須遵守 度高位后被更新數據 dianya=ADCH*256+dianya; yanwu=dianya*0.09765625; if(yanwu>78) flag1=1; else flag1=0; if((flag==1)&&(flag1==1)) {PORTC=0xff;} else {PORTC=0;} } } #pragma interrupt_handler Timer1_icp_isr:6 void Timer1_icp_isr(void) //6 號中斷 { unsigned char i; if(CAPi==0) {CAPi=ICR1;CAP[0]=ICR1;}//TCCR0 = 0;} else { CAP[1]=ICR1; CAPj=ICR1-CAPi; CAPj=1000000/8/CAPj; if(CAPj>3000) {flag=1;//TIMSK=0x21;timer0_init();SEI(); } else flag=0; TCCR1B&=0xFC;//11000000 TCCR1B|=0x03; TCNT1=0; CAPi=0; CAPj=0; } } #pragma interrupt_handlertimer0_ovf_isr:iv_TIM0_OVF //定時器0中斷 void timer0_ovf_isr(void) { TCNT0 = 0x9c; if(count<jd)//PWM比較 { PWM_1;//高電平轉 } else PWM_0;//低電平停 count++; if(count>20)//周期 count=0; } |