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

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


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

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

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

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

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

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

Аккумуляторы INR21700 от EVE Energy со стандартной и увеличенной емкостью

В Компэл представлены аккумуляторы 21700 с емкостями 4000 мА⋅ч и 5000 мА⋅ч (INR21700-40P и INR21700-50E, соответственно). Аккумуляторы INR21700-50E характеризуются повышенной емкостью и предназначены для  устройств с длительным сроком службы. Для приложений, где требуется экстремальный ток разряда до 30 или 50 А, подойдет аккумулятор INR21700-40P. Аккумуляторы INR21700 предназначены для  электротранспорта, а также для промышленных и бытовых приложений. Подробнее>>

 

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

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

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

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

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

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

Изменено пользователем солар

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

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

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

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

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

Помехоподавляющие пленочные конденсаторы Hongfa для бытовых и промышленных сетей

Компания Hongfa - один из лидеров азиатского рынка пленочных конденсаторов с полным циклом производства. Она выпускает пять серий помехоподавляющих конденсаторов этого типа как для бытовой, так и для трехфазной промышленной сети, а также для автомобильного применения. Продукция компании по ассортименту, параметрам и количеству серий конденсаторов ЭМП не уступает другим крупным производителям этого сегмента и может легко заменить ассортимент ушедших из РФ брендов. Подробнее>>

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

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

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

:blink:

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

шо апять

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

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

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

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

В вашем коде (состояние кнопки по первому событию) использована функция 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", бывает очень нужен.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Так еще и

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

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

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

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

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

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

Вот ваш код

Ashampoo_Snap_2024.05.29_14h22m33s_002_.png

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

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

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

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

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

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

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

Так? 

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

IMG_20240529_153138.jpg

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

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

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

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

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

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

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

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

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

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

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

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

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;} // сбрасываем флаг. 
}


 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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);
		}
	}
	
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
×
  • Создать...