Страница 1 из 2

Переключение режима кнопкой.

Добавлено: Вт окт 11, 2016 19:35:16
sTRog
Нужно переключать два режима с одного на другой - кнопокй без фиксатора. В момент переключения может работать устройство, которое легко сажает всю батарейку, если держать ключ (полевой транзистор) открытым. Поэтому открываю ключ на 1 ms - так не сажает.
Однако, когда нажимаю кнопку, и МК ее обрабатывает - вся система вешается. Т.е. батарейка, которую я использую (литионка на 4 В), показывает 0.5 В. И единственный способ запустить снова работу - это разьеденить цепь и заново замкнуть.
Код использую такой
Спойлер

Код: Выделить всё

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

char mod = 0;
int FixTime = 5400;
volatile uint8_t i;
volatile uint8_t Sec;
int tp = 0; // time pain - время сколько бьет током.

ISR(TIM0_OVF_vect)
{
   if (!(++i%4)) //period 1s
   {   PORTB ^= (1<<PB0);
      Sec++;
   }
}

int main(void) {


   PRR = (1<<PRADC); // shut down ADC

        TIMSK0 = (1<<TOIE0);  // timer0 overflow interrupt enable
        TCCR0B = (1<<CS02) | (1<<CS00); // prescaler 1/1024

   DDRB |= (1<<PB0);
   i=0; Sec=0;

   sei();
   int RandTime = 3600 + random()%3600;
   
   DDRB |=(1<<2); //транзистор
   DDRB |=(1<<3); //cветодиод З
   DDRB |=(1<<4); //cветодиод К
   DDRB &=~(1<<1); //кнопка
 
while (1)
{
	
	if (mod==0) //если первый режим включен, то когда прошедшее время равно RandTime - подаем напряжение на ножку.
	{
			while (tp <= 20)
				{
			
			        PORTB &=~(1<<2);
					_delay_ms(100);
					PORTB |= (1<<2);
					_delay_us(1000);
					tp++; 
				}
				tp = 0;
			
	}
	else //если второй режим включен, то когда прошедшее время равно FixTime - подаем напряжение на ножку.
	{
		while (tp <= 20)
		{
			
	                PORTB &=~(1<<2);
			_delay_ms(4000);
			PORTB |= (1<<2);
			_delay_us(1000);
			tp++; 
		}
		tp = 0;		
	}
	
	
	if (PINB & (1<<1)) //Если на ножке есть напряжение то:
	{
		if (mod==0) //Если включен режим 0, меняем его на 1
		{
			mod = 1;
			
			Sec = 0; //обнуляем время

			_delay_ms(100);
			
			
			
		}
		else //Если включен 1 режим, меняем его на 0
		{
			mod = 0;
			
			Sec = 0; //обнуляем время
			
			_delay_ms(100);
			
			
		}
	}
}

    
}
И еще вопрос.
Микроконтроллер управляет через ключ в виде полевого транзистора можным устройством.
Если задать команду
Спойлерwhile (1)
PORTB &=~(1<<2);
_delay_ms(4000);
PORTB |= (1<<2);
_delay_us(1000);
То выдает сигнал раз в 4 сек.
Но если добавить после этого
СпойлерPORTB &=~(1<<2);
_delay_ms(4000);
PORTB |= (1<<2);
_delay_us(1000);
PORTB &=~(1<<2);
_delay_ms(1000);
PORTB |= (1<<2);
_delay_us(1000);
Т.е. должен срабатывать так: 4 сек ждет, сигнал, 1 сек ждет, сигнал, 4 сек ждет и т.д.
Но по факту работает так: 4 сек ждет, сигнал, 4 сек ждет и т.д.
Почему?

Re: Переключение режима кнопкой.

Добавлено: Ср окт 12, 2016 10:33:02
Demiurg
В вашем случае нужно описать что за устройство, схема. Затруднения. И только потом код. Один код без описания и схем бесполезен.

Re: Переключение режима кнопкой.

Добавлено: Ср окт 12, 2016 16:55:51
sTRog
Меня интересует - есть ли ошибка в коде?

Re: Переключение режима кнопкой.

Добавлено: Ср окт 12, 2016 17:14:13
Demiurg
То есть ваше устройство - тайна великая, а здесь форум телепатов? Весь ваш код - ошибка. Что дальше?

Re: Переключение режима кнопкой.

Добавлено: Ср окт 12, 2016 19:45:40
Аlex
Т.е. вешается батарейка до 0.5V, а показываем нам код и ищем в нём проблему. Где логика ? :dont_know:
Причём тут вообще код, если проблема с питанием ? :dont_know:

Re: Переключение режима кнопкой.

Добавлено: Ср окт 19, 2016 19:14:48
sTRog
Новая формулировка.
Режим (используется этот код) переключается самостоятельно, хотя ножка, которая испольняет роль кнопки - обесточена и подтянута резистором 5кОМ к массе.

Re: Переключение режима кнопкой.

Добавлено: Ср окт 19, 2016 21:01:31
Mishany
Без схемы - разговор ни о чем.

Re: Переключение режима кнопкой.

Добавлено: Сб окт 22, 2016 18:40:11
sTRog
Изображение

Re: Переключение режима кнопкой.

Добавлено: Сб окт 22, 2016 19:22:57
leo__b
а вот так, без контроллера не пойдет? (извините за корявый рисунок).

Re: Переключение режима кнопкой.

Добавлено: Сб окт 22, 2016 23:27:09
sTRog
leo__b писал(а):а вот так, без контроллера не пойдет? (извините за корявый рисунок).
Типо вибратор?
Просто микрокотроллер мне нужен - потому что светодиод должен зажигать в определенный интервал, а точнее, в случайное время казанного интервала.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 00:17:52
leo__b
sTRog писал(а):
leo__b писал(а):а вот так, без контроллера не пойдет? (извините за корявый рисунок).
Типо вибратор?
Просто микрокотроллер мне нужен - потому что светодиод должен зажигать в определенный интервал, а точнее, в случайное время казанного интервала.
Из описания я понял, что по кнопке вам нужно получить одиночный ипмульс определенной длины. Это я просто нарисовал тригер + ограничитель длительности импульса, можно сказать - одновибратор по кнопке. В самом задании про переодичность не увидел, только в посл. коментарии... Вообще это можно реализовать на мелкой логике (счетчик), но тут зависит все от конкретного алгоритма, насколькоточен интервал д.б., если нужно то 4 сек, то 1 сек, то можно так: счетчик считает до 4 сек - схема выдает импульс, потом он считает до 1 сек - схема выдает тот же импульс - так? т.е. после каждого импульса изменяется число сброса счетчика. не тут нужно наверное как минимум 3 микрухи.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 08:01:42
Demiurg
Конечные автоматы. Автоматное программирование. Цикл статей. Конкретно по вопросу часть 8.
Смысл следующий. Модульность программ. Нужно разбивать процессы на подзадачи. Дробить процессы. Чтобы добиться псевдопараллельности. Каждый модуль за итерацию основного цикла выполняет часть кода. Никаких долгих циклов. Процессы дробятся условиями, флагами, состояниями конечных автоматов.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 08:09:10
sTRog
А попроще можно в двух словах? В чем ошибка то, почему МК сам переключается?

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 08:22:49
Demiurg
В двух словах никак не получится. Тут много моментов. Вам попросту не хватает знаний и опыта.

1 - Дребезг контактов. Ищите информацию самостоятельно в поисковиках.
2 - При выполнении задержек delay МК выполняет только эту задачу. Грубо, он вешается на время выполнения задержек. Поставили 100 мс, все это время МК выполняет только эту задачу. Решается это только программными таймерами.

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

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 09:46:30
shindax
Demiurg писал(а):...Так что берите паузу и читайте цикл статей с самого начала и внимательно.
Ну или сделать на Arduino. Так, глядишь, весь мусор отвалится и каждый, наконец, займется своим делом. :)

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 09:47:51
Demiurg
shindax писал(а):
Demiurg писал(а):...Так что берите паузу и читайте цикл статей с самого начала и внимательно.
Ну или сделать на Arduino. Так, глядишь, весь мусор и отвалится. :)
ардуина не панацея. там такие же задержки delay.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 10:42:14
Morroc
Не панацея против такого :)) Совет был с некоторой долей сарказма, IMHO.
На ардуине как то так можно, можно и без ардуины точно так же

...
if (<условие включения чего то на ноге 2 с учетом дребезга и т.п.>) {
digitalWrite(2, HIGH);
pin_2_TimerOff = millis() + 4000; // заводим будильник на 4 сек
}
...
if ((digitalRead(2)==HIGH)&&(pin_2_TimerOff > millis()) digitalWrite(2, LOW); // выключаем через 4 сек
...

ну и подумать что делать при переполнении таймера если это критично.
Те самые конечные автоматы про которые советовали почитать в общем.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 12:24:58
sTRog
Demiurg писал(а):В двух словах никак не получится. Тут много моментов. Вам попросту не хватает знаний и опыта.

1 - Дребезг контактов. Ищите информацию самостоятельно в поисковиках.
2 - При выполнении задержек delay МК выполняет только эту задачу. Грубо, он вешается на время выполнения задержек. Поставили 100 мс, все это время МК выполняет только эту задачу. Решается это только программными таймерами.

Так что берите паузу и читайте цикл статей с самого начала и внимательно.
Дребезг у странил. Я говорил, что мк переключается сам, даже без нажатия кнопки, хотя резистором ножка (которая отвечает за кнопку) притянута к массе. Так что дребезг тут не причем.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 12:30:17
Demiurg
WatchDog включен? Если включен, то какое время сброса сторожевого таймера и какие у вас задержки? Во время задержек в цикле delay МК больше ничего не делает, также как и не выполняет команду wdr.

Re: Переключение режима кнопкой.

Добавлено: Вс окт 23, 2016 14:14:05
sTRog
Это все замечательно, но никто так и не ответил, почему переключаются режимиы, если на ножку, которую програмно подключаю кнопку - на самом деле ничего не вешаю, только к массе резистором заземляю.