измерение частоты генерируемой волны с использованием ICU - Atmega32 - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь использовать модуль ввода ввода ATMega32 следующим образом:

У меня есть волна, сгенерированная с использованием TIMER0 (через вывод OC0) (XTAL = 8 МГц, прескалер = 1024, CT C режим, OCR0 = 244, что дает ~ 32 Гц). Затем я пытаюсь захватить эту волну, используя TIMER1 (через вывод ICP) (XTAL = 8 МГц, prescaler = 1024, нормальный режим, в результате ~ 7812,5 Гц)

Фрагмент кода предоставляет более подробную информацию.

Проблема в том, что у меня есть только результат 0.

**

MODIFIED.

** спасибо много @clifford, согласно приведенному ниже коду, он работает, но:

1 - есть небольшая ошибка (результаты не точны).

2-, когда я изменяю свое уравнение

с

        count=(capture2+(captOVf*65536))-capture1;

           to   
   count=capture2-capture1; 

Я вижу мусор на ЖК-дисплее.

очень жаль, что форматирование плохого вопроса.

typedef enum{
    CAPTURE1,
    CAPTURE2,
    WAIT
}timer_states_t;

volatile timer_states_t flag= WAIT;
volatile u8 x,y,captOVf,TOVfs=0;
volatile u16 capture1,capture2;

void setup_pins(){

    SET_BIT(DDRB,3); //SET OC0 pin as output
    CLEAR_BIT(DDRD,6); //set ICP pin as input
    SET_BIT(PORTD,6);  //set ICP pin pullup resistance

}

//Timer0 Configurations / wave generator .
void timer0_init(){
    OCR0=244;
    TCCR0=0x1D; //ctc , 1024 , toggle OC0 pin on compare match ;
}

//Timer1 Configurations / capturer .
void timer1_init(){
    TCCR1A=0x00; // Timer1 , normal mode, no on compare output ,
    TCCR1B=0x45; // prescaler 1024, Input capture edge as rising .
    SET_BIT(TIMSK,TICIE1); // enable input capture interrupt .
    SET_BIT(TIMSK,TOIE1); //enable timer1 overflow interrupt .
    CLEAR_BIT(ACSR,ACIC);  //disable Analog comparator .
    SET_BIT(SREG,7); //GLOOBAL ITERRUPT

}

ISR(TIMER1_OVF_vect){
    TOVfs++;

}

ISR(TIMER1_CAPT_vect){
    switch(flag){
    case CAPTURE1:
        //capture1=ICR1;
        x=ICR1L;
        y=ICR1H;
        capture1=x | (y<<8);
        TOVfs=0;
        flag=CAPTURE2;
        break;

    case CAPTURE2:
        //capture2=ICR1;
        x=ICR1L;
        y=ICR1H;
        capture2=x | (y<<8);
        flag=WAIT;
        captOVf=TOVfs;
        break;
    }
}
int main(){

setup_pins();
timer0_init();
timer1_init();
LCD_init();

unsigned long count  ;
u8* countString ;

while(1){
    flag=CAPTURE1;

    while(flag != WAIT);

        count=(capture2+(captOVf*65536))-capture1;
        itoa(count,countString,10);
        LCD_send_string("count:");
        LCD_send_string(countString);
        _delay_ms(500);
        LCD_send_cmd(lcd_Clear);

    }
}

1 Ответ

0 голосов
/ 05 апреля 2020

Ничто никогда не изменяет capture1 или capture2, которые сами по себе унифицированы.

capture1 = x | (y<<8);
...
capture2 = x | (y<<8);

возможно? temp1 и temp2 кажутся бесполезными; будучи установленным в ISR и не упоминаемым в других местах.

Учитывая, что счетчик TIMER2 будет около 244 для одного цикла 32 Гц, является ли счетчик переполнения ненужным? Просто сбросьте счетчик TIMER1 в CAPTURE1 и получите счет в CAPTURE2, удалив арифметику c и одну из capture переменных.

Все общие переменные должны быть объявлены volatile, все не общие переменные не должны быть глобальными.

...