2015-09-06 3 views
1

Я хочу измерить длительность импульса, но мне нужно измерить 4 сигнала, поэтому я не могу использовать прерывание захвата таймера, поскольку есть только 1 контактный ICP1, обеспечивающий эту опцию (или может?). Поэтому я пытаюсь реализовать что-то вроде arduino pulseIn с той разницей, что я использую таймер (у arduino есть другая реализация, но очень похоже).Измерение ширины импульса

Фактическая проблема в том, что pulseIn не возвращает никаких данных и просто продолжает работать в бесконечном цикле.

Использование ATmega16. Тестирование только на PB2 сейчас.

unsigned long pulseIn() 
{ 
    unsigned long duration = 0; 
    DDRB = 0x00; 

    /* Initiate timer and wait for the end of previous pulse*/ 
    initTime1(); 
    while(getPortBPin(2) == 1); 

    /* Wait for current pulse begin */ 
    while(getPortBPin(2) != 1); 

    /* Time before previous pulse ended */ 
    TCNT1 = 0; 
    overflowCounter = 0; 

    /* Wait for current pulse end */ 
    while(getPortBPin(2) == 1); 

    /* Closk freq is 2 MHz = 1/2 us per tick */ 
    duration = (TCNT1+overflowCounter*65536)/2; 
    overflowCounter = 0; 
    stopTimer1(); 

    return duration; 
} 

void initTime1() 
{ 
    /* Noise filtering */ 
    TCCR1B = (1 << ICNC1); 

    /* Set prescaling factor to 8 */ 
    TCCR1B |= (1 << CS11); 

    /* Enable overflow interruption */ 
    TIMSK = (1 << TOIE1); 

    /* Clear counter */ 
    TCNT1 = 0; 
} 

void stopTimer1() 
{ 
    TCCR1B = 0; 
    TIMSK = 0; 
    TCNT1 = 0; 
} 


uint8_t getPortBPin(uint8_t pin) 
{ 
    if(pin < 0 || pin > 8) 
    { 
     return 0; 
    }  

    return (uint8_t)((PINB >> pin) & 0x01); 
} 

UPDATE

Это моя схема протей. Сигнал поступает от генератора. Частота составляет 1 кГц, а ширина - 50%. Мощность составляет 5 вольт. Proteus scheme

UPDATE

К сожалению, это была глупая ошибка. Он работает нормально. Отладка вещей, которые я не работал, как ожидалось.

ответ

1

Я не могу найти, где проблема в коде. но вот несколько шагов отладки, которые я мог бы выполнить:

1) Какую пишу всегда читали? логика 1 или 0, возможно, импульсное напряжение недостаточно высоко, поэтому AVR не может его ощутить.

2) Умножение в duration = (TCNT1+overflowCounter*65536 - timestamp)/2; занимает много процессорного времени, возможно, потребуется больше времени, чем импульс, поэтому импульс будет низким до того, как AVR войдет в последний цикл while. Конечно, в зависимости от увядания пульс непрерывный или только один импульс. Также я не знаю, почему вы используете timestamp, как вы уже очистили overflowcounter. Я думаю, что эту строку следует удалить.

UPDATE

Для измерения четырех сигналов пульса, я рекомендую использовать прерывание PORTB изменения, когда происходит прерывание, вы можете маскировать порт, чтобы увидеть, какой сигнал изменились, и вычислить его продолжительность.

+0

Спасибо. Вы правы, я должен просто очистить время, чтобы получить новый сигнал. См. Обновления в моем сообщении. –

+0

@LongSmith проверить обновление – Nasr

+0

Да, видел. Я просто не могу найти ничего о том, как изменить значение iterruption (это?) Для atmega16. Найдено регистры PCMSK и PCINT для некоторых mcs. Но ничего для меня. Думайте, что это не поддерживает. –

Смежные вопросы