Здраствуйте, уважаемые форумчане!
Написал программку, все работает, но немного не так как надо
Суть: считаем импульсы на входе, в зависимости от их кол-ва приводим в действие исполнительный механизм (моторчик и концевик, сигнализирующий о необходимости выключения моторчика). Новые импульсы могут прийти во время работы мотора, потому создал переменную для хранения кол-ва циклов включения мех-ма "ball". На случай поломки концевика(INT1), каждый цикл включения мотора ограничен по времени (TIMER2_OVF_vect). Входящие импульсы принимаем на INT0, в случае окончания пакета импульсов не будет в течении пол секунды, считаем (TIMER1_OVF_vect). Все работает, НО при опыте, вместо 10 необходимых срабатываний концевичка, хватает 8..9 иногда 10 для завершения работы, т.е. Должны выдать 10 мячиков, выдаем 8. Я только учусь, поэтому буду благодарен каждому тычку носом в проблемные места
Код:
#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 > 4 && imp < 6){
ball++;
imp = 0;
return;
}
else if(imp > 9 && imp < 11){
ball += 2;
imp = 0;
return;
}
else if (imp >19 && imp < 21){
ball += 4;
imp = 0;
return;
}
else if (imp > 49 && imp < 51){
ball += 10;
imp = 0;
return;
}
}
}
volatile uint8_t flag = 0; //флаг отключения мотора, по признаку срабатывания концевика INT1 либо исхода макс времени работы мотора
volatile int timer2_counter = 0;//счетчик длительности работы мотора
ISR(INT1_vect){ //концевик выключения мотора
GICR &= ~(1 << INT1);
flag = 1;
_delay_ms(300);
}
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--;
//flag = 0;
}
}
}
И схемка [img][url=http://img.radiokot.ru/files/119676/medium/17bk7b5cc1.jpg][/img]