Jump to content
tifaso

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

Recommended Posts

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

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

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


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

Share this post


Link to post
Share on other sites

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

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


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

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

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

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

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

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

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


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

Share this post


Link to post
Share on other sites

Безмостовые ККМ для 99% КПД!

Схема коррекции коэффициента мощности (ККМ) на основе так называемого «тотемного столба» (Totem Pole) обладает минимально возможными потерями и потенциально может обеспечить самые жесткие требования к энергоэффективности источников питания. Компания Wolfspeed представляет референсную разработку – плату ККМ CRD-02AD065N на базе собственных карбид-кремниевых MOSFET и диодов с наилучшими в отрасли характеристиками.

Подробнее

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

 

Share this post


Link to post
Share on other sites

Гибридные IGBT - сила Si и SiC в одном корпусе!

Компания Infineon представила новые гибридные IGBT-транзисторы на 650 В, которые сочетают в себе преимущества технологий TRENCHSTOP и CoolSiC. Использование SiC-диода Шоттки позволяет значительно расширить возможности IGBT и снизить уровень энергии, необходимой для включения транзистора (Eon), а также уменьшить потери на переключение.

Подробнее

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

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

Вебинар «Параметры выше, цена ниже. Обновление в линейке AC/DC- и DC/DC-преобразователей MORNSUN» (26.01.2021)

Приглашаем 26 января на бесплатный вебинар, посвящённый преимуществам и отличиям новых источников питания и DC/DC-преобразователей Mornsun. На вебинаре будут рассмотрены изолированные и неизолированные DC/DC-преобразователи последнего, четвертого, поколения (R4) и компактные модульные источники питания второго и третьего поколений (семейства LS/R3 и LD/R2) на плату. Рассмотрим новую группу продукции – встраиваемые источники питания в кожухе.

Подробнее

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

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

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

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

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

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

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

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

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

 

Share this post


Link to post
Share on other sites
2 часа назад, tifaso сказал:

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

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

 

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

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

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

Share this post


Link to post
Share on other sites
1 час назад, Алексей Еремеев сказал:

мой код симулировал в протеусе

3d-funny-monster-cartoon-cute-938.jpg

 

Share this post


Link to post
Share on other sites
1 час назад, Алексей Еремеев сказал:

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

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

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

 

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

Share this post


Link to post
Share on other sites

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

Edited by samogon

Share this post


Link to post
Share on other sites

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

1059290498_3.JPG.890d8f5ca371cf8f098a856fe8e00c2b.JPG

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

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

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

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

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites
31 минуту назад, tifaso сказал:

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

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

Share this post


Link to post
Share on other sites

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

Edited by tifaso

Нарушение правил форума II.24

Share this post


Link to post
Share on other sites

 

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

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

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

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

 

Share this post


Link to post
Share on other sites

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


Нарушение правил форума II.24

Share this post


Link to post
Share on other sites
1 час назад, tifaso сказал:

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

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

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

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

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

 

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

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

Edited by Алексей Еремеев

Share this post


Link to post
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
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...

  • Сообщения

    • Ещё один очень интересный ролик о том, как создавался фильм о дворце пуйла, который не может никак достроится и теперь не будет им использоваться, о конспирации и уходе от слежения ФСБешников итд итп .  
    • Всем - Благодарю, частично распаяна плата, поэтому делаю так:
    • Я действительно пропустил один момент, но не этот. Я не обратил внимание что переменная "а" сохраняется между вызовами функции поскольку статическая, конструкция очень не стандартная поэтому я даже не пытался ее анализировать, потому что безапеляционно решил что это ошибка, так бывает у всех - не все в состоянии это признать. С учетом этого моего упущения смысл, действительно, появляется. Похоже ваша улыбка простимулировала понимание  !
    • Помогли найти схему на данный аппарат. В схеме защиты был треснут диод 4148. Хотя звонился как рабочий. Видно при нагреве коротил. схема тут, только что-то стаба на 5В в ней не заметил.  Ту что я нарисовал, одним резистором отличается. Кстати по схеме другие моточные данные трансформатора дежурки. Поварил ПА несколько швов см по 10. В защиту не ушел.  Считаю тему решенной. 
    • По секрету (только тсссс.....) - он сам себе метролог (вероятно главный). Хорошее название для семейной кинокомедии! Почти эквивалент "Сам себе сама"

  • Настольный гравировальный станок NEJE Master 2 - 3500

×
×
  • Create New...