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

MEGA8 опрос кнопок по таймеру


tifaso

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

Потому что таймер это отдельно взятая часть МК, которая "тикает" абсолютно отдельно от главного кода, независимо от других функций. А задержка это часть главного кода. Пока МК считает время задержки больше НИКАКОЙ код в этот момент работать не будет. Код в микроконтроллере исполняется линейно - от верха до низу по твоему листингу. Это значит что пока все твои задержки не отработают цикл, то код не перейдет в начало где идет проверка нажата ли кнопка. А цикл с твоими задержками работает 2,4 секунды. Это значит чтобы программа могла поймать нажатие кнопки тебе придется нажимать кнопку дольше чем 2,4 секунды. После того как ты подержишь кнопку дольше , то заданная тобой переменная измениться, но измениться она на несколько рандомных значений, а не на 1 увеличение, в следствии чего у тебя она сразу станет максимально возможной. Далее код снова продолжится. 

В скомпилированном мною файлике я немножко подредактировал программу оставив все твои подключения и алгоритм на месте. Оно должно чуть лучше работать чем исходник. 

Но в идеале нужно делать по другому. Совсем по другому. Или выкинуть кнопки, или перевести все на таймер.

"Мы все учились понемногу, чему-нибудь и как-нибудь...")

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

@Beliy_voron Это гирлянда, а там без задержек никак или как ещё заставить светодиоды мигать да ещё в нужных мне алгоритмах? С таймерами это будет сделать полный гемор.

И как уже для себя решил всё сводится к тому что мне стоит вместо кнопок установить галетный переключатель и проверять каждый его вывод как обычную кнопку и тогда всё встанет на своё место. Остаётся только найти его в магазине.

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

29.11.2020 в 12:13, IMXO сказал:

бредо генератором

Здесь веселее - https://www.cyberforum.ru/dump/thread2281005.html

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

галетный переключатель

и убрать микроконтроллер. Именно он источник гемора.

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

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

#define F_CPU 1000000UL



#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

// ===================================================================================

void ButtonsProcess(void);

void Effect_1(void);
void Effect_2(void);
void Effect_3(void);
void Effect_4(void);

// ===================================================================================

volatile uint8_t menu     = 1;
volatile uint8_t menu_new = 1;

// ===================================================================================

ISR(TIMER1_OVF_vect) 
{
  ButtonsProcess();
}

// ===================================================================================

int main(void)
{
    DDRB  = 0b11111100;
    DDRC  = 0b01111111;
    DDRD  = 0b11111111;
    PORTB = 0b00000000;
    PORTC = 0b00000000;
    PORTD = 0b00000000;
    
    TIMSK |= (1<<2);
    TCCR1B = 0b00000001;
    TCNT1  = 54613;

    sei();
    
    while(1)
    {
        // menu (effect) changed - reset 
        if (menu_new != menu)
        {
          menu = menu_new;
          PORTD = 0b00000000;
        }
        // select menu (effect)
        if (menu==1)
        {
          Effect_1();
        }
        else
        if (menu==2)
        {
          Effect_2();
        }
        else
        if (menu==3)
        {
            Effect_3();
        } 
        else
        if (menu==4)
        {
            Effect_4();
        }
    }
}

// ===================================================================================

#define BUTTON_1_MASK (0b00000001)
#define BUTTON_2_MASK (0b00000010)

void ButtonsProcess(void)
{
  static uint8_t oldButtons = 0;

  // get buttons state
  uint8_t newButtons = ~(PINB & (BUTTON_1_MASK|BUTTON_2_MASK));

  // check buttons state change
  uint8_t pressedButtons = 0;
  if (oldButtons != newButtons)
  {
    if (((oldButtons & BUTTON_1_MASK) == 0) && (newButtons & BUTTON_1_MASK)) pressedButtons |= BUTTON_1_MASK;
    if (((oldButtons & BUTTON_2_MASK) == 0) && (newButtons & BUTTON_2_MASK)) pressedButtons |= BUTTON_2_MASK;
    oldButtons = newButtons;
  }

  // handle pressed buttons
  if (pressedButtons & BUTTON_1_MASK) 
  {
    if (menu_new > 1) menu_new--;
  }
  if (pressedButtons & BUTTON_2_MASK) 
  {
    if (menu_new < 4) menu_new++;
  }
}

// ===================================================================================

void Effect_1(void)
{
    PORTD |= (1<<0);
    PORTD &= ~((1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<1);
    PORTD &= ~((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<2);
    PORTD &= ~((1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<3);
    PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<4);
    PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<5)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<5);
    PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<6));
    _delay_ms(300);
    PORTD |= (1<<6);
    PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5));
    _delay_ms(300);
}

void Effect_2(void)
{
    PORTD |= (1<<0);
    _delay_ms(300);
    PORTD |= (1<<1);
    _delay_ms(300);
    PORTD |= (1<<2);
    _delay_ms(300);
    PORTD |= (1<<3);
    _delay_ms(300);
    PORTD |= (1<<4);
    _delay_ms(300);
    PORTD |= (1<<5);
    _delay_ms(300);
    PORTD |= (1<<6);
    _delay_ms(300);
    PORTD &= ~(1<<0);
    _delay_ms(300);
    PORTD &= ~(1<<1);
    _delay_ms(300);
    PORTD &= ~(1<<2);
    _delay_ms(300);
    PORTD &= ~(1<<3);
    _delay_ms(300);
    PORTD &= ~(1<<4);
    _delay_ms(300);
    PORTD &= ~(1<<5);
    _delay_ms(300);
    PORTD &= ~(1<<6);
    _delay_ms(300);
}

void Effect_3(void)
{
    PORTD |= ((1<<0)|(1<<6));
    _delay_ms(300);
    PORTD |= ((1<<1)|(1<<5));
    _delay_ms(300);
    PORTD |= ((1<<2)|(1<<4));
    _delay_ms(300);
    PORTD |= (1<<3);
    _delay_ms(300);
    PORTD &= ~((1<<0)|(1<<6));
    _delay_ms(300);
    PORTD &= ~((1<<1)|(1<<5));
    _delay_ms(300);
    PORTD &= ~((1<<2)|(1<<4));
    _delay_ms(300);
    PORTD &= ~(1<<3);
    _delay_ms(300);
}

void Effect_4(void)
{
    PORTD |= ((1<<0)|(1<<6));
    _delay_ms(300);
    PORTD |= ((1<<2)|(1<<4));
    _delay_ms(300);
    PORTD &= ~((1<<0)|(1<<6));
    _delay_ms(300);
    PORTD &= ~((1<<2)|(1<<4));
    _delay_ms(300);
    PORTD |= ((1<<1)|(1<<5));
    _delay_ms(300);
    PORTD |= (1<<3);
    _delay_ms(300);
    PORTD &= ~((1<<1)|(1<<5));
    _delay_ms(300);
    PORTD &= ~(1<<3);
    _delay_ms(300);
}

 

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

@Алексей Еремеев Спасибо. Понятно впринцепи не так уж это и сложно. Завтра попробую повторить думаю это решит мою проблему. Тут мне становится ясно как делить программу на блоки что кстати иногда очень удобно.

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

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

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

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

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

@Алексей Еремеев Спасибо большое за этот код, но всё таки саму проблему это так и не решило. всё тоже самое.

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void buttons(void);
void led_pos_1(void);
void led_pos_2(void);
void led_pos_3(void);
void led_pos_4(void);
void led_pos_5(void);
void led_pos_6(void);
void led_pos_7(void);
void led_pos_8(void);
void led_pos_9(void);
void led_pos_10(void);
void led_pos_11(void);

volatile uint8_t menu=3;
volatile uint8_t menu_new=3;

ISR(TIMER1_OVF_vect)
{
    buttons();
}

int main(void)
{
	DDRB = 0b11111100;
	DDRC = 0b1111111;
	DDRD = 0b11111111;
	PORTB = 0b00000000;
	PORTC = 0b0000000;
	PORTD = 0b00000000;
	
	TIMSK |= (1<<2);
	TCCR1B = 0b00000001;
	TCNT1 = 54613;
	sei();
	
	while(1)
	{
		if (menu_new != menu)
		{
			menu = menu_new;
			PORTB &= ~((1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7));
			PORTC &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4));
			PORTD = 0b00000000;
		}
		
		if (menu==1)
		{
			led_pos_1();
		}
		else
		if (menu==2)
		{
			led_pos_2();
		}
		else
		if (menu==3)
		{
			led_pos_3();
		}
		else
		if (menu==4)
		{
			led_pos_4();
		}
		else
		if (menu==5)
		{
			led_pos_5();
		}
		else
		if (menu==6)
		{
			led_pos_6();
		}
		else
		if (menu==7)
		{
			led_pos_7();
		}
		else
		if (menu==8)
		{
			led_pos_8();
		}
		else
		if (menu==9)
		{
			led_pos_9();
		}
		else
		if (menu==10)
		{
			led_pos_10();
		}
		else
		if (menu==11)
		{
			led_pos_11();
		}
	}
}
#define BUTTON_1_MASK (0b00000001)
#define BUTTON_2_MASK (0b00000010)
void buttons(void)
{
	static uint8_t old_buttons=0;
	uint8_t new_buttons= ~(PINB & (BUTTON_1_MASK|BUTTON_2_MASK));
	uint8_t press_buttons=0;
	if (old_buttons != new_buttons)
	{
		if (((old_buttons & BUTTON_1_MASK)==0) && (new_buttons & BUTTON_1_MASK))
		{
			press_buttons |= BUTTON_1_MASK;
		}
		if (((old_buttons & BUTTON_2_MASK)==0) && (new_buttons & BUTTON_2_MASK))
		{
			press_buttons |= BUTTON_2_MASK;
		}
		old_buttons = new_buttons;
	}
	if (press_buttons & BUTTON_1_MASK)
	{
		if (menu_new>1)
		{
			menu_new--;
		}
	}
	if (press_buttons & BUTTON_2_MASK)
	{
		if (menu_new<11)
		{
			menu_new++;
		}
	}
}
void led_pos_1(void)
{
	PORTB |= (1<<2);
	
	PORTD |= (1<<0);
	PORTD &= ~((1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<1);
	PORTD &= ~((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<2);
	PORTD &= ~((1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<3);
	PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<4);
	PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<5)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<5);
	PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<6));
	_delay_ms(300);
	PORTD |= (1<<6);
	PORTD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5));
	_delay_ms(300);
}
void led_pos_2(void)
{
	PORTB |= (1<<3);
	
	PORTD |= (1<<0);
	_delay_ms(300);
	PORTD |= (1<<1);
	_delay_ms(300);
	PORTD |= (1<<2);
	_delay_ms(300);
	PORTD |= (1<<3);
	_delay_ms(300);
	PORTD |= (1<<4);
	_delay_ms(300);
	PORTD |= (1<<5);
	_delay_ms(300);
	PORTD |= (1<<6);
	_delay_ms(300);
	PORTD &= ~(1<<0);
	_delay_ms(300);
	PORTD &= ~(1<<1);
	_delay_ms(300);
	PORTD &= ~(1<<2);
	_delay_ms(300);
	PORTD &= ~(1<<3);
	_delay_ms(300);
	PORTD &= ~(1<<4);
	_delay_ms(300);
	PORTD &= ~(1<<5);
	_delay_ms(300);
	PORTD &= ~(1<<6);
}
void led_pos_3(void)
{
	PORTB |= (1<<4);
	
	PORTD |= ((1<<0)|(1<<6));
	_delay_ms(300);
	PORTD |= ((1<<1)|(1<<5));
	_delay_ms(300);
	PORTD |= ((1<<2)|(1<<4));
	_delay_ms(300);
	PORTD |= (1<<3);
	_delay_ms(300);
	PORTD &= ~((1<<0)|(1<<6));
	_delay_ms(300);
	PORTD &= ~((1<<1)|(1<<5));
	_delay_ms(300);
	PORTD &= ~((1<<2)|(1<<4));
	_delay_ms(300);
	PORTD &= ~(1<<3);
	_delay_ms(300);
}
void led_pos_4(void)
{
	PORTB |= (1<<5);
	
	PORTD |= ((1<<0)|(1<<6));
	_delay_ms(300);
	PORTD |= ((1<<2)|(1<<4));
	_delay_ms(300);
	PORTD &= ~((1<<0)|(1<<6));
	_delay_ms(300);
	PORTD &= ~((1<<2)|(1<<4));
	_delay_ms(300);
	PORTD |= ((1<<1)|(1<<5));
	_delay_ms(300);
	PORTD |= (1<<3);
	_delay_ms(300);
	PORTD &= ~((1<<1)|(1<<5));
	_delay_ms(300);
	PORTD &= ~(1<<3);
}
void led_pos_5(void)
{
	PORTB |= (1<<6);
}
void led_pos_6(void)
{
	PORTB |= (1<<7);
}
void led_pos_7(void)
{
	PORTC |= (1<<0);
}
void led_pos_8(void)
{
	PORTC |= (1<<1);
}
void led_pos_9(void)
{
	PORTC |= (1<<2);
}
void led_pos_10(void)
{
	PORTC |= (1<<3);
}
void led_pos_11(void)
{
	PORTC |= (1<<4);
}

Вот получившийся код на этот момент.

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

Проверил ещё раз всю схему дорожки на платах светодиоды индикации и сами кнопки всё так как и должно быть, но не переключает. А что делать даже и не знаю сейчас.

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

покажи схему и опиши логику - подумаем

мой код симулировал в протеусе, 7 светодиодов на порту D 0..6 и две кнопки на B 0 и 1, кнопки на массу, пины подтянуты резисторами 10К на питание

работает - эффекты переключает (в момент окончания цикла эффекта)

 

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

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

А что делать даже и не знаю сейчас

Вы же не слушаете, когда вам советуют. Что вы от нас еще хотите?

 

1 час назад, Алексей Еремеев сказал:

 в момент окончания цикла эффекта

Вот как раз из за задержек это и происходит. И не важно где они, в главном цикле или в подпрограмме.

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

1 час назад, Алексей Еремеев сказал:

кстати, в протеусе и ваш код как-то работает

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

Любую непосильную задачу можно решить , если ее разбить на множество мелких, но на которые по отдельности хватает сил . Как этому научить -  х.з. .

 

Может  как-то проще  запрограммировать переключение по принципу зависимой фиксации, как в планках П2К ?

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

Flowcode v8 - "тема". Может для профессионального использования не "канает", но для "бытовых" задач самое то. Зато на много проще и понятней, и прощает много ошибок. При этом никто не запрещает параллельно изучать "человеческое" программирование. Я уже 2 полноценных устройства собрал, которые год в полевых условиях работают, причём относительно сложных, хотя в программировании я лох. День на изучение программы (среды разработки), два на написание самой программы. Зато результат достигнут и уже можно пользоваться.

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

Вот в общем начертил схему своей гирлянды:

1059290498_3.JPG.890d8f5ca371cf8f098a856fe8e00c2b.JPG

На схеме оставил несколько примечаний чтобы понять что и для чего.

Ну а теперь опишу алгоритм программы и как оно всё должно работать. При запуске выбирается первый пункт меню и зажигается LED1 в индикации и включается первый режим работы гирлянды. Далее при переключении кнопками пункта меню в ту или иную сторону задаётся номер пункта меню включается соответствующий светодиод индикации и включается выбранный режим работы гирлянды. 

Вот как то так всё это и должно быть.

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

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

31 минуту назад, tifaso сказал:

режим работы гирлянды

Так тут ещё и разные режимы работы есть.  То есть должны быть. Может вам попробовать на логике собрать? Типа 155ТМ2. Я в детстве собирал, даже в  кружке автоматики какое то призовое место занял.

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

@andrusha152 Так в том то и вся проблема что не выходит сделать переключение между режимами. остальное то всё работает. А таких микросхем у меня всё равно нет и ближайшее время приобретать ничего не собираюсь.

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

 

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

переключений меню не происходит.

1) проверка цепи кнопок - есть ли +5 на пинах 14 и 15 при отпущенных кнопках? сопротивление между пином и питанием 10К?   - проверка подтягивающих резисторов и открытых кнопок

2) падает ли до нуля на одном пине при нажатии соответствующей кнопки и не падает на втором? - проверка взаимопересечений

 

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

@Алексей Еремеев Проверка по данным сопротивлениям показала что как ни странно резисторы хоть и промаркированы были на 10 ком, но по замеру показывали всего 5 ком. Заменил все три. Ещё был найден коротыш между 14 и 15 выводом микросхемы и тут причина крылась в самих кнопках пришлось заменить и их за одним и плату поправил.  После сделаных поправок всё заработало так как и должно быть.

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

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

но по замеру показывали всего 5 ком

это не проблема

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

Ещё был найден коротыш между 14 и 15 выводом микросхемы

Вооот! это оно - подозревал

 

а еще перемести индикацию светодиодов меню в обработчик кнопок, тогда сразу увидишь изменение "пункта меню", ну а эффект переключится только после окончания цикла

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

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

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