Помогите разобраться с простенькой задачей про кнопки

Раздел создан специально для людей которым интересна робототехника, но в силу разных причин они не знают с чего начать.
Задавайте ваши вопросы, какими бы простыми они не казались, постоянные посетители форума постараются ответить на них по мере своих сил.
Робот своими руками. Самодельный робот.

Помогите разобраться с простенькой задачей про кнопки

Сообщение alek4322 » 08 авг 2010, 14:22

Учусь программировать микроконтроллеры AVR, Столкнулся с проблеммой, не могу запрограммировать контроллер на работу от одной кнопки. Задача такая, одной кнопкой на любом входе контроллера по очереди переключать две функции мигания светодиода на любом одном выходе, функции почти одинаковы по алгоритму работы, просто одна функция обеспечивает более быстрое мигание светодиода, чем другая, программирую на С++

хочу запрограммировать контроллер так чтобы он выполнял разные функции в зависимости от нажатия кнопки, но кнопки одной, а не нескольких. это примерно выглядело бы по анологии работы ёлочных герлянд, где при нажатии одной кнопки поочерёдно меняются разные мерцания светодиодов. в приведённой выше мной программе я создал две функции мерцания двух разных светодиодов красного и зелёного подключённых к ножкам Pc0 и Pc1 микроконтроллера Atmega 8 сконфегурированными на выход, функции создал почти одинаковыми только с разной частотой мерцания. хочу одной кнопкой подключённой к ножке Pb5 сконфегурированной на вход, поочерёдно менять функции, нажал кнопку мерцает один светодиод, отжал кнопку ничего не меняется продолжает мерцать тот же светодиод так же как и мерцал, нажал второй раз кнопку мерцает уже другой светодиод с другой частотой, отжал кнопку ничего не меняется продолжает мерцать тот же светодиод так же как и мерцал, нажал ещё раз (третий раз) мерцает опять первый светодиод также как и при нажатии первый раз


#include <delay.h>


int time_1 ();
int time_2 ();

while (1)
{
while (PINB.5==1)
{PORTC.0=0;}

while (PINB.5==0)
{time_2 ();}

while (PINB.0==1)
{time_2 ();}

while (PINB.0==0)
{time_1 ();}

while (PINB.0==1)
{time_1 ();}
}
}

int time_1 ()
{
while (1)
{
// Place your code here
PORTC.1=1; //зажигаем светодиод
delay_ms(200); //пусть горит 200 милисекунд
PORTC.1=0; //гасим светодиод
delay_ms(200); //теперь не горит 200 милисекунд
}
return 0;
}

int time_2 ()
{
while (1)
{
// Place your code here
PORTC.0=1; //зажигаем светодиод
delay_ms(30); //пусть горит 30 милисекунд
PORTC.0=0; //гасим светодиод
delay_ms(30); //теперь не горит 30 милисекунд
}
return 0;
}
:sorry:
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение -= Александр =- » 08 авг 2010, 14:36

1)А где у тебя функция main?
2)while (1) после своего запуска уже никогда не остановится - и никакие кнопки контроллер не проверит!


Перемещаю в вопросы новичков.
Ниндзя - круче всех. Они умеют ходить по воде, делить на ноль и угадывать шаффл в АйПоде.
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3678
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C/C++, Python, asm
ФИО: Курмис Александр Андреевич

Re: Помгите разобраться с простенькой задчей

Сообщение alek4322 » 08 авг 2010, 14:44

Извените не правильно скопировал функция main присутствует

*****************************************************
This program was produced by the
CodeWizardAVR V2.04.8 Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 08.08.2010
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

int time_1 ();
int time_2 ();
// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0x3F;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State6=T State5=T State4=T State3=T State2=T State1=0 State0=0
PORTC=0x00;
DDRC=0x03;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
{
if (PINB.5==0) { // ждем нажатия
delay_ms(50); // антидребезг
if (PINB.5==0) time_2 (); // если все норм, включаем функцию time_2 ()
else continue;
}
else continue;

while(PINB.5==0) {}; // ждем отпускания кнопки
delay_ms(50); // антидребезг
if (PINB.5==0) time_2 (); // если все норм, включаем функцию time_2 ()
else continue;

if (PINB.5==0) { // ждем нажатия
delay_ms(50); // антидребезг
if (PINB.5==0) time_1 (); // если все норм, включаем функцию time_2 ()
else continue;
};
}
}

int time_1 ()
{
while (1)
{
// Place your code here
PORTC.1=1; //зажигаем светодиод
delay_ms(200); //пусть горит 500 милисекунд
PORTC.1=0; //гасим светодиод
delay_ms(200); //теперь не горит 500 милисекунд
}
return 0;
}

int time_2 ()
{
while (1)
{
// Place your code here
PORTC.0=1; //зажигаем светодиод
delay_ms(30); //пусть горит 500 милисекунд
PORTC.0=0; //гасим светодиод
delay_ms(30); //теперь не горит 500 милисекунд
}
return 0;
}
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение avr123.nm.ru » 08 авг 2010, 16:21

в while (1) прога навечно будет застревать.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Помгите разобраться с простенькой задчей

Сообщение alek4322 » 08 авг 2010, 16:35

Дело в том, что я как уже только не пробовал и с while и без и с помощью операций ветвления, не получается осуществить алгоритм и всё тут.

*****************************************************
This program was produced by the
CodeWizardAVR V2.04.8 Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 08.08.2010
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

int time_1 ();
int time_2 ();
// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0x3F;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State6=T State5=T State4=T State3=T State2=T State1=0 State0=0
PORTC=0x00;
DDRC=0x03;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;


while (PINB.5==1)
{PORTC.0=0;}

while (PINB.5==0)
{time_2 ();}

while (PINB.0==1)
{time_2 ();}

while (PINB.0==0)
{time_1 ();}

while (PINB.0==1)
{time_1 ();}
}

int time_1 ()
{
while (1)
{
// Place your code here
PORTC.1=1; //зажигаем светодиод
delay_ms(200); //пусть горит 200 милисекунд
PORTC.1=0; //гасим светодиод
delay_ms(200); //теперь не горит 200 милисекунд
}
return 0;
}

int time_2 ()
{
while (1)
{
// Place your code here
PORTC.0=1; //зажигаем светодиод
delay_ms(30); //пусть горит 30 милисекунд
PORTC.0=0; //гасим светодиод
delay_ms(30); //теперь не горит 30 милисекунд
}
return 0;
}
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение avr123.nm.ru » 08 авг 2010, 16:51

Есть тег для кода - code

Возможно вам будет интересно "Язык Си для микроконтроллеров" - http://proavr.narod.ru/05.htm

Кнопкой лучше менять паузы в мигании, можно это делать и в функции.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Помгите разобраться с простенькой задчей

Сообщение alek4322 » 08 авг 2010, 17:29

Я сталкивался с этим сайтом, ну не знаю может я такой слишком начинающий, не понятно составлено обучение, во первых куча не нужной и не понятной рекламы по продаже, во вторых пол часа читал его с начала естественно и понял что всё это время мне объясняли о том как важно дочитать этот курс до конца с выполнением всех примеров иногда выли вставки по теме программирования контроллеров, но тут же прерывались опять рекламой, и потом сразу же начался разговор о прерываниях, я понимаю что это важно и что с их помощью можно многое осуществить, но мне интересно можно ли осуществить алгоритм с помощью обычных циклических конструкций или операций ветвления на языке С, задачка выглядит вроде бы не сложной а я так и не смог её осуществить и в общем может у меня мало терпения и я хочу узнать побыстрей от других, может кто осуществлял такой алгоритм, наверное мне стоит ещё раз обратить внимание на этот сайт и поучить его побольше.
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение avr123.nm.ru » 08 авг 2010, 19:11

К каждой строчке кода напишите комментарии что она делает - может прояснится.

alek4322 писал(а):у меня мало терпения


Google пришел к выводу что терпения мало у большинства. Текст не читаю, смотрят только картинки, комиксы, видео.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Помгите разобраться с простенькой задчей

Сообщение alek4322 » 08 авг 2010, 21:07

Я согласен с тем что кнопкой можно менять паузы между включением и выключением светодиода, но хочу научиться переключать именно разные функции причём поочерёдным нажатием одной кнопки.
*****************************************************
This program was produced by the
CodeWizardAVR V2.04.8 Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 08.08.2010
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

int time_1 ();
int time_2 ();
// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0x3F;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State6=T State5=T State4=T State3=T State2=T State1=0 State0=0
PORTC=0x00;
DDRC=0x03;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;


while (PINB.5==1)// Пока на пятом выводе регистра портов В логическая единица, то есть она ещё ни разу не была нажата, отжата в начальном положении.
{PORTC.0=0;}// Установить на первом выводе регистра портов С логический ноль, то есть светодиод не горит.

while (PINB.5==0)// Как только на пятом выводе регистра портов В появился логический ноль, то есть нажали кнопку.
{time_2 ();}// Запустили вторую функцию мигания светодиода

Дальше этого места программа не идёт

while (PINB.0==1)// После того как на пятом выводе регистра портов В появилась логическая единица, то есть отжали кнопку.
{time_2 ();}// Оставляем включённой вторую функцию, то есть оставляем всё без изменения.

Или этого места
В общем при первом нажатии кнопки вызывает вторую функцию и всё программа становится, дальше хоть нажимай, хоть не нажимай ни чего не изменится, будет выполняться вторая функция и всё.
while (PINB.0==0)// Как только на пятом выводе регистра портов В появился логический ноль, то есть нажали второй раз кнопку.
{time_1 ();}// Запустили первую функцию мигания светодиода

while (PINB.0==1)// После того как на пятом выводе регистра портов В появилась логическая единица, то есть отжали второй раз кнопку.
{time_1 ();}// Оставляем включённой первую функцию, то есть оставляем всё без изменения.
}

int time_1 ()
{
while (1)
{
// Place your code here
PORTC.1=1; //зажигаем светодиод
delay_ms(200); //пусть горит 200 милисекунд
PORTC.1=0; //гасим светодиод
delay_ms(200); //теперь не горит 200 милисекунд
}
return 0;
}

int time_2 ()
{
while (1)
{
// Place your code here
PORTC.0=1; //зажигаем светодиод
delay_ms(30); //пусть горит 30 милисекунд
PORTC.0=0; //гасим светодиод
delay_ms(30); //теперь не горит 30 милисекунд
}
return 0;
}
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение Сергей » 08 авг 2010, 21:57

Для того, чтобы программировать микроконтроллеры на языке С необходимо научиться писать и на обычном компьютере. Возьми книжку по Си, читай и изучай примеры. Ясень пень, если ты будет пытаться зажечь светодиод и при этом не разбираться в программировании на Си - то возникнут проблемы, которые друг друга задевают.
Сергей
 
Сообщения: 3744
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Помгите разобраться с простенькой задчей

Сообщение alek4322 » 08 авг 2010, 22:22

Согласен нужно лучше знать С
alek4322
 
Сообщения: 11
Зарегистрирован: 08 авг 2010, 13:51

Re: Помгите разобраться с простенькой задчей

Сообщение Дмитрий К. » 08 авг 2010, 22:27

Имхо нужно ясно представить алгоритм работы программы. Из прочитанного я не понял, что требуется.
Дмитрий К.
 
Сообщения: 76
Зарегистрирован: 01 июл 2010, 20:58
Откуда: Санкт-Петербург
прог. языки: Си
ФИО: Дмитрий

Re: Помгите разобраться с простенькой задчей

Сообщение avr123.nm.ru » 08 авг 2010, 22:58

alek4322 писал(а): поочерёдным нажатием одной кнопки.


Что значит:

Код: Выделить всё
while (1)
{
}


?

Ответ есть и на страничке "Язык Си для микроконтроллеров".
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Помгите разобраться с простенькой задчей

Сообщение Radist » 09 авг 2010, 08:17

Бегло посмотрел код. В одном месте кнопка подключена в пятому биту, в другом - к нулевому. Может опечатка? И все заработает? И антидребезг вы делали как то странно. Как делают нормальный антидребезг:
-увидеть факт нажатия
- пауза
- повторно увидеть факт нажатия
- если второй раз нажато - выполнить действие, иначе нет
- цикл ожидания ОТЖАТИЯ (иначе действие будет выполнено N раз)

Вы хотите по одной кнопке по очереди переключать два события (так я понял вашу задачу). Для этого нужна переменная-флажок (в вашем случае достаточно битовой переменной). Кнопка инвертирует переменную (было тру - стало фолс, было фолс - стало тру), а в основном цикле проверяется эта переменная и выполняется соответствующее действие.
Аватара пользователя
Radist
 
Сообщения: 2253
Зарегистрирован: 01 июл 2009, 08:59
Откуда: Екатеринбург
прог. языки: асемблер AVR

Re: Помгите разобраться с простенькой задчей

Сообщение yak-40 » 09 авг 2010, 08:33

alek4322 писал(а):Дальше этого места программа не идёт

И правильно не идёт, она уходит в бесконечный цикл while (1)
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!
Аватара пользователя
yak-40
 
Сообщения: 3037
Зарегистрирован: 23 окт 2007, 22:03
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец

След.

Вернуться в Новичкам или основы основ роботостроения.

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4