Jump to content
tifaso

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

Recommended Posts

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

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

ISR(TIMER1_OVF_vect)
{
	if (~PINB & (1<<0))
	{
       PORTD = 0b00000000;
  	}
	if (~PINB & (1<<1))
	{
  		PORTC &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4));
  	}
}

int main(void)
{
	DDRB = 0b11111100;
	DDRC = 0b1111111;
	DDRD = 0b11111111;
	PORTB = 0b00000000;
	PORTC = 0b0000000;
	PORTD = 0b00000000;
	
	TIMSK |= (1<<2);
	TCCR1B = 0b00000001;
	TCNT1 = 32768;
	sei();
    while(1)
    {
    }
}   
      
  

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


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

Share this post


Link to post
Share on other sites

В прерывании по таймеру нужно только инкрементировать некую переменную (например intTimerVar). Таким образом эта переменная будет изменяться например каждую миллисекунду. Далее в бесконечном цикле главной программы смотрится - изменилась ли эта таймерная переменная intTaimerVar, и если изменилась, то значит время пришло - пора идти смотреть что там с кнопками - запустить функцию xxxGetButton(). 

Функция xxxGetButton()  должна строиться как конечный автомат для устранения дребезга. Ну и так далее...

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-принтер и так далее...

Вебинар "Новый BlueNRG-LP с Bluetooth 5.2 и Long Range — волшебная палочка разработчика IoT" (04/02/2021)

Приглашаем 4 февраля на бесплатный вебинар о BlueNRG-LP - новой системе-на-кристалле (SoC) STMicroelectronics. На вебинаре будут детально рассмотрены функциональные блоки, особенности подключения, аппаратные и программные средства для разработки, настройка сценариев с помощью BlueNRG-GUI, практические примеры работы с микросхемой, а также примеры применения BlueNRG-LP в устройствах интернета вещей.

Подробнее

@dasZebra Сделал всё так как ты и сказал, но ничего не изменилось. Всё тоже самое.

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile unsigned char menu=1;
volatile unsigned char btn=1;
volatile unsigned char timer=0;

ISR(TIMER1_OVF_vect)
{
	timer=1;
}

GetButton()
{
	if (~PINB & (1<<0))
	{
		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 (btn==1)
		{
			PORTB |= (1<<2);
			btn=1;
			menu=1;
		}
		if (btn==2)
		{
			PORTB |= (1<<2);
			btn=1;
			menu=1;
		}
		if (btn==3)
		{
			PORTB |= (1<<3);
			btn=2;
			menu=2;
		}
		if (btn==4)
		{
			PORTB |= (1<<4);
			btn=3;
			menu=3;
		}
		if (btn==5)
		{
			PORTB |= (1<<5);
			btn=4;
			menu=4;
		}
		if (btn==6)
		{
			PORTB |= (1<<6);
			btn=5;
			menu=5;
		}
		if (btn==7)
		{
			PORTB |= (1<<7);
			btn=6;
			menu=6;
		}
		if (btn==8)
		{
			PORTC |= (1<<0);
			btn=7;
			menu=7;
		}
		if (btn==9)
		{
			PORTC |= (1<<1);
			btn=8;
			menu=8;
		}
		if (btn==10)
		{
			PORTC |= (1<<2);
			btn=9;
			menu=9;
		}
		if (btn==11)
		{
			PORTC |= (1<<3);
			btn=10;
			menu=10;
		}
		timer=0;
	}
	if (~PINB & (1<<1))
	{
		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 (btn==11)
		{
			PORTC |= (1<<4);
			btn=11;
			menu=11;
		}
		if (btn==10)
		{
			PORTC |= (1<<4);
			btn=11;
			menu=11;
		}
		if (btn==9)
		{
			PORTC |= (1<<3);
			btn=10;
			menu=10;
		}
		if (btn==8)
		{
			PORTC |= (1<<2);
			btn=9;
			menu=9;
		}
		if (btn==7)
		{
			PORTC |= (1<<1);
			btn=8;
			menu=8;
		}	
		if (btn==6)
		{
			PORTC |= (1<<0);
			btn=7;
			menu=7;
		}
		if (btn==5)
		{
			PORTB |= (1<<7);
			btn=6;
			menu=6;
		}
		if (btn==4)
		{
			PORTB |= (1<<6);
			btn=5;
			menu=5;
		}
		if (btn==3)
		{
			PORTB |= (1<<5);
			btn=4;
			menu=4;
		}
		if (btn==2)
		{
			PORTB |= (1<<4);
			btn=3;
			menu=3;
		}
		if (btn==1)
		{
            PORTB |= (1<<3);
            btn=2;
            menu=2;
		}
		timer=0;
	}
}

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 (timer==1)
		{
			GetButton();
		}
		
        if (menu==1)
        {
	        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);
        }
        if (menu==2)
        {
	        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);
        }
        if (menu==3)
        {
	        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);
        }
        if (menu==4)
        {
	        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);
        }
    }
}

Вот он код прошивки на этот раз весь.

Edited by tifaso

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

Share this post


Link to post
Share on other sites

Новые компактные конденсаторы Panasonic серии TPS. Закаленный характер.

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

Подробнее

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

Вот он код прошивки на этот раз весь.

Большая портянка. Во первых нельзя пихать делай в бесконечный цикл. Во вторых.... 

вот погляди просто кнопки   (там правда косяк - 8ми битный счетчик, ну да ладно):

/*
 * Atmega32  Buttons
 */ 

/* 8ми битный счетчик: нужно использовать для коротких отсчетов. */
#define F_CPU 8000000UL       // Частота кварца
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//----------------------------------------

#define PIN_BUTTONS (PIND&=(1<<7)) && (PIND&=(1<<6)) && (PIND&=(1<<5)) && (PIND&=(1<<4)) && (PIND&=(1<<3))  // сюда подключены кнопки
// так же нужно бы определить порт
 
unsigned char char_sys_20ms_beat=0;                // Системный таймер 
unsigned char DelayReadBUTTON=6 , DelayClickBUTTON =3;   // Стартовые значения задержек для процессов
char charNumberClickBUTTON=0;                    // Номер нажатой кнопки

ISR (TIMER0_COMP_vect)                            // Вектор прерывания первого 8ми битного таймера
{
    cli();
    /* прерывание будет вызываться каждые 4 ms но ТРЕБУЕТСЯ каждые 20 ms*/
    static char chat_timer1_inkrement =0; 
    TCNT0 = 0;
    chat_timer1_inkrement++;        //прерывание увеличивает внутрений подсчетчик
    if (chat_timer1_inkrement > 4)  // и когда он добирается до 5ти то обнуляется увеличивая int_sys_20ms_beat каждые 0.02 сек
     {
        chat_timer1_inkrement = 0;
         char_sys_20ms_beat++;       // вот оно
     }
    sei();
}

char Delay_8bit_count(unsigned char Delay_1)    // расчитывает значение для 8мити битного таймера, с которым должен совпасть системый таймер
{
    unsigned char newDelay=0;                   // локальная переменная 
    newDelay = char_sys_20ms_beat + Delay_1;   // новое значение
    return newDelay;
}


char ReadBUTTONs(void)                          // BUTTONs ЧТЕНИЕ СОСТОЯНИЯ
{
    static char steps=0;   // переменная, запоминающая состояние автомата 
     char ret_BUTTON=0;
    switch (steps)
    {
        case 0:
        {
            if (PIN_BUTTONS) {return ret_BUTTON;}  
            steps=1;    
        }
        case 1:
        {
            if (PIN_BUTTONS) {return ret_BUTTON;}  
            steps = 2;
        }
        case 3:
        {
            if (PIN_BUTTONS) { steps = 0; return ret_BUTTON; }  
                if (!(PIND&=(1<<7)))  { ret_BUTTON = 1;  steps = 0; return ret_BUTTON; }
                if (!(PIND&=(1<<6)))  { ret_BUTTON = 2;  steps = 0; return ret_BUTTON; }
                if (!(PIND&=(1<<5)))  { ret_BUTTON = 3;  steps = 0; return ret_BUTTON; }
                if (!(PIND&=(1<<4)))  { ret_BUTTON = 4;  steps = 0; return ret_BUTTON; }
                if (!(PIND&=(1<<3)))  { ret_BUTTON = 5;  steps = 0; return ret_BUTTON; }
        }
    default: return ret_BUTTON;
    }
}
void ButtonClickProcessings(void)              // Buttons РЕАКЦИЯ
{
    if (!charNumberClickBUTTON) 
    {
        return;
    }
    if (charNumberClickBUTTON == 1)
    {
        // вызвать какую нужно функцию, что бы выполнить что нужно
        // или выставить ФЛАГ, что бы нужная функция выполнила что нужно
        charNumberClickBUTTON = 0;
        return;
    }
    if (charNumberClickBUTTON == 2)
    {
        // вызвать какую нужно функцию, что бы выполнить что нужно
        // или выставить ФЛАГ, что бы нужная функция выполнила что нужно
        charNumberClickBUTTON = 0;
        return;
    }
    if (charNumberClickBUTTON == 3 )
    {
        // вызвать какую нужно функцию, что бы выполнить что нужно
        // или выставить ФЛАГ, что бы нужная функция выполнила что нужно
        charNumberClickBUTTON = 0;
        return;
    }
    if (charNumberClickBUTTON == 4)
    {
        // вызвать какую нужно функцию, что бы выполнить что нужно
        // или выставить ФЛАГ, что бы нужная функция выполнила что нужно
        charNumberClickBUTTON = 0;
        return;
    }
    if (charNumberClickBUTTON == 5)
    {
        // вызвать какую нужно функцию, что бы выполнить что нужно
        // или выставить ФЛАГ, что бы нужная функция выполнила что нужно
        charNumberClickBUTTON = 0;
        LCD_PrintStr1();
        return;
    }
    
}
int main(void)
{

/*Инициализация первого 8ми биттный таймер*/
 TCCR0=(1<<CS02);            // делитель на 256: 8 000 000/256=31250 => 1/31250=0.000032 сек
 TIMSK|=(1<<OCIE0);            // добавляет в общий для всех таймеров регистр разрешение прерывания по стравнению с OCR0
 OCR0 = 0x7D;                //  0.000032сек х 125 прерывание будет происходить каждые 4ms (0.004)
/*Конец инициализации первого 8ми битного таймера*/

  
 /*К данному порту подключены кнопки*/
PORTD=0;  //  порт глушится в Z состояние - прописать в дефайн
  
sei();              //Разрешение прерываний
/* Внимание!!! функцию delay() (например для задания задержек при инициализации перефирии) можно использовать только до этого места */    
    while(1)
    {
           
        //Считывание нажатия кнопок =>
        if (DelayReadBUTTON == char_sys_20ms_beat)     // Вызов функции через заданный интервал
        {
            DelayReadBUTTON =  Delay_8bit_count(8);    // Расчет значения следующего вызова
             charNumberClickBUTTON= ReadBUTTONs();     // Чтение кнопок
         }
        
        if (DelayClickBUTTON == char_sys_20ms_beat)    // Вызов функции через заданный интервал
        {
            DelayClickBUTTON =  Delay_8bit_count(3);   // Расчет значения следующего вызова
            ButtonClickProcessings();                  // Выполнение нажатия кнопки
        } 
        
        /*Как это работает:
        С заданным интервалом  запускается функция ReadBUTTONs() чтения состояния порта, 
        которая выполняется за три шага (), и если до третьего шага дошло (антидребезг), то она вывешивает номер нажатой кнопки
        
        Параллельно, со своим интервалом запускается функция чтения переменной, в которуу записывается номер нажатой кнопки,
        и если обнаруживается значение, то вызывается нужная функция или наример переменной написатьхyйнаэкране присваивается 1
        
        Параллельно, со своим интервалом запускается функция, которая смотрит, а не равна ли единице переменная написатьхyйнаэкране
        и если равна, то функция выводит на экране заветный Hello World.
        
        таким образом ничего не путается, не накладывается, не глючит, не тупит, легко масштабируется и тдю и тп
        
        как то так вобщем. Вобщем алгоритм этот был придуман наверно неким Цезарем, который был Гай Июлий и называется
         - "разделяй и влавствуй"
           
        
        */
        
    }
}

 

Share this post


Link to post
Share on other sites

SiC MOSFET на 1200 В для схем флайбэк до 500 Вт!

Компания Wolfspeed выпустила новые карбид-кремниевые транзисторы C3M0350120D/J на 1200 В, предназначенные для маломощных устройств мощностью до 500 Вт. Карбид-кремниевые транзисторы в сравнении с кремниевыми демонстрируют меньший на 75% уровень потерь на переключение и меньшее на 50% значение потерь проводимости в рабочем режиме при температуре кристалла 100…150°С.

Подробнее

@dasZebra Всё это как то выглядит сильно сложно, но я попробую завтра разобраться. Сейчас уже время позднее (12 ночи). 


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

Share this post


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

@dasZebra Сейчас уже время позднее (12 ночи). 

12? Офигеть.... у меня 18.30:D

 

Кривовато да, но не сложно. 

Edited by dasZebra

Share this post


Link to post
Share on other sites

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

	if (~PINB & (1<<0))
	{
		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;
		btn--;
		if (btn==0)
		{
			btn=1;
		}
	}
	if (~PINB & (1<<1))
	{
		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;
		btn++;
		if (btn==12)
		{
			btn==11;
		}
	}

	if (btn==11)
	{
		PORTC |= (1<<4);
		btn=11;
		menu=11;
	}
	if (btn==10)
	{
		PORTC |= (1<<3);
		btn=10;
		menu=10;
	}
	if (btn==9)
	{
		PORTC |= (1<<2);
		btn=9;
		menu=9;
	}
	if (btn==8)
	{
		PORTC |= (1<<1);
		btn=8;
		menu=8;
	}
	if (btn==7)
	{
		PORTC |= (1<<0);
		btn=7;
		menu=7;
	}
	if (btn==6)
	{
		PORTB |= (1<<7);
		btn=6;
		menu=6;
	}
	if (btn==5)
	{
		PORTB |= (1<<6);
		btn=5;
		menu=5;
	}
	if (btn==4)
	{
		PORTB |= (1<<5);
		btn=4;
		menu=4;
	}
	if (btn==3)
	{
		PORTB |= (1<<4);
		btn=3;
		menu=3;
	}
	if (btn==2)
	{
		PORTB |= (1<<3);
		btn=2;
		menu=2;
	}
	if (btn==1)
	{
		PORTB |= (1<<2);
		btn=1;
		menu=1;
	}

Я думал как то так, но оно не работает. 


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

Share this post


Link to post
Share on other sites

Я бы делал это иначе - читал значение портов и двигал бы эти значения туда-сюда, попутно следя за флагами нуля и переноса.

ЗЫ: А вот выражение if (btn==1) btn=1; мне вообще не понятно =(


Телеграмм канал для кладоискателей @ReviewdetectorChannel

Share this post


Link to post
Share on other sites

@mr_Kuzmich Чего то я не понял как это читать значение портов? Слишком это непонятно. Я даже не могу представить как это будет в коде. Там же проверяется нажатие кнопки и меняется переменная. Но почему оно не срабатывает я вообще не понимаю.

Edited by tifaso

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

Share this post


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

. Но почему оно не срабатывает я вообще не понимаю.

Упрости: у тебя есть ОДНА КНОПКА и ОДИН светодиод. Начал кнопку -светодиод включился. Нажал еще раз - выключился. 

 

Share this post


Link to post
Share on other sites

Нет ты не понял. У меня есть 2 кнопки и 11 светодиодов. Допустим на данный момент светит 4 светодиод нажимая одну кнопку четвёртый светодиод гаснет и включается 3 светодиод, а если нажать на другую кнопку, тогда четвёртый светодиод также гаснет и включается уже пятый светодиод. У меня уже всё это распаяно и подготовлено нужно только прошивку дописать в микросхему. Переделывать всё это очень сложно и долго. 

Edited by tifaso

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

Share this post


Link to post
Share on other sites

Берешь переменную, например некую "i"  и  в начале инициализации  задаешь ей некое  значение, то значение которое является начальным для порядкового значения свечения светодиода. Значение этой переменной проверяешь в основном цикле и если оно изменилось, то изменяешь и вывод свечения светодиодов, например через "case" или же через "портянку " кода. К примеру при включении устройства начальное значение 

i=4; 

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

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

Такое решение "в лоб" является всего лишь алгоритмом. Его можно упростить вплоть до бинарных сдвигов в регистре порта, записи значения переменной "i" в флешь память МК (для запоминания последнего значения переменной и возврата к нему после включения устройства) , проверку значения действующего пина порта , но сложность понимания кода тогда увеличится. 

Есть ли смысл?

Я делал одноразовое устройство на Mega8 в котором использовались два семисегментники и две кнопки по такому алгоритму.  По нажатию на одну из них значение табло увеличивалось, а второй уменьшалось. Если подержать дольше то скорость изменения  чисел увеличивалась (сделано для удобства). Основной код выполнял выдачу ШИМ генерацию на силовой транзистор. Проект был сделан для управления двигателем подачи проволоки в сварочном аппарате. 

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


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

Share this post


Link to post
Share on other sites

@Beliy_voron Я сейчас вроде всё так и сделал, но оно хоть ты тресни ни в какую не работает.


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

Share this post


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

Переделывать всё это очень сложно и долго. 

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

То есть сначала просто мигаешь светодиодом. Если все ок, мигаешь светодиодами "по кругу". Потом задецствуешь кнопку. Потом задействуешь другую. То есть от элементарного к простому, от простого к более сложному, и т.д.

Edited by dasZebra

Share this post


Link to post
Share on other sites

Самое главное в этой каше понять что такое прерывание и как оно работает. Как только удастся сделать подпрограмму прерывания (фактически программную или вообще аппаратную) тогда все пойдет как по маслу. 

А для этого нужно подключить таймер и в таймере каждые несколько десятков (сотен) микросекунд проверять - а не нажата ли наша кнопка? Обычно она не нажата и все гуд. Но только она нажалась, тогда надо что бы:

и вся программа останавливается и исполняется то что в прерывании. 

А в прерывании у нас изменяется переменная. Ну изменилась и Бог с ней. Прерывание окончилось. Главный цикл снова запустился. Но в главном цикле уже наша переменная используется и уже  измененная. Значит цикл будет работать по другому алгоритму, а по какому Вы уже напишете сами согласно Ваших нужд. 


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

Share this post


Link to post
Share on other sites

Прерывания я сделал они у меня работают проверил светодиодом. Тут скорей косяк именно с переключателем. Причем когда нажимаешь кнопку даже заметно что какие то действия выполняются, но я понял по какой то причине не происходит смены значений переменной при нажатии. Вот это до меня сейчас дошло и весь косяк в этом. Может я неверно переменную обьявил?

Переменная btn и есть стартовая переменная которая управляет переключателем

Весь код на данный момент:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile unsigned char menu=1;
volatile unsigned char btn=1;

ISR(TIMER1_OVF_vect)
{
    	if (~PINB & (1<<0))
    	{
	    	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;
	    	btn--;
	    	if (btn==0)
	    	{
		    	btn=1;
	    	}
    	}
    	if (~PINB & (1<<1))
    	{
	    	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;
	    	btn++;
	    	if (btn==12)
	    	{
		    	btn=11;
	    	}
    	}	
}

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 (btn==11)
    	{
    		PORTC |= (1<<4);
    		menu=11;
    	}
    	if (btn==10)
    	{
    		PORTC |= (1<<3);
    		menu=10;
    	}
    	if (btn==9)
    	{
    		PORTC |= (1<<2);
    		menu=9;
    	}
    	if (btn==8)
    	{
    		PORTC |= (1<<1);
    		menu=8;
    	}
    	if (btn==7)
    	{
    		PORTC |= (1<<0);
    		menu=7;
    	}
    	if (btn==6)
    	{
    		PORTB |= (1<<7);
    		menu=6;
    	}
    	if (btn==5)
    	{
    		PORTB |= (1<<6);
    		menu=5;
    	}
    	if (btn==4)
    	{
    		PORTB |= (1<<5);
    		menu=4;
    	}
    	if (btn==3)
    	{
    		PORTB |= (1<<4);
    		menu=3;
    	}
    	if (btn==2)
    	{
    		PORTB |= (1<<3);
    		menu=2;
    	}
    	if (btn==1)
    	{
    		PORTB |= (1<<2);
    		menu=1;
    	}		
		
        if (menu==1)
        {
	        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);
        }
        if (menu==2)
        {
	        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);
        }
        if (menu==3)
        {
	        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);
        }
        if (menu==4)
        {
	        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);
        }
    }
}

 

Edited by tifaso

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

Share this post


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

А для этого нужно подключить таймер и в таймере каждые несколько десятков (сотен) микросекунд проверять - а не нажата ли наша кнопка? Обычно она не нажата и все гуд. Но только она нажалась, тогда надо что бы:

и вся программа останавливается и исполняется то что в прерывании. 

Не надо так делать. 

 

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

Весь код на данный момент:

Ты думаешь кому то захочется изучать твой код? 

На вскидку: 

- в прерывании должно быть только инкрементирование переменной.

В бесконечном цикле не должно быть никаких задержек. 

 

Share this post


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

Самое главное в этой каше понять что такое прерывание и как оно работает. Как только удастся сделать подпрограмму прерывания (фактически программную или вообще аппаратную) тогда все пойдет как по маслу. 

А для этого нужно подключить таймер и в таймере каждые несколько десятков (сотен) микросекунд проверять - а не нажата ли наша кнопка? Обычно она не нажата и все гуд. Но только она нажалась, тогда надо что бы:

и вся программа останавливается и исполняется то что в прерывании. 

А в прерывании у нас изменяется переменная. Ну изменилась и Бог с ней. Прерывание окончилось. Главный цикл снова запустился. Но в главном цикле уже наша переменная используется и уже  измененная. Значит цикл будет работать по другому алгоритму, а по какому Вы уже напишете сами согласно Ваших нужд. 

Согласен в принцепи так я всё и построил в своей программе и всё бы ничего работает но не работают только строки переключения переменной btn--; и btn++; никак только не пойму почему? Остальное же всё срабатывает так как и должно быть.


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

Share this post


Link to post
Share on other sites

Замучился уже искать решение как сделать? Объявлял уже и переменные по разному, но либо не работает либо вообще в ошибку вылетает. Ни хочет он почему то из таймера переменную уменьшать либо прибавлять и сами строки переписывал по другому, но ничего не меняется. Так я и не могу сообразить как из таймера изменить значения переменной.


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

Share this post


Link to post
Share on other sites

а смысл? Вы же все равно пользуетесь своим бредо генератором не взирая на то что вам пишут.

Share this post


Link to post
Share on other sites

В принципе... если ресурсы МК больше не под что не будут заняты и не ограничиваясь памятью МК и если не лезть в дебри профессионального программирования, то код @tifaso  будет работать. Туго конечно, но если бы его залить в реальное устройство и показать публике, то большинство не поняло бы что там на каждом моменте delay. :)


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

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...

  • Сообщения

    • Рекомендация не приближаться к местам высадок Аполлона 11 и17 совершенно не говорит о нежелании показать достоверную информацию.  Разве будет недостаточно близко подойти на 75 метров?  А к другим Аполлонам можно ближе. А какая она ещё должна быть? - прямая что-ли??? Она всегда была и будет только косвенной. В смысле, что ракеты не взрывались? Так это мы сравниваем с нашими, которые из-за спешки постоянно взрывались. А заметные заминки и сбои были. Как же без этого? Приплыли! Вот скажи, пожалуйста, ты сам пробовал искать эту информацию и ничего не нашёл???  Или просто прочитал это в методичке для начинающего "немоглика" ? Информации по грунту имеется выше крыши. И я тоже выкладывал здесь ссылку на экскурсию по хранилищу нашими космонавтами С.Кудь-Сверчкова и О.Скрипочки. Каких предметов или обьектов?   Как раз её отсутствие является доказательством телевизионных съемок именно с поверхности Луны!  Так как на Земле подобного снять было невозможно!  Так это похвально! Мы тоже стремились быть первыми любой ценой. Вот только денег у нас было гораздо меньше, да и по технологиям сильно отставали. Ты изучил всю историю развития космонавтики США и не увидел не одного применения наработок? Или опять это прочитал в методичке? В 1969 году не было фотошопа. Ни за какие деньги! Вообще-то, это просто. Идёшь учится в ВУЗ  со специальностью проектирование авиационных и ракетных двигателей или какой нибудь математический или физический, где преподают астрономию. И все проблемы. Никаких сомнений не будет!   А как можно убеждать необразованных людей, что американцы высаживались на Луне?  Подскажи хоть один вариант такого убеждения.  
    • Имеются 2 системных блока 1-й блок с установленной XP SP2 Его внешний вид и рабочая начинка на фото 2-й блок. Начинка: материнка(такая же, как в первом) и блок питания Могу подкинуть мышь и клавиатуру, силовые и другие кабели...Поищу также планки с памятью Находятся в Сходне(между Москвой и Зеленоградом). Самовывоз. П.С. Если у желающего ВДРУГ окажется парочка КТ825-был бы рад.
    • @KRAB Рисовал не я , вопросы не ко мне. Просто нашел и показал. Схемы выше в теме чем лучше? Там защита есть какая?
    • непойми для кого ... Хоть кто-то понимает какой ПУСКОВОЙ ТОК у   И при этом - ни токового протекта, ничего ... Кто рисовал эту схему? Дятел? для интернетпомойки .... и не более.
    • разве это повод задавать ТУПЫЕ вопросы? Да и сама задача - верх тупости .... А будешь возражать - задам такой вопрос про ЭТО - что .... Так что не стОит парить мозги ... купил игрушку - играйся .... пока не научишься ей работать ....
    • тупость это .... жмотоламерская .... в направлении МАСТЕРА ....   да и с БУКВАРЕМ не дружишь .... рановато ты полез в мониторы .... через год знакомства с электроникой - твой уровень - соседке утюг починить, вилку прикрутить ... а не в сложнобытовую технику лезть.
    • так и будет, пока не разделишь проблему на ИИП и инвертор и не прочтешь про БЛОКИРОВКУ ПРОТЕКТА в ИНВЕРТОРАХ ПОДСВЕТКИ ....

  • Мощные небольшие моторчики, 2 шт.

×
×
  • Create New...