Перейти к содержанию

как подружить ATtiny 2313 и биполярный шаговый двигатель?


Рекомендуемые сообщения

Так чтоб без долгих дискусий начну с сути влпроса.

Есть у меня биполярный шаговик, тот что с 4-мя выводами, и есть тинька 2313, но не могу их подружить, точнее не могу правильно написать программу. Управление вращением работает правильно, но я не могу подключить туда кнопку. Т.Е. мне нужно чтоб при нажатии кнопки движок начинал крутиться и крутиться он должен до следующего нажатия этой же кнопки. Перебрал уже кучу вариантов, но ничто не работает, или включает но не выключает. Подскажите в какую сторону рыть...


#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
int main(void)
{
	DDRB|=(1<<0);
	DDRB|=(1<<1); //Настройка портов
	DDRB|=(1<<2);
	DDRB|=(1<<3);

	PORTD|=(1<<0);     //раскомментируйте, если лень вешать резисторы подтяжки на кнопки
	PORTB&=~(1<<1);
	PORTB&=~(1<<2);   //В регистрах портов, после включения, всегда нули.  Эти три строчки бесполезны.
	PORTB&=~(1<<3);
	PORTB&=~(1<<4);
	
		while(1)
	    {
		_delay_ms(50); //задержка t
		PORTB=0b00000001;
		_delay_ms(50); //задержка t
		PORTB=0b00000011;
		_delay_ms(50); //задержка t
		PORTB=0b00000010;
		_delay_ms(50); //задержка t
		PORTB=0b00000110;
		_delay_ms(50); //задержка t
		PORTB=0b00000100;
		_delay_ms(50); //задержка t
		PORTB=0b00001100;
		_delay_ms(50); //задержка t
		PORTB=0b00001001;
		}
		if (PORTD==1) ;
		 else {
			PORTB=0b00000000;
		}
	}

 

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Вывод значений в порт лучше сделать через массив чтобы на одной итерации мотор поворачивался на шаг, а не на оборот. Это позволяет куда проще регулировать скорость вращения.

PROGMEM const char mot_arr[] = {0b00001010, 0b00001001, 0b00000101, 0b00000110}; //полушаг не всегда лучше, поэтому для простоты оставим шаг

//переход к следующему шагу. Аргумент : направление (+1, 0, -1) другие значения не рекомендуются, но к ошибке не приведут
void mot_step(int8_t dir){
  static uint8_t pos = 0;
  pos += dir;
  pos &= 3; //поскольку в массива всего 4 элемента, достаточно обрезать по маске чтобы корректно обработать переполнение
  PORTB = (PORTB & 0b11110000) | pgm_read_byte( &mot_arr[pos] );
}

Что у вас за шаговик не знаю, а для шаговика от CD-привода (2 изолированные обмотки, 4 вывода) ваша последовательность сигналов неверна.

Цитата

if (PORTD==1) ;

А вот это расшифруйте подробнее:

- что мешало проверять обратное условие (PORTD != 1)?

- почему проверяется PORTD вместо PIND (напряжение, которое контроллер пытается выдать на пин вместо измеренного)?

- гарантируется ли нулевое значение на неиспользуемых пинах PORTD?

Такое ощущение что вы не знаете как работать с кнопками и даже как отлаживать программу. Разберитесь сначала с этим.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

@COKPOWEHEU Вы совершенно правы, я еще ничего, грубо говоря, не умею, а только учусь. Двигатель от принтера старенького. Спасибо, что указали на ошибки, буду пробовать. По итогу отпишусь

@optima Это уже прочитано мною было раньше! Спасибо.

Ссылка на комментарий
Поделиться на другие сайты

15 часов назад, Lihey.german сказал:

if (PORTD==1) ; else { PORTB=0b00000000; }

и смысл ?  как это выполнится ? (else ставится без точки с запятой )

да и проводить проверку порта ? всего порта ? Если по простому - PORTD это регистр выхода каков смысл сравнения его с единицей ?  

Самое главное куда подключена кнопка ? 

чего уж проще то

bit trigger;      // объявляем переменную для запоминания состояния

в основной программе

if(PIND.X==1)         // если кнопка нажата

{trigger=!trigger;};  // меняем состояние переменной

if(trigger){        ;} // в скобках код на вращение // здесь зайдет при trigger=1

else{           ; }; // в скобках код на стоп или реверс// здесь зайдет при trigger=0

 

Ну и инициализацию  порта D на вход без подтягивающих резисторов не забыть.

PORTD=0x00;
DDRD=0x00;

Но это все только    для примера годиться, а если правильно подходить, то нужно делать защиту от дребезга, вместо delay использовать прерывания по таймеру ... будет желание разберешься...

 

 

Изменено пользователем E_C_C
Ссылка на комментарий
Поделиться на другие сайты

15 часов назад, E_C_C сказал:

bit trigger;

Ошибка: в Си нет типа "bit"

15 часов назад, E_C_C сказал:

if(PIND.X==1)

Ошибка: в Си не поддерживается обращение к отдельным битам числа как к полям структуры

15 часов назад, E_C_C сказал:

и смысл ?  как это выполнится ? (else ставится без точки с запятой )

при выполнении условия выполняется пустой оператор так что синтаксически все верно.

В 15.03.2017 в 18:27, Lihey.german сказал:

Ничего не изменилось

А что вы изменили?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, COKPOWEHEU сказал:

в Си нет типа "bit"

8 часов назад, COKPOWEHEU сказал:

в Си не поддерживается обращение к отдельным битам числа как к полям структуры

CodeVision работает с такими отступлениями от стандарта.

Ссылка на комментарий
Поделиться на другие сайты

Знаю. Но я написал "Си" а не "cvavr", да и ТС использует avr-gcc.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

11 час назад, COKPOWEHEU сказал:

при выполнении условия выполняется пустой оператор так что синтаксически все верно.

Синтаксически верно, иначе компилятор не пропустил бы , но логически то  бессмысленно.

 

11 час назад, COKPOWEHEU сказал:

Ошибка: в Си нет типа "bit"

Зависит от компилятора, если CodeVision поддерживает , то почему не воспользоваться. Так же и с портом, я не сильно вникал в синтаксис avr-gcc , при желании ТС разберется, если захочет, но от него никаких сообщений нет , что воздух то сотрясать.  Думаю человек мало мальский начавший вникать в программирование поймет смысл  if(PIND.2)  или  if (PIND & (1<<<2))  или  if(PIND & 0х02) .

 

 

 

Изменено пользователем E_C_C
Ссылка на комментарий
Поделиться на другие сайты

Попробуй проверять не PORTD == 1, а так PIND.(тут номер пина куда прицеплена кнопка) ==1. И вроде должно быть так if (PIND.0 == 1) { }; else {PORTB=0b00000000 }; Если например кнопка висит на пине 0 порта D.  Точка с запятой в конце оператора if() делает его пустым оператором или я могу конечно ошибаться, я сам еще только учусь)

Изменено пользователем elki
Ссылка на комментарий
Поделиться на другие сайты

7 часов назад, E_C_C сказал:

Синтаксически верно, иначе компилятор не пропустил бы , но логически то  бессмысленно.

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

7 часов назад, E_C_C сказал:

Зависит от компилятора, если CodeVision поддерживает , то почему не воспользоваться.

Потому что при переходе на другие компиляторы полезут ошибки. Пользоваться компиляторо-специфичной экзотикой стоит как можно реже - только если это существенно упрощает код.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Извините пожалуйста, что не отвечал,думал что больше эта тема не интересна. В общем учу программирование ооочень недолго, много читаю, плохо понимаю и запоминаю, но стараюсь.

Работаю в AtmelStudio, proteus и железе. Некоторые термины мне не ясны. Например объявление переменной, массив и т.д., по-этому я решил изучать это на практике сразу, т.е., у меня есть двигатель и им управлять хочу от контроллера. Програмку накидал, но она не верна... вот. Теперь буду следовать вашим советам, правда читать еще больше придеться)))

11 час назад, elki сказал:

И еще вроде как у тебя программа крутится в бесконечном цикле while(1){} Она и не может пойти дальше что бы проверить следующее условие if().

И как выйти из этого положения?

Ссылка на комментарий
Поделиться на другие сайты

Так, насколько я понял мне нужно сделать следующее:

Проверить PORTD0,

Проверить PORTB,

Если кнопка нажата и на выходе порта B нули, то запускаем двигатель.

Если кнопка нажата и на выходе не нули- останавливаем двигатель... Примерно так? 

Ссылка на комментарий
Поделиться на другие сайты

15.03.2017 в 16:06, Lihey.german сказал:

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

для решения задачи нужно самую малость: осознать что работа двигателя и опрос кнопки это два абсолютно разных , параллельных процесса, но есть проблема : контролер не может выполнять параллельно процессы/задачи , но может очень быстро переключатся с выполнения одной задачи на другую или перебирать задачи

первое что делаем: определяем как часто будем перебирать задачи , для этого используют таймеры и прерывания, но для вашей задачи и понимания достаточно и обычной задержки

главный цикл примет вид

Скрытый текст

while(1)
	    {
		_delay_ms(50); //задержка t
         // задача1
         // задача2
         // задача3
         // и тд.
        }

 

задача 1 опрос кнопки:

Скрытый текст

if (PIND & (1<<<2)) {BUTTON=1} else {BUTTON=0} ;

 

задача 2 фиксация нажатия кнопки, переключаем вид работы

Скрытый текст

    if ((BUTTON_OLD==0)&&(BUTTON==1)  POWER^=1; 
        BUTTON_OLD=BUTTON;

 

задача 3 включаем или выключаем двигатель

Скрытый текст

  if (  POWER == 1) 
      { step++;
        step&=0b00000111; считаем шаги от 0 до 7
        switch (step)
         {
          case 0: 
            PORTB=0b00000001;     
          break;
          case 1:
            PORTB=0b00000101;
          break;
          case 2:
            PORTB=0b00000100;
          break;
          case 3: 
            PORTB=0b00000110;     
          break;
          case 4:
            PORTB=0b00000010;
          break;
          case 5:
            PORTB=0b00001010;
          break;
          case 6: 
            PORTB=0b00001000;     
          break;
          case 7:
            PORTB=0b00001001;
          break;
          default:
            PORTB=0b00000000;
        }
      }
       else
      {
        PORTB=0b00000000;
      }
       

 

          

Ссылка на комментарий
Поделиться на другие сайты

стер - переменная

батон, батон_олд и пауэр - флаги ,

в данном случае для упрощения это переменные типа unsigned char

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

руководство по Си поможет в понимании

http://forum.cxem.net/index.php?/topic/169847-как-не-надо-писать-код-с-для-atmega/&do=findComment&comment=2521970

ЗЫ исправил задачу2

 

Ссылка на комментарий
Поделиться на другие сайты


#define  F_CPU 4000000
#include <avr/io.h>
#include <util/delay.h>


int main (void)
unsigned char BUTTON;
unsigned char step;
unsigned char POWER;
unsigned char BUTTON_OLD;

while(1)
{	
_delay_ms(50);
if(PIND0& (1<<2)){BUTTON==1} 
  else {BUTTON==0};	
if ((BUTTON_OLD==0)&&(BUTTON==1))
  else{POWER^=1};
 
 BUTTON_OLD=BUTTON;	
	
}

Если я правильно понял, то первые две задачи должны быть так

Ссылка на комментарий
Поделиться на другие сайты

В общем я туплю, опять. @IMXO сложил Ваш код докучи, вот что вышло:

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
int main(void)
{
	
	DDRB|=(1<<0);
	DDRB|=(1<<1); //Настройка портов
	DDRB|=(1<<2);
	DDRB|=(1<<3);
unsigned char BUTTON;
unsigned char step;
unsigned char POWER;
unsigned char BUTTON_OLD;

while(1)
{
	_delay_ms(100);
	if (PIND & (1<<2)) 
	{BUTTON=1;} 
		else {BUTTON=0;} ;
		if ((BUTTON_OLD==0)&&(BUTTON==1)) 
		 POWER^=1;
		BUTTON_OLD=BUTTON;
		
		if ( POWER == 1)
		{ step++;
			step&=0b00001111; 
			switch (step)
			{
				case 0:
				PORTB=0b00000001;
				break;
				case 1:
				PORTB=0b00000101;
				break;
				case 2:
				PORTB=0b00000100;
				break;
				case 3:
				PORTB=0b00000110;
				break;
				case 4:
				PORTB=0b00000010;
				break;
				case 5:
				PORTB=0b00001010;
				break;
				case 6:
				PORTB=0b00001000;
				break;
				case 7:
				PORTB=0b00001001;
				break;
				default:
				PORTB=0b00000000;
			}
		}
		else
		{
			PORTB=0b00000000;
		}
		
	}
}

Компилятор кричит  Warning        'BUTTON_OLD' may be used uninitialized in this function [-Wmaybe-uninitialized]  ,

Хотя в протеусе работает... Интересно. Теперь буду разбирать код по кусочкам и изучать каждую составляющую... 

Ссылка на комментарий
Поделиться на другие сайты

Можете инициализировать

unsigned char BUTTON_OLD = 0;

Это не ошибка а предупреждение - вдруг вы забыли указать переменной что в ней будет при включении. Если этого не сделать, там может оказаться все что угодно. В данном случае это не особо помешает.

На счет вывода значений для мотора, массив все-таки удобнее и быстрее. Собственно, процедура, которую я уже приводил, вполне соответствует "задаче" IMXO.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Lihey.german сказал:

Компилятор кричит  Warning        'BUTTON_OLD' may be used uninitialized in this function [-Wmaybe-uninitialized]  ,

вынесете определение и инициализацию переменных перед функцией мейн

и настройка портов :

DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<3);
1 час назад, COKPOWEHEU сказал:

На счет вывода значений для мотора, массив все-таки удобнее и быстрее.

да вы правы , но в данном случае кася наглядней и проще для понимания.

 

Ссылка на комментарий
Поделиться на другие сайты

Так, в принципе мне всё ясно по коду, есть только пара вопросов:

собственно что делают именно эти две строки

step++;

step&=0b00001111;

первая просто к переменной step прибавляет один, а вторая... Или они обе являются счетчиком и считают до... но зачем они, ведь есть строчка switch (step) которая сама переключает состояние на выходе.

И другой вопрос:

Можно ли вместо одной общей delay  использовать раздельные, потому, как после прохождения одного цикла вращения двигателя образуется заметная пауза, во время которой как раз и идет опрос кнопок.

Ссылка на комментарий
Поделиться на другие сайты

step++; // увеличивает на единицу переменную step, т.е. она должна была бы изменяться с 0 до 255, потом снова 0 и т.д.
step &=0b00001111; // выделяет только 4 младших бита (старшие 4 сбрасывает в 0), т.е. значение будет меняться с 0 до 15. И полученное значение присваивается обратно переменной step (step = step & 0b00001111)

можно сделать так
step++;
switch (step & 0b00001111)
таким образом переменная step будет постоянно увеличиваться с 0 до 255, а для условия switch накладывать маску 0b00001111 (такой вариант может больше понравиться компилятору, для оптимизации)
 

31 минуту назад, Lihey.german сказал:

Можно ли вместо одной общей delay  использовать раздельные, потому, как после прохождения одного цикла вращения двигателя образуется заметная пауза, во время которой как раз и идет опрос кнопок.

Пауза образуется из-за количества шагов у вас их 8, а в условие switch формально 16, остальные 8 работают здесь
default:
PORTB=0b00000000;

Может вы хотели всего восемь шагов, тогда маска будет 0b00000111
step++;
switch (step & 0b00000111)

Ссылка на комментарий
Поделиться на другие сайты

5 минут назад, dm37 сказал:

 

step++; // увеличивает на единицу переменную step, т.е. она должна была бы изменяться с 0 до 255, потом снова 0 и т.д.
step &=0b00001111; // выделяет только 4 младших бита (старшие 4 сбрасывает в 0), т.е. значение будет меняться с 0 до 15. И полученное значение присваивается обратно переменной step (step = step & 0b00001111)

 

И зачем?

ааа, я по-ходу понял,

step++; // увеличивает на единицу переменную step, т.е. она должна была бы изменяться с 0 до 255, потом снова 0 и т.д.
step &=0b00001111; // выделяет только 4 младших бита (старшие 4 сбрасывает в 0), т.е. значение будет меняться с 0 до 15. И полученное значение присваивается обратно переменной step (step = step & 0b00001111), а switch (step) уже указывает верхним двум строкам что должно быть при этих шагах...

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • @Gomerchik а вы контролировали как меняется уровень сигнала на А1 ардуины?
    • Спасибо за совет. Автором данного проекта я не являюсь, мне нужно было воссоздать уличный датчик для метеостанции взамен пропавшего(( Из разного найденного в интернете этот проект работает с моей станцией Орегон (спасибо автору). В понедельник попробую последовать Вашему совету. Но все равно куча непоняток  как блин это работает)) Если дело в неправильной отправки команды, то как на это влияет подключение датчика температуры? Если совсем не подключать таймер, то передача идет один раз (как и прописано в программе), станция принимает и отображает, но минут через сколько-то естественно станция уже ни чего не показывает, но с таймером питание полностью не пропадает с ардуинки, но передача сигнала каким-то образом работает по таймеру.  В моем понимании данная команда подается один раз потому, что таймер должен отключать питание МК после передачи сигнала и каждые 43 сек снова подавать питание (так того требует станция).  Ардуино передает показания температуры отключается полностью и 43 секунды мк не работает.  Сейчас у меня питание пока сделано на подпитке от солнечной батареи, но пару пасмурных дней и аккумулятор съедается до отключения(
    • thickman Так и сделаю. Вытащу из бу БП.  Буду знать, как отличить. Благодарю. Заменил транзисторы на IRFB20N50K. Картина стала, совсем другой.  Похоже трудность не в драйвере, на момент подвозбуда, переходные процессы, в нем, завершены. Увеличил затворные резисторы до 50ом, стало немного лучше.  Не понятно, почему верхний ключ греется несколько сильнее. Возможно, стоит посмотреть ток в коллекторе.  Снабберные емкости временно удалил, изменений не произошло.  Замена ТГР на другой, на кольце MSTN-16A-TH, так же, результата не принесла.   irfb20n50k.pdf
    • А что нить из ассортимента активных щупов производства СССР..))
    • Типа такого: https://aliexpress.ru/item/2044864227.html?sku_id=58855020183
    • поняли неправильно. У ТЛ494 никакой защиты нет, усилители ошибки не защита, они не должны приводить к ложным импульсам. Причем тут "микруха" ?  надо нагружать ВСЁ. До сих пор вообще непонятно о каком ИИП идет речь и сколько у него каналов. Бесполезно схему рисовать? - Помогать так бесполезно. Картина кривая по самое "немогу" продолжаются картинки, снятые через ногу и без цены деления.
×
×
  • Создать...