Здраствуйте, форумчане! Возможно кто-то сможет мне помоч, извеняюсь за тавтологию)
Суть: контроллер считает импульсы, приходящие на INT0 пакетами,окончание пакета определяет по TIMER0_OVF_vect, в зависимости от их кол-ва, увеличивает переменную ball (кол-во запусков исполнительного мех-ма) на необходимое значение.
Исполнит мех-м работает до срабатывания концевика INT0, либо до истечения времени TIMER2_OVF_vect.
В Proteus все работает замечательно

В жизне же колдунства какие-то происходят... Прошиваешь, включаешь, все замечательно

По истечению нескольких циклов, перестает реагировать на концевик INT1, ресет не помогает, полежит некот время без работы (питание включено) снова все в порядке и так уже много раз. Причем все работает, импульсы подсчитываются корректно, даже если, вместо интервалов указать строгое равенство, не реагирует только на INT1

Че делать то!?

Знающие люди,

Контроллер Mega8 DIP
|
Код:
|
#define F_CPU 1000000
#include ‹avr/io.h›
#include ‹util/delay.h›
#include ‹avr/interrupt.h›
volatile uint8_t timer0_counter = 0; //счетчик таймера макс длинны импульса
volatile uint8_t imp = 0; //подсчет импульсов
volatile uint8_t ball = 0; //подсчет, необходимого к выдачи, количества мячиков
ISR(INT0_vect){//принимаем импульсы с купброприемника
GICR &= ~(1 ‹‹ INT0); //выключаем прерывания от купюроприемника
_delay_ms(20);
if(!(PIND & (1 ‹‹ 2))){
GICR |= (1 ‹‹ INT0);
return;
}
TCNT0 = 0; //
timer0_counter = 0; //настраиваем таймер длинны импульса
TIMSK |= (1 ‹‹ TOIE0); //и включаем прерываниуе по переполнению таймера0
imp++; //считаем импульс
GICR |= (1 ‹‹ INT0); //включаем прерывания от купюроприемника
}
ISR(TIMER0_OVF_vect){ //таймер длинны импульса
timer0_counter++; //по истечению мы понимаем, что пакет импульсов от купюроприемника
if(timer0_counter › 3){ //принят, и назначаем количество выдаваемых мячиков, увеличивая значение
TIMSK &= ~(1 ‹‹ TOIE0); // буферной переменной ball
if(imp › 3 && imp ‹ 7){
ball++;
imp = 0;
return;
}
else if(imp › 6 && imp ‹ 14){
ball += 2;
imp = 0;
return;
}
else if (imp ›15 && imp ‹ 25){
ball += 4;
imp = 0;
return;
}
else if (imp › 42 && imp ‹ 57){
ball += 10;
imp = 0;
return;
}
imp = 0;
}
}
volatile uint8_t flag = 0; //флаг отключения мотора, по признаку срабатывания концевика INT1 либо исхода макс времени работы мотора
volatile int timer2_counter = 0;//счетчик длительности работы мотора
ISR(INT1_vect){ //концевик выключения мотора
GICR &= ~(1 ‹‹ INT1);
flag = 1;
}
ISR(TIMER2_OVF_vect){ //таймер выключения мотора ~5 секунд
timer2_counter++;
if(timer2_counter › 15){
flag = 2;
TIMSK &= ~(1 ‹‹ TOIE2);
}
}
int main(void)
{
MCUCR = (1 ‹‹ ISC01)|(1 ‹‹ ISC00)|(1 ‹‹ ISC11);
GICR = (1 ‹‹ INT0);
TCCR0 = (1 ‹‹ CS02)|(1 ‹‹ CS00);
TCCR2 = (1 ‹‹ CS22)|(1 ‹‹ CS21)|(1 ‹‹ CS20);
TIMSK = 0;
DDRD = 1;
PORTD = 0;
sei();
while(1)
{
if(ball › 0 && !(PIND &(1‹‹0))){ //включаем мотор
PORTD |= (1 ‹‹ 0);
GICR |= (1 ‹‹ INT1);//включаем прерывание от концевика
timer2_counter = 0;
TCNT2 = 0;
TIMSK |= (1 ‹‹ TOIE2);// настраиваем и включаем таймер длительности работы мотора
flag = 0;
}
if(flag != 0 && (PIND &(1‹‹0))){ //выключаем мотор
PORTD &= ~(1 ‹‹ 0);
GICR &= ~(1 ‹‹ INT1);//выкл прерывание от концевика
TIMSK &= ~(1 ‹‹ TOIE2);//выкл таймер длительности работы мотора
ball--;
}
}
} |