AtMega8 Шаговый двигатель, прерывания

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

Сообщение Azizbek »

Здравствуйте. Собрал схему по этой статье http://radioparty.ru/prog-avr/program-c ... -stepmotor. Немного изменил программу, так как мне нужно было что б после нажатия кнопки шаговый двигатель остановился сделав определенное количество оборотов или иную сторону. Вроде всё работает, но есть не большая проблема, после того как я нажал кнопку №1 (или №2) я не могу прервать движение двигателя до тех пор пока он не отработает все количество оборотов заданной программой. то есть если в проге задано 100 оборотов. а мне нужно на 50 том обороте остановить и запустить обратный ход, то я этого не могу сделать пока не будут пройдены все 100 оборотов. В программировании мк я новичок. помогите пожалуйста...
Спойлер

Код: Выделить всё

// Подключение биполярного шагового двигателя к AVR
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> 


void cw_dir(){ //направление по часовой

      PORTB=0b00000011; //+a +b 
      _delay_ms(1000); 
      PORTB=0b00000110; //+b -a
      _delay_ms(1000);
      PORTB=0b00001100; //-a -b
      _delay_ms(1000);
      PORTB=0b00001001; //-b +a
      _delay_ms(1000);     
    }

void ccw_dir(){ //направление против часовой

      PORTB=0b00001001; //+a +b 
      _delay_ms(1000); 
      PORTB=0b00001100; //+b -a
      _delay_ms(1000);
      PORTB=0b00000110; //-a -b
      _delay_ms(1000);
      PORTB=0b00000011; //-b +a
      _delay_ms(1000);     
    

}
volatile unsigned char step_index;
volatile unsigned int ovftimes;
volatile unsigned char status;
volatile unsigned int var=0;
volatile unsigned int var2=0;
// Прерывание по переполнению Т0
ISR(TIMER0_OVF_vect)
{
static unsigned int count = 1;
count++;
if(count >= ovftimes) // Применяем задержку
{
cli(); // Запрещаем прерывания

if(status){ // если status == 1 крутим по часовой
while(var<=100)
	{
		ccw_dir();
		var++;
		
	}; var2=0;
}
else      
{ // если status == 0 крутим против часовой
while(var2<=100)
	{
		cw_dir();
		var2++;
	}; var=0;
}

if (step_index >= 4)
step_index=0;

count = 0; // Сброс счетчика
TCNT0 = 0; // Старт счетчика с нуля
sei(); // Глобально разрешаем прерывания
}
}

int main(void)
{
DDRB = 0b00001111; // PB0, PB1, PB2, PB3 - выходы
PORTB = 0x00; // Лог. нули на выходе
PORTD = 0xFF;
DDRD = 0x00;

ADCSRA = (1 << ADEN) // разрешение АЦП
      | (1 << ADPS2) // предделитель на 64 (частота АЦП 125kHz)
	  | (1 << ADPS1);
ADMUX = 0x00; // ADC0 - вход, внешний ИОН 5 Вольт

TCCR0 |= (1 << CS01); // Предделитель на 8
TCNT0 = 0; // Старт счетчика с нуля

step_index = 0;
ovftimes = 10; // первоначальная задержка

sei(); // Глобально разрешаем прерывания

while(1) 
{
ADCSRA |= (1 << ADSC); // Начинаем преобразование
while (ADCSRA & (1 << ADSC)); // Ждем пока завершится преобразование
ovftimes = ADCW; // Значение временной задержки

if((PIND &(1 << PD2)) == 0)
{
TIMSK |= (1 << TOIE0); // Разрешаем прерывания от таймера
status = 1;
}
else 
{
//TIMSK &= ~(1 << TOIE0); // Запрещаем прерывания от таймера
}

if((PIND &(1 << PD3)) == 0)
{
TIMSK |= (1 << TOIE0); // Разрешаем прерывания от таймера
status = 0;
}
else 
{
//TIMSK &= ~(1 << TOIE0); // Запрещаем прерывания от таймера
}
}
}
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Уберите из обработчика прерывания запрещение/разрешения прерывания. Оно будет запрещено автоматически, а разрешение прерывания в обработчике грозит опасностью ввалится опять в обработчик не успев выйти из него.

Если не менять сильно структуру программы, то наверно самое простое и в обработчике прерывания контролировать нажатость кнопки и если что прервать цикл вращения.

Делать что-то длительное в обработчике прерывания, в большинстве случаев, неудачное решение.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Не буду исправлять программу, сам подумай куда и чего добавить.
Решается просто: при нажатии кнопки счетчик оборотов "волевым решением" устанавливается в значение >=100. После возврата из прерывания в цикл счетчика оборотов этот значение счетчика будет отвечать условию остановки(реверса).
В статье вообще странное решение простейшей задачи, мягко говоря.
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб мар 07, 2015 05:49:57

Сообщение Azizbek »

Z_h_e писал(а):Уберите из обработчика прерывания запрещение/разрешения прерывания...
Убрал, но не помогло.
Спойлер

Код: Выделить всё

// Прерывание по переполнению Т0
ISR(TIMER0_OVF_vect)
{
	static unsigned int count = 1;
	count++;
	if(count >= ovftimes) // Применяем задержку
		{
		 //cli(); // Запрещаем прерывания

		if(status)
		 { // если status == 1 крутим по часовой
		 while(var<=10)
		  {
			ccw_dir();
			var++;
		  }; var2=0;
	  }
	else      
     { // если status == 0 крутим против часовой
	 while(var2<=10)
	   {
		cw_dir();
		var2++;
	   }; var=0;
     }

	if (step_index >= 4) step_index=0;

		count = 0; // Сброс счетчика
		TCNT0 = 0; // Старт счетчика с нуля
		//sei(); // Глобально разрешаем прерывания
	}
}
Добавлено after 1 minute 33 seconds:
vem566 писал(а):...при нажатии кнопки счетчик оборотов "волевым решением" устанавливается в значение >=100...
Не совсем понял мысль... я только учусь.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Azizbek писал(а):Убрал, но не помогло.
Я же объяснил для чего нужно убрать.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Двигатель крутится пока счетчик не станет равным 100. И плевать на прерывания и все остальное. Чтобы остановить двигатель нужно при нажатии кнопки установить счетчик в значение 100 (переменные var или var2). Остальное произойдет само. Но учиться по таким алгоритмам - только отбить охоту. Простейшая задача, а уже куча сообщений.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Не получится так, если не менять структуру программы. Нажатие кнопки проверяется в основном теле программы, движок вращает прерывание. Пока прерывание не закончит вращать движок, кнопки не проверяются.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Z_h_e, я не вдавался. Просто мельком глянул - через жопу. Ну и подробно разбираться стало резко неохота.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Ваше сексуальное прошлое и будущее меня не интересует. Предположу что остальных форумчан также.
Так же кроме половых предподчений, абсолютно не имеет смысла писать, что Вы пост не читали и помогать не собираетесь, это можно отнести ко всему населению страны, кроме некоторых. Какой длины будет форум, если все напишут "не знаю"?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 4751
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Сексуальные предпочтения, это происки модераторов. Вот за такие замены текста их самих во все дыры. Причем круглые сутки.
Ответить

Вернуться в «AVR»