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

Организация Управления С Помощью Одной Кнопки На Attiny13


Xray

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

Здравствуйте, необходимо устройство которое при нажатии на кнопку включало бы нагрузку на 3 минуты, а при еще одном нажатии во время первого режима ( 3 минуты ) Оставляло бы ее включенной до тех пор пока не нажать кнопку (+ светодиод для контроля этого режима) третий раз. Частоту выбрал 0.128 МГц . Таймер настроил. Переменную в которой секунды сделал. Не могу организовать логи работы. Помогите пжлст.

post-64393-0-34139500-1424094149_thumb.jpg

#include <tiny13.h>
#include <delay.h>
int s = 0, sec = 0,st = 0,sr = 0;
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
s++; // увеличиваем переменную на 2мс
if (s==500)
{
s=0;
sec++; //Увеличиваем переменную каждую секунду
}
}
void main(void)
{
// Function: Bit5=In Bit4=In Bit3=Out Bit2=In Bit1=Out Bit0=In
DDRB=(0<<DDB5) | (0<<DDB4) | (1<<DDB3) | (0<<DDB2) | (1<<DDB1) | (0<<DDB0);
// State: Bit5=T Bit4=T Bit3=1 Bit2=P Bit1=1 Bit0=T
PORTB=(0<<PORTB5) | (0<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (0<<PORTB0);
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Clock value: 128,000 kHz
// Timer Period: 2 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
#asm("sei")
while (1)
{
if (PINB.2==0&&st==0&&sr==0)
{
PORTB.3=0;
sec = 0;
st = 1;
delay_ms (100);		
}
if (PINB.2==0&&st==1&&sr==0)
{
PORTB.3=0;
st = 1;
sr = 1;
delay_ms (100);			
}	
if (PINB.2==0&&st==1&&sr==1)
{
PORTB.3=1;
st = 0;
sr = 0;
delay_ms (100);			
}

}
}

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

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

я бы после

delay_ms (100);

добавил контроль отпускания кнопки

while (!PORTB.3);

delay_ms (100);

в первых двух блоках

как то так

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

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

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

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

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

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

ну не совсем но практически =)

interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
s++; // увеличиваем переменную на 2мс
if (s==500) //Этот цикл выполняется раз в секунду
{
s=0;	
sec++; // Считаем секунды
if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку
{
PORTB.3=0;	
for(i=5;i==0;i--){st=0;} // Выполняем 5сек
}}
if (st==1) // проверяем нажатия раз в 2мс
{
PORTB.3=0;
}
else{PORTB.3=1;}
}

Обработчик нажатия кнопок

while (1)
{
if (PINB.2==0)
  {
   st = 1;
   while (!PORTB.2);
   delay_ms (20);		  
  }
if (PINB.2==0&&st==1)
  {
   sr = 1;
   st = 0;
   while (!PORTB.2);
   delay_ms (20);			 
  }	
if (PINB.2==0&&st==0&&sr==1)
  {
   sy = 1;
   delay_ms (20);		   
  }

}
}

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

круто ) Тогда почитаем перлы, авось чего придумаем

i для цикла for определена глобально?

ну и вот тут

if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку
{
PORTB.3=0;
for(i=5;i==0;i--){st=0;} // Выполняем 5сек
}

этот цикл будет выполняться ровно 5 раз каждое прерывание, а не 5 секунд.

его надо перенести в main и подумать как обеспечить его зависимость от работы таймера

например делать так

if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку
{
i=sec+5;
PORTB.3=0;
while (sec<i) st=0; // Выполняем 5сек
}

только надо помнить, что на этом блоке прога зависнет на 5 секунд. Поэтому если надо делать чтото еще, придется думать глубже

даже лучше так

if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку
{
i=sec+5;
PORTB.3=0;
st=0;
while (sec<i); // Выполняем 5сек
PORTB.3=1;
}

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

даже лучше так

if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку
{
i=sec+5;
PORTB.3=0;
st=0;
while (sec<i); // Выполняем 5сек
PORTB.3=1;
}

Спасибо, работает, теперь пробую обработать второе нажатие, в чем ошибка? Работает через нажатие ...

while (1)
{
if (PINB.2==0)
{
st = 1;
while (!PORTB.2);
delay_ms (20);		
}
if (PINB.2==0&&sy==1)
{
sr = 1;
while (!PORTB.2);
delay_ms (20);			
}	
if (st==1) // Если поднят флаг нажатия кнопки то включаем нагрузку на 5 сек
{
 i=sec+5;
 PORTB.3=0;
 st=0;
 sy = 1;
 while (sec<i) // Выполняем 5сек poka ne najal 2 raz
 {
	 if (sr==1) // Если поднят флаг нажатия кнопки то включаем нагрузку на 10 сек + красный светодиод
		 {
		 t=sec+10;
		 PORTB.3=0;
		 PORTB.1=0;
		 while (sec<t);
		 PORTB.3=1;
		 PORTB.1=1;
		 sr=0;
		 }
 }	
}
PORTB.3=1;

PS к предыдущим постам, все переменные пока определены глобально

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

думайте внимательнее

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

думайте внимательнее

Пробовал и в while подставлять дополнительные инструкции но все мои варианты работают по порядку т.е. после того как отработает первый while. Думаю что нужно добавить какое то условие в while либо прерывание. Так?

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

main
{
delay_ms(10);

if(timeout) --timeout;
if(timeout== 1 && mode== 1)
{
PORTB.3= 1; // истекли 3 мин, выключить нагрузку
mode= 0; // первоначальный режим
}

//опрос кнопки
OldKey= Key;
Key= PINB.2;

if(OldKey && !Key) ++mode; // нажата кнопка

switch(mode)
{
case 0:
	break;

case 1:
	timeout= 18000; // 3 мин в отсчетах 10мсек
	PORTB.3= 0; // включаем нагрузку
	mode= 2;
	break;

   case 2:
	break;

   case 3:
	PORTB.3= 1; // выключаем нагрузку
       mode= 0;
	break;
   }
}

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

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

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

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

естественно организовать везде антидребезг

строите велосипед блин когда в инете полно примеров вашей хотелки))

Не знаеш как? Спроси у Google'а !!!

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

  • 3 недели спустя...
  • 1 месяц спустя...

Вот мой код управления гаражными воротами одной кнопкой на Тини13А , для дистанционного управления можно использовать любую авто сигнализацию взяв сигнал управления замками

/*
* GarVorota_2.c
*
* Created: 13.04.2015 21:57:50
* Author: Dmitry
*/


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

#define NAPR_OPEN PORTB &= ~(1<<0)
#define NAPR_CLOSE PORTB |= (1<<0)
#define DVIG_STOP PORTB &= ~(1<<1)
#define DVIG_PUSK PORTB |= (1<<1)

unsigned char a=1;
//unsigned char b;
ISR(PCINT0_vect) // обработка прерывания
{
if (!(PINB &(1<<PINB3))) // Только если концевик замкнут
{
DVIG_STOP;	 // остановить двигатель
_delay_ms(50);
NAPR_OPEN;
a++;		 // определить направление вращения
if(a==5)
a=1;
}
}

void Stop() // Остановка двигателя
{
_delay_ms(20);
DVIG_STOP;
_delay_ms(50);
NAPR_OPEN;
};


int main(void)
{ // Настрока порта
DDRB = 0b00000011;
PORTB = 0b00011100;
// Настройка и разрешение прерывания PCINT3 PCINT4
PCMSK = (0<<PCINT5) | (1<<PCINT4) | (1<<PCINT3) | (0<<PCINT2) | (0<<PCINT1) | (0<<PCINT0);
GIMSK |= (1<<PCIE); GIFR |= (1<<PCIF);
sei();

while(1)
{
_delay_ms(1000);
while (PINB &(1<<PINB2)){}
switch(a)
{
case 1:
_delay_ms(100);
NAPR_OPEN; // Вращение на открытие
_delay_ms(100);
DVIG_PUSK; // Пуск двигателя
a=2;
break;

case 2: // Stop
Stop();
a=3;
break;

case 3:
_delay_ms(100);
NAPR_CLOSE; // Вращение на закрытие
_delay_ms(100);
DVIG_PUSK; // Пуск двигателя
a=4;
break;

case 4: //Stop
Stop();
a=1;
break;
}

}
}

Осталась не прописана защита по току ,одна кнопка осталась пока свободной (на ней она и будет реализована), на случай заклинивания ворот по каким либо причинам .

Vorota.rar

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

  • 6 месяцев спустя...

Дмитрий Спасибо Вам за такой проект. компилировал исходник и проверил в Протеусе. Работает нормально. Но не все понятно... А можно описать работу вашего проекта. Я так понял кнопка на PB2- включает(вперед) , выключает, включает (назад) и выключает. А кнопки OPEN и CLOSE- концевики или как?

Proteus.rar

Vorota.PDF

post-65168-0-26710800-1445243156_thumb.jpg

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

кнопка на PB2

Включает движение, обратное концевикам OPEN и CLOSE. Т.е. если закрыто, то открывает и наоборот.

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

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

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

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

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

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

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

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

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

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

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

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