реклама на сайте
подробности

 
 
> Несколько прерываний, Как разрулить?
Ruffian
сообщение Mar 30 2011, 12:12
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 4-03-11
Пользователь №: 63 397



Нужно ловить два сигнала от датчиков (для простоты прямоугольные).
Первый сигнал нужно измерить его длительность.
Для второго сигнала просто считать количество (при каждом импульсе инкремент некоей переменной).
Решил повесить эти два сигнала на INT0 и INT1. Но как разрулить - не пойму.
Если по INT0 начинать считать длительность, то для этого нужен ещё и таймер. Значит третье прерывание добавляется. А что будет, если придет прерывание INT1?
В общем каша образовалась.
Может проще сделать вообще без прерываний, тупо в цикле опрашивать порт и смотреть, появились импульсы или нет и реагировать, если они появились?
Что посоветуете?

Сообщение отредактировал Ruffian - Mar 30 2011, 12:13
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AHTOXA
сообщение Mar 30 2011, 12:40
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Ruffian @ Mar 30 2011, 18:12) *
Что посоветуете?

Для измерения длительности сигналов есть специально предназначенные модули захвата (input capture).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ruffian
сообщение Mar 30 2011, 19:41
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 4-03-11
Пользователь №: 63 397



Цитата(AHTOXA @ Mar 30 2011, 16:40) *
Для измерения длительности сигналов есть специально предназначенные модули захвата (input capture).


Нашёл пример, перевел его с AVRStudio на mikroc. Работать отказывается. Весь вечер просидел с ним.
Думаю, может ошибся когда переводил, взял оригинальный код и собрал в AVRStudio.

Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>

// Input: Square wave on ICP PIN
// This program determines the pulse width of a square wave and represents that pulse width
//in a certain form in port D

double overflow_counter, rising_edge, falling_edge, pulse_width;
double TOP = 65535;

//This interrupt service routine calculates the pulse width of a square wave on the ICP pin
//and displays that in a certain form on PORT D

ISR(TIMER1_CAPT_vect){
    
    if (PORTA == 0xAA) PORTA = 0x55;
    else PORTA == 0xAA;

    // If ICP pin is set, there was a rising edge else if its low there must have been a falling edge /
    if (bit_is_set(PINB,1)){
        rising_edge = ICR1;
        TCCR1B &= ~(1<<ICES1); //Capture now on falling edge
        overflow_counter = 0;
    }
    else{
        falling_edge = ICR1;
        TCCR1B |= (1<<ICES1);//Capture now on rising edge
        pulse_width =falling_edge - rising_edge + TOP*overflow_counter;

        //Test to see if correct pulse width being calculated
        //if pulse width is greater than 35 than PD2 goes high otherwise PD3 IS HIGH
        if (pulse_width>35){
            PORTD |= (1<<PD2);
            PORTD &= ~(1<<PD3);
        }
        else{
            PORTD |= (1<<PD3);
            PORTD &= ~(1<<PD2);
        }
    }
}


ISR(TIMER1_OVF_vect){
    overflow_counter++; //increment counter when overflow occurs
}


int main(void){

    DDRB = 0;// ICP pin as input which is pin 0 on port B/

    DDRD = 0XFF; // ALL PINS on port D are set as output.

    DDRA = 0xFF;
    PORTA = 0xAA;


    sei();//enable global interrupt

    //setting up Timer control register 1

    //TOP VALUE IS 0XFFFF; (NORMAL MODE)
    TCCR1A = 0;
    TCCR1B = 0;


    //SETS PRESCALER ON 1
    TCCR1B |= (1<<CS10);
    TCCR1B &= ~(1<<CS11) & ~(1<<CS12);

    // Enable Input noise canceller and capture time on rising edge
    TCCR1B |= (1<<ICES1) | (1<<ICNC1);

    TIMSK = 0;
    TIMSK |= (1<<TICIE1); //Enable Input Capture Interrupt
    TIMSK |= (1<<TOIE1); //Enable timer overflow interrupt

    while(1){}

}



Проект настроен на 8 МГц, Атмега16. В оригинале примера сигнал читался с PB0, хотя для Timer1 должен быть вход PB1. PB0 это для Timer0. Пробовал и так и так. В конечном счёте тупо взял и запараллелил оба входа, чтобы не гадать.

Счётчик работает, прерывание TIMER1_OVF_vect срабатывает исправно, а прерывание TIMER1_CAPT_vect срабатывает только один раз, когда запускается main. И больше не вызывается. Независимо от состояния порта В.
В чём прикол - не могу понять blink.gif


Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 20:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01372 секунд с 7
ELECTRONIX ©2004-2016