роботы робототехника микроконтроллеры


 Страниц (6): « 1 2 3 4 [5] 6 »   

> Без описания
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



Я тут призадумался...
А можно сделать так чтобы при нажатии кнопки менялась пауза (при этом работая с делеем без таймера ), дело в том что если в скобки _deley_ms() ставишь переменную, то компилятор начинает материться, если задаешь значение например U через дефаин то все работает, но менять значения U уже нельзя Замешательство . Значит нужно изучать таймеры??
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



у функции _delay_ms() есть один ядреный недостаток: процессор крутится в этой функции и никак не может узнать, что-же там с кнопками.
итак рекомендую:
1) разобрать прерывания: для начала повесить прерывание на кнопку, чтобы обработчик заставил переключить светодиод, при этом в основной программе главный цикл пустой.
2) разобраться с дребезгом, чтобы одно нажатие было одним нажатием.
3) завести таймер: переключать светодиод по прерыванию от таймера.

для целевого количества миганий, для подсчета количества уже мигнутых ... нужно позаводить глобальных переменных.
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



хорошо, на счет делея вроде понял, но а что с этой проблемой делать
Andrey 2004 пишет:
Проблема в том что у меня или получается бесконечный цикл (при первом нажатии кнопки цикл замыкается и не реагирует на дальнейшие нажатия);
Или получается сделать все это при помощи For где я действительно могу менять переменную i
,но при этом светодиод мигает до тех пор пока не достигнет значения переменной i а затем гаснет до следующего нажатия кнопки.

Здесь я не знаю о чем и думать, вроде все операторы более менее знаю, а подходящего варианта не нашел . Замешательство
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



тут надо конкретно вашу программу смотреть - собственно даже не операторы, а алгоритм.
и да, теперь вы переходите на следующий уровень: от написания операторов к программированию (переход от быдлокодера к программисту).


подозреваю, что в бесконечном цикле крутится по причине того, что внутри цикла в принципе не опрашивает кнопку.
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



CODE:
#define F_CPU 8000000UL //16MHz
#include <avr/io.h>
#include <util/delay.h>
#define l 10
volatile unsigned char i;
volatile unsigned char p;
int main(void) {
DDRB = 0xFF;
PORTB = 0x00;
DDRD=0x00;
PORTD=0xFF;
i=0;
while(1)
{




if (PIND & (1<<1))
{

_delay_ms(5);

if (PIND & (1<<1))
{
while (PIND & (1<<1)) {}
i++;
_delay_ms(10);

}
}


for(int p=0;p<i;p++)
{
PORTB=0b00000010;
_delay_ms(50);
PORTB=0b00000000;
_delay_ms(50);
}




}








}

Вот код от которого я "пляшу"
(Добавление)
сейчас скину свои неудачные варианты
(Добавление)
В принципе все мои попытки сводятся к одному соединить фор который может считать кол во
миганий и ваил который зацикливает что либо.Вот один из моих "кодов":
CODE:
#define F_CPU 8000000UL //16MHz
#include <avr/io.h>
#include <util/delay.h>
#define l 10
volatile unsigned char i;
volatile unsigned char p;
int main(void) {
DDRB = 0xFF;
PORTB = 0x00;
DDRD=0x00;
PORTD=0xFF;
i=0;
while(1)
{
if (PIND & (1<<1))
{

_delay_ms(5);

if (PIND & (1<<1))
{
while (PIND & (1<<1)) {}
i++;
_delay_ms(10);

}
}

while (PIND & (1<<1))
{
for (p=0;p<i;p++)
{

PORTB=0b00000010;
_delay_ms(50);
PORTB=0b00000000;
_delay_ms(50);
if (PIND & (1<<1))
{
i++;
}
_delay_ms(200);
}
}
}
}
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



В первом случае у вас происходит проверка нажатия кнопки, после отпускания фиксируется факт нажатия и только тогда программа продолжает работать дальше.
Есть еще нюанс: в процессе мигания светодиодом (в цикле p=0;p<i;p++) проверка кнопки не происходит, то есть нужно нажать и держать пока не промигается.

Во втором случае чуть хуже: вы проверяете нажатие кнопки, после отпускания фиксируется факт нажатия и только тогда программа продолжает работать дальше. (пока как в первом случае)
А дальше, через 10 мс, в случае нажатой кнопки вы начинаете мигать, иначе снова проверять нажатие фиксировать. В общем чтобы начать мигать надо отпустить кнопку и за 10 мс успеть обратно нажать. Рекомендую перевести эту задачу на другую кнопку.
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



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

(Отредактировано автором: 20 Марта, 2019 - 19:34:14)

 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



Все сделал программу при помощи прерывания вот что получилось:
CODE:
#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile unsigned char i;
volatile unsigned char p;

ISR(INT1_vect)
{
i++;
_delay_ms(30);
}
int main(void)
{
DDRB |=(1<<1);
PORTB &=~(1<<1);
DDRD &=~(1<<3);
PORTD |=(1<<3);
i=0;
GICR |=(1<<7);// Разрешаем прерывание INT1
MCUCR =0b00000010;// Генерация сигнала при низком уровне на ножке PD3

sei();//Разрешить прерывания
while(1)
{
_delay_ms(50);
for(p=0;p<i;p++)
{
PORTB|=(1<<1);
_delay_ms(15);
PORTB &=~(1<<1);
_delay_ms(15);
}
}

}

Что смутило, у меня при попадании в "прерывание" процессор не просто "проходит" по коду
единожды, а выполняет этот код в течении некоторого времени. Таким образом, когда я в цикл прерывания писал просто " i++;" без задержки, процессор при первом нажатии кнопки PD3 присваивал переменной "i" не "1",а "41".
Так и должно быть??
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



Так и должно быть??
Это и есть дребезг контактов.
41 раз переколбасилась кнопка (контачит-не контачит) -> прерывание 41 раз вызвалось и отработало.
задержка и есть решение этой проблемы, на мой взгляд оптимальное, только я еще после задержки перепроверяю, что юзер всё еще держит кнопку, а не это помеха проскочила.
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



Мда... Про то что здесь может быть дребезг я и забыл.
Сейчас сижу балуюсь с внешними прерываниями, и вдруг понимаю что мне их не хватает,
в смысле не "их" а их количества Замешательство . А есть помимо INT0 и INT1 другие виды внешних прерываний???
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



В обработчике можно проводить анализ на тему "что случилось", если не хватает именно ног с прерываниями - тут сложнее.
Если собираетесь просто много кнопок насобирать, то их можно опрашивать по прерыванию от таймера, на 10 ног можно навесить 25 кнопок (5 строк-5столбцов).
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



Да, пока не хватает именно ног с прерываниями. Можете объяснить как проводить этот анализ?
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



если именно ног не хватает - не поможет.
Анализ - да всё просто (у пиков 16 - вообще одно прерывание на все случаи жизни) попадаем в обработчик и последовательно осматриваем регистры модулей, ищем кто вызвал.
С кнопками - примерно так:
сработало прерывание на таймер (пусть каждые 100 мс) - проверяем, что там с портом, если нажата кнопка - обрабатываем нажатие.
Если нужно обрабатывать не кнопку - тут сложнее, всё зависит от срочности реакции.
 
 Top
Andrey 2004 Post Id



Капитан


Сообщений всего: 46
Дата рег-ции: Дек. 2018  



Predator пишет:
С кнопками - примерно так:
сработало прерывание на таймер (пусть каждые 100 мс) - проверяем, что там с портом, если нажата кнопка -

Спасибо, понял, наверно так и сделаю.
(Добавление)
Вот сделал программу для семисегментного индикатора:
CODE:
//-----------------------------***Семисигментный индикатор c массивом***-----------------------------//

# define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define razriad PORTC
#define chislo PORTB
unsigned int razr1 = 0, razr2 = 0, razr3 = 0, razr4 = 0;
unsigned char LOL;
//----------------------------------------------------------------------------------------//
ISR(TIMER0_OVF_vect)
{
if (LOL == 1) {razriad = 0b00000001; chislo = chisla [razr1];}
if (LOL == 2) {razriad = 0b00000010; chislo = chisla [razr2];}
if (LOL == 3) {razriad = 0b00000100; chislo = chisla [razr3];}
if (LOL == 4) {razriad = 0b00001000; chislo = chisla [razr4];}
LOL++;
if( LOL > 4 ) LOL = 0;
}

int chisla [10]=
{
0b00111111,//0
0b00000110,//1
0b01011011,//2
0b01001111,//3
0b01100110,//4
0b01101101,//5
0b01111101,//6
0b00000111,//7
0b01111111,//8
0b01101111,//9
};

void vse_chislo (unsigned int razbivka_chisla)
{
razr1 = razbivka_chisla/1000;//тысячи
razr2 = razbivka_chisla%1000/100;//сотни
razr3 = razbivka_chisla%100/10;//десятки
razr4 = razbivka_chisla%10;//еденицы
}
int main(void)
{
DDRC=0xFF;
PORTC=0x00;
DDRB=0xFF;
PORTB=0x00;
TCCR0|=(1<<1); TCCR0&= ~ ((1<<0)|(1<<2));
TIMSK|=(1<<0);
TCNT0 = 0;
sei();
//----------------------------------------------------------------------------------------//
razriad=0b00000001;
chislo = 0b00111111;

while(1)
{
vse_chislo (1987);
}

}

Но при компиляции выдает ошибку:

Error 'chisla' undeclared (first use in this function)
При двойном щелчке кидает вот сюда:
CODE:
if (LOL == 1) {razriad = 0b00000001; chislo = (сюда)chisla [razr1];}

Что не так ??
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



CODE:

int chisla [10]=
{
0b00111111,//0
0b00000110,//1
0b01011011,//2
0b01001111,//3
0b01100110,//4
0b01101101,//5
0b01111101,//6
0b00000111,//7
0b01111111,//8
0b01101111,//9
};

перенесите выше, чем
CODE:

ISR(TIMER0_OVF_vect)
{
if (LOL == 1) {razriad = 0b00000001; chislo = chisla [razr1];}
if (LOL == 2) {razriad = 0b00000010; chislo = chisla [razr2];}
if (LOL == 3) {razriad = 0b00000100; chislo = chisla [razr3];}
if (LOL == 4) {razriad = 0b00001000; chislo = chisla [razr4];}
LOL++;
if( LOL > 4 ) LOL = 0;
}

иначе вы сперва используете, потом объявляете. Некоторые компиляторы умеют такое разруливать, но это скорее исключение.
 
 Top
Страниц (6): « 1 2 3 4 [5] 6 »
« С чего начать? »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown
  Яндекс.Метрика   Рейтинг@Mail.ru