roboforum.ru

Технический форум по робототехнике.

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

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

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:

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

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

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


Перемещаю в вопросы новичков.

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

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

avr123.nm.ru » 08 авг 2010, 16:21

в while (1) прога навечно будет застревать.

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

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

avr123.nm.ru » 08 авг 2010, 16:51

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

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

Кнопкой лучше менять паузы в мигании, можно это делать и в функции.

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

alek4322 » 08 авг 2010, 17:29

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

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

avr123.nm.ru » 08 авг 2010, 19:11

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

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


Google пришел к выводу что терпения мало у большинства. Текст не читаю, смотрят только картинки, комиксы, видео.

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

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

Сергей » 08 авг 2010, 21:57

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

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

alek4322 » 08 авг 2010, 22:22

Согласен нужно лучше знать С

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

Дмитрий К. » 08 авг 2010, 22:27

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

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

avr123.nm.ru » 08 авг 2010, 22:58

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


Что значит:

Код: Выделить всёРазвернуть
while (1)
{
}


?

Ответ есть и на страничке "Язык Си для микроконтроллеров".

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

Radist » 09 авг 2010, 08:17

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

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

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

yak-40 » 09 авг 2010, 08:33

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

И правильно не идёт, она уходит в бесконечный цикл while (1)


Rambler\'s Top100 Mail.ru counter