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

 
 
 
Reply to this topicStart new topic
> Внешнее прерывание PCINT по изменению уровня, Определение уровня сигнала
ILNUR
сообщение Jul 16 2010, 07:35
Сообщение #1





Группа: Участник
Сообщений: 13
Регистрация: 21-05-10
Из: Казань
Пользователь №: 57 414



Проблема распознавания уровня сигнала на входе PCINT0.
Надо определить время (по таймеру1) нахождения сигнала на высоком уровне, и выводить значения по USART через определенное время (таймер2).
Почему при прерывании число задних и передних франтов сильно отличается? Это приводит к неверным результатам.
Микроконтроллер ATmega644P
Код программы:

#include <avr/io.h>
#include <avr/interrupt.h>

#define check_num_pin0 (1<<PINA0)
#define check_pinA PINA


unsigned long counterA;
unsigned long T1_0,T2_0;

void USART_Init() // Initializing USART
{
UBRR0 = 0x33;
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 1stop bit */
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}
void USART_Transmit( char data )
{
/* Wait for empty transmit buffer */
while ( !(UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
void TIMER2_Init() // Initializing TIMER2
{
ASSR=(1<<AS2);
OCR2A=0x20;
TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20);
TIMSK2=(1<<OCIE2A);
}
void TIMER1_Init()
{
TCNT1=0;
TCCR1B=(1<<CS12);
}
void Interrupt_Extern()
{
PCICR=(1<<PCIE0);
PCMSK0=(1<<PCINT0);
}
int main()
{
PORTA=(1<<PORTA0);

counterA=0;
T1_0=0;
T2_0=0;

USART_Init();
TIMER2_Init();
Interrupt_Extern();

sei();

while(1);

}

ISR(TIMER2_COMPA_vect)
{
cli();

if (check_num_pin0 & check_pinA)
{
T2_0=TCNT1;
counterA+=(T2_0-T1_0);
}

TCCR2B=(0<<CS22)|(0<<CS21)|(0<<CS20); // выключение таймера2
TCCR1B=0; // выключение таймера1
TCNT1=0;

USART_Transmit(counterA>>16); // вывод данных
USART_Transmit(counterA>>8);
USART_Transmit(counterA);

counterA=0;
T1_0=0;
T2_0=0;

TCNT2=0;
TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20); // Включение таймера2

TIMER1_Init(); // Включение таймера1

PCIFR=0; // Обнуление флагов прерывания PCINT

sei();

}

ISR(PCINT0_vect)
{
cli();
if (check_num_pin0 & check_pinA) // Высокий уровень
{
T1_0=TCNT1;
}
else // Низкий уровень
{
T2_0=TCNT1;
counterA+=(T2_0-T1_0);
}
PCIFR=0;
sei();
}


Go to the top of the page
 
+Quote Post
EugenB2
сообщение Jul 17 2010, 22:15
Сообщение #2





Группа: Участник
Сообщений: 13
Регистрация: 14-01-10
Пользователь №: 54 820



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

ISR(TIMER2_COMPA_vect)
{
cli();

if (check_num_pin0 & check_pinA)
{
T2_0=TCNT1; --------------- так нельзя делать потому как неизвестно сколько же будет пропущено тактов с num_pin0 и на какой момент тогда придется это прерывание таймера
counterA+=(T2_0-T1_0);
}

ISR(PCINT0_vect)
{
cli();
if (check_num_pin0 & check_pinA) // Высокий уровень
{
T1_0=TCNT1;
}
else // Низкий уровень
{
T2_0=TCNT1; ------------- А если счетчик пару раз переполниться пока сигнал в 1 будет? Что тогда посчитается в итоге? Неверно!
counterA+=(T2_0-T1_0);
}
PCIFR=0;
sei();
}
Go to the top of the page
 
+Quote Post
V_G
сообщение Jul 18 2010, 01:19
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Если считаются нажатия кнопки (или контактного датчика), то при дребезге контактов редко когда число положительных и отрицательных перепадов будет совпадать. Здесь четко надо представлять соотношение между ожидаемым временем дребезга и максимальной частотой полезного изменения сигнала, и обязательно учитывать это в алгоритме.
Похожая ситуация может случиться и при отработке медленно меняющегося сигнала, в районе порога переключения могут случиться паразитные перепады туда-сюда. Тогда лучше задействовать компаратор.
Go to the top of the page
 
+Quote Post

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

 


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


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