Jump to content

Видеокурс по AVR-микроконтроллерам для начинающих


 Share

Recommended Posts

2 часа назад, sashka сказал:

шаг за шагом проверить программу

Нижняя строка меню, кнопки справа от зелёной стрелки - вроде бы оно.

Link to comment
Share on other sites

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

Ребят ,подскажите пожалуйста, как дребезг контактов победить кроме как функцией delay_ms. Кнопка без фиксации, если  использовать "делей" задержку, то при нажатой и удержанной кнопке ,светодиод начинает мигать ,а нужно чтобы нажал-светодиод загорелся и не тух до следующего нажатия.

Опыта пока нет ,начал изучать пока базовый синтаксис.

Безымянный.png

Link to comment
Share on other sites

Важные нюансы подбора литиевых ХИТ для разработчиков

В многообразии литиевых батареек и аккумуляторов нет какого-то универсального или идеального варианта. Выбирая тот или иной вариант для питания устройства, разработчику приходится оперировать множеством параметров, используя наиболее оптимальное их сочетание для каждого приложения. Разберем параметры для различных приложений. Подробнее>>

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

Posted (edited)

В этой программе алгоритм не тот, что нужен. Составь сначала алгоритм, а не копипасть программу. (делэй здесь совершенно ни при чём.)

Я пользуюсь таким алгритмом:

Button= 1;
while(1)
{
_delay_ms(10);
oldButton= Button; // предыдущее состояние кнопки
Button= PINB & 0x01; // текущее состояние кнопки

if(oldButton && !Button) PORTC^= 0x0C; // если предыдущее было "1" и текущее равно "0"
}

Ясен пень в реале он организован на таймере(примечание для зануд).

Edited by солар

Я не раздаю удочки. Я продаю рыбу.

Link to comment
Share on other sites

Литиевые батарейки и аккумуляторы от мирового лидера EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. EVE является поставщиком аккумуляторных элементов круглого формата для электрических моделей автомобилей.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

Posted (edited)
1 час назад, солар сказал:

Ясен пень в реале он организован на таймере

:blink:

1 час назад, IMXO сказал:

шо апять

Нет, я походу до дребезга контактов еще не дорос...

Что то сложновато пока:(

Edited by sashka
Link to comment
Share on other sites

Posted (edited)

Да чё том доростать. Есть событие (изменение состояния порта). После которого идёт череда изменений этого события (дребезг). Все что нужно - после первого события сделать паузу проверить ещё раз и тогда принять решение. Методов реализации много.

В вашем коде (состояние кнопки по первому событию) использована функция xor (^) которая инвертирует состояние порта пока нажата кнопка. Измените алгоритм (используйте вторую часть ветвления (else)) и все будет хорошо.

0 xor 0 = 0

1 xor 0 = 1

0 xor 1 = 1

1 xor 1 = 0

--------------

0 or 0 = 0

1 or 0 = 1

0 or 1 = 1

1 or 1 = 1

-------------

0 and 0 = 0

1 and 0 = 0

0 and 1 = 0

1 and 1 = 1

---------------

Ну и не забываем о "not", бывает очень нужен.

Edited by korsaj
Link to comment
Share on other sites

Posted (edited)
47 минут назад, korsaj сказал:

Измените алгоритм (используйте вторую часть ветвления (else))

Я только научился регистры выставлять на вход или выход, и порты назначать в 1 или в 0. Синтаксис только начал изучать)

Так что понятия не имею пока, что и как нужно правильно изменить.

Edited by sashka
Link to comment
Share on other sites

Да все верно, нот это инверсия (лог операция "не").

У вас в строка PORTC ^= ((1<<2) | (1<<3)) выполняет инверсию (меняет на противоположное) состояния выводов порта.

Т.е. если выводы 2 и 3 были равны 1, то после выполнения этой строки выводы будут иметь 0, если были равны 0, то станут 1.

Чтобы установить биты нужно выполнить такое PORTC |= ((1<<2) | (1<<3)), а чтобы сбросить биты: PORTC &= ~((1<<2) | (1<<3))

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

Link to comment
Share on other sites

11 минут назад, korsaj сказал:

Чтобы установить биты нужно выполнить такое PORTC |= ((1<<2) | (1<<3)), а чтобы сбросить биты: PORTC &= ~((1<<2) | (1<<3))

С этим вроде немного разобрался ,спасибо

Сейчас 12 урок смотрю про таймеры.

Link to comment
Share on other sites

Posted (edited)

Вы доделайте переключение светодиода по кнопке, потом таймерами займётесь.

Edited by korsaj
Link to comment
Share on other sites

Posted (edited)
12 минут назад, sashka сказал:

вроде

Плохое состояние.

Edited by солар

Я не раздаю удочки. Я продаю рыбу.

Link to comment
Share on other sites

Posted (edited)
2 часа назад, korsaj сказал:

Вы доделайте переключение светодиода по кнопке

Так я хотел бы но не могу понять как ,знаний мало пока.

Мне насоветовали примеры в которых я разобраться не могу.

Вот человек скинул примерIMG_20240529_150847.jpg.876ee6110aa74dac8e279ed4d90a9aa1.jpg

Баттон , понятно это кнопка. Ее нужно сначала как то инициализировать? Чем int-ом или #define?

Old button что такое? Не понятно.. 

Так еще и

5 часов назад, солар сказал:

организован на таймере(примечание для зануд).

Мне вот не понятно ,как это на таймере делается.

Человек под ником IMXO ,ссылку дал там вообще темный лес, для опытных только.

Edited by sashka
Link to comment
Share on other sites

Posted (edited)

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

Вот ваш код

Ashampoo_Snap_2024.05.29_14h22m33s_002_.png

Проверяете состояние пина 0 порта В и если он 0 (нажата кнопка) вы что делаете? А если она не нажата, что нужно сделать?

Edited by korsaj
Link to comment
Share on other sites

13 минут назад, korsaj сказал:

Проверяете состояние пина 0 порта В и если он 0 (нажата кнопка) вы что делаете?

Если нажата, то то порт С (2,3) присваивают 1.

Else ,вот что туда присвоить? Если кнопка отпущена if (PINB & (1<<0)) ,то светодиод продолжает гореть? 

PORTC |= (1<<2) | (1<<3); и потом небольшую задержку _delay_ms(100);

Так? 

Как по проще сделать без таких длинных кодов

IMG_20240529_153138.jpg

Link to comment
Share on other sites

Posted (edited)
8 минут назад, sashka сказал:

Если нажата, то то порт С (2,3) присваивают 1.

Да, но у вас в коде нет этого (см. моё сообщение выше).

8 минут назад, sashka сказал:

Else ,вот что туда присвоить? Если кнопка отпущена if (PINB & (1<<0)) ,то светодиод продолжает гореть? 

Потому как его нужно там погасить, а вы этого не делаете.

Задержка нужно только при нажатии кнопки. И задержки хватит в 50 мС. 

8 минут назад, sashka сказал:

Как по проще сделать без таких длинных кодов

До этого ещё дойдете. Вам пока не нужно разбираться в структурах.

Edited by korsaj
Link to comment
Share on other sites

6 минут назад, sashka сказал:

там вообще темный лес, для опытных только.

Нет там никакого темного леса, все просто.
Вот смотри, есть кнопка BUTTTON , у нее есть два состояния:
1.  "нажата"  Pressed
2. "отпущена" Released
(Так как "отпущена" противоположно "нажата", то для работы Released не используется)
и два события:
1. "только что нажали" JustPressed
2. "только что отпустили" JustReleased
Чтобы определить события "только что нажали/отпустили" нужно знать "предыдущие состояние"  OldPressed
Ну и нужен счетчик чтобы подавить дребезг контактов Jitter.
То есть для обработки кнопки нужно пять переменных (один счетчик размером байт (8бит) и четыре флага размером 1 бит).
Так как в Си нет переменой размером 1 бит, для экономии памяти мы создаем переменную нового типа в виде  битового поля(структуры)

Спойлер
typedef struct
{
    unsigned char   Jitter       :8;      // 
    unsigned char   Pressed      :1;      // 
    unsigned char   OldPressed   :1;      // 
    unsigned char   JustPressed  :1;      // 
    unsigned char   JustReleased :1;      // 
    unsigned char   :4;
} TBUTTONS;
volatile TBUTTONS   m_button1;

 

Опрос кнопки , подавление дребезга и установку флагов событий и состояния кнопки делаем ввиде отдельной функции

Спойлер
 void Task_Button1 (void)
{
    // подавление дребезга при опросе кнопки 
	m_button1.Jitter<<=1;
	if(!(PINB & 0x01)) {m_button1.Jitter++;} // опрос кнопки
	
	if(m_button1.Jitter==0xFF) {m_button1.Pressed=1;} // подавление дребезга при нажатии кнопки 
	if(m_button1.Jitter==0x00) {m_button1.Pressed=0;} // подавление дребезга при отпускании кнопки 
	// проверка событий
    if(m_button1.Pressed && !m_button1.OldPressed) {m_button1.JustPressed=1;} // флаг кнопка только что нажата
    if(!m_button1.Pressed && m_button1.OldPressed) {m_button1.JustReleased=1;} // флаг кнопка только что отпущена       
    m_button1.OldPressed = m_button1.Pressed; // сохраняем текущее соотояние для следующего опроса
}
	

 

В главном цикле

Спойлер
while(1)
{
 _delay_ms(1);
  Task_Button1 ();
  if(m_button1.JustPressed) //  кнопка только что нажата?
    { PORTC^= 0x0C;         // чтото делаем 
      m_button1.JustPressed=0;} // сбрасываем флаг. 
}

 

 

1 час назад, sashka сказал:

Мне вот не понятно ,как это на таймере делается.

_delay_ms(1) меняется на проверку флага который устанавливается в прерывании по таймеру

FLAG=0;
while(1)
{
 while(FLAG==0) continue;
 FLAG=0;
  Task_Button1 ();
  if(m_button1.JustPressed) //  кнопка только что нажата?
    { PORTC^= 0x0C;         // чтото делаем 
      m_button1.JustPressed=0;} // сбрасываем флаг. 
}


 

Link to comment
Share on other sites

Во флоукоде я дребезг контактов делал таким образомIMG_20240529_165925.jpg.7e351c9afd0afed72f942ce85e559005.jpg

Цикл активен ДО того как кнопка не будет отпущена. Там это работало. 

Как такой алгоритм сделать в С? Пробовал через do{.     }While() но не получилось что то

Link to comment
Share on other sites

Posted (edited)

Забудьте о флоукод и ответьте на моё сообщение.

35 минут назад, IMXO сказал:

для обработки кнопки нужно пять переменных

Для логики со счётчиком достаточно 1 байта (реально можно и меньше): каждый цикл опроса кнопки в нулевой бит  записываем состояние кнопки и делаем сдвиг влево. Как только в байте все биты будут одинаковы - дребезг все.

Тоже можно организовать на инкременте счётчика. 

Но все это лишнее, достаточно задержки на время дребезга.

Edited by korsaj
Link to comment
Share on other sites

25 минут назад, IMXO сказал:

Нет там никакого темного леса

Вы профи в этом ,поэтому вам все легко и просто кажется. И занимаетесь наверное этим ни первый год.

А я месяц как заинтересовался микроконтроллерами только)

Ничего 2 -3 года может поднаберусь опыта, если будет что то получатся ,иначе интерес может пропасть 

Link to comment
Share on other sites

40 минут назад, korsaj сказал:

Забудьте о флоукод и ответьте на моё сообщение.

Отвечу чуть позже ,на работе сейчас

Link to comment
Share on other sites

2 часа назад, korsaj сказал:

ответьте на моё сообщение

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

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
int k=0;	
	
int main (void)
{   
	DDRC = 0xff;
	PORTC = 0b0001100;
	DDRB = 0b0000000;
	PORTB = 0b0000001;
	
	 while (1)
    {
		if (~PINB & (1<<0 && k==0))
		{
			PORTC^= ((1<<2) | (1<<3));
			k=1;
		} 
		else
		{
			if (~PINB & (1<<0) && k==1)
			{
			} 
			else
			{
				k=0;
			}
			_delay_ms(100);
		}
	}
	
}

Нужно то было всего лишь одну переменную добавить.

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

Почему у меня скопированный код не как у всех? Весь как попало разбросан по экрану

Вроде правильно же все сделал ,скопировал с атмел студио и вставил в сообщение для кода<>.

Link to comment
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   1 member


×
×
  • Create New...