Опрос кнопок микроконтроллером
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Помогите опросить кнопку
А причём тут "мегапроект" ? У Вас проблема с опросом кнопок, значит Вам сюда. Зачем темы плодить ?
Re: Помогите опросить кнопку
Модератор тебе правильно сказал. Не стоит темы плодить. И стыдится не стоит. Ты же не колупаешь в носу, время от времени выпрашивая у форумчан пару строчек для себя.Zhursat писал(а):А то в этой теме мне стыдно позориться со своим "мегапроектом".
С уважением,
Виктор.
Виктор.
- RGB
- Родился
- Сообщения: 17
- Зарегистрирован: Пт ноя 09, 2012 17:22:37
- Откуда: Москва
- Контактная информация:
Re: Помогите опросить кнопку
Zhursat Используй функцию опроса кнопок в прерывании от таймера
в предоставленном на 4 странице уважаемым пользователем Аlex код опроса кнопок просто велеколепный
За что ему ещё раз отдельное спасибо!
в предоставленном на 4 странице уважаемым пользователем Аlex код опроса кнопок просто велеколепный
За что ему ещё раз отдельное спасибо!
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Помогите опросить кнопку
Правильно как раз в динамической индикации уже используются прерывания таймера, вписываем в существующий код опрос кнопок и поехали!
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Тут вот какое дело.... Убрал я из программы все, и оставил только работу с кнопками, как советовали.
Вот код:
{
if (PINB.0==0)
{
delay_ms(50);
if (PINB.0==0)
{
if (set_temp<90) set_temp++;
};
};
if (PINB.1==0)
{
delay_ms(50);
if (PINB.1==0)
{
if (set_temp>40) set_temp--;
};
};
indication=set_temp;
recoding();
};
}
И что вы думаете? Нифига они не пашут. Жму на них жму - а на индикаторе "00"
Такое впечатление, что программа не знает, что это за переменная set_temp и что с ней нужно делать.
Напомню, она у меня обьявлена вот так eeprom int set_temp=50 тоесть по идее она должна храниться в ЕЕПРОМ и сохранять свое значение даже при выключении схемы (ну или если электричество вырубится). Или я как то неправильно ее инициализирую? Но КодВижн вроде не ругается..... Компилит красиво.
Вот код:
Спойлер
while (1){
if (PINB.0==0)
{
delay_ms(50);
if (PINB.0==0)
{
if (set_temp<90) set_temp++;
};
};
if (PINB.1==0)
{
delay_ms(50);
if (PINB.1==0)
{
if (set_temp>40) set_temp--;
};
};
indication=set_temp;
recoding();
};
}
И что вы думаете? Нифига они не пашут. Жму на них жму - а на индикаторе "00"
Такое впечатление, что программа не знает, что это за переменная set_temp и что с ней нужно делать.
Напомню, она у меня обьявлена вот так eeprom int set_temp=50 тоесть по идее она должна храниться в ЕЕПРОМ и сохранять свое значение даже при выключении схемы (ну или если электричество вырубится). Или я как то неправильно ее инициализирую? Но КодВижн вроде не ругается..... Компилит красиво.
- U235
- Встал на лапы
- Сообщения: 135
- Зарегистрирован: Вт фев 21, 2012 20:42:26
- Откуда: Санкт-Петербург, Россия, Земля
Re: Помогите опросить кнопку
Zhursat писал(а):Такое впечатление, что программа не знает, что это за переменная set_temp и что с ней нужно делать.
С этой переменной в программе всё нормально, что бы убедиться в этом достаточно глянуть на ассемблерный листинг. А вот переменную indication функция main хранит в регистре, компилятор так оптимизирует программу. И поскольку выполнение функции никогда не завершается, в регистре все изменения и остаются. Что бы избежать такое, нужно объявить переменную как volatile.
Код: Выделить всё
volatile unsigned int indication;Тем самым Вы сообщите, что переменная может "внезапно" измениться и к ней нельзя применять оптимизацию.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Помогите опросить кнопку
Вообще-то, CVAVR всегда было пофиг на volatile. Чтоб сказать где проблема нужно увидеть весь код, желательно полный проект, а не огрызок за которым скрывается невесть что..
И еще, почему кнопка на PB0 проверяется на уровень 0, на на PB1 - на уровень 1? Подтянуты по разному что ли?
И еще, почему кнопка на PB0 проверяется на уровень 0, на на PB1 - на уровень 1? Подтянуты по разному что ли?
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Goodefine писал(а):Вообще-то, CVAVR всегда было пофиг на volatile. Чтоб сказать где проблема нужно увидеть весь код, желательно полный проект, а не огрызок за которым скрывается невесть что..
И еще, почему кнопка на PB0 проверяется на уровень 0, на на PB1 - на уровень 1? Подтянуты по разному что ли?
Извините, где вы увидели, что кнопки проверяются на разные уровни? Что PINB.0 что PINB.1 проверяются на 0. И подтянуты они одинаково.
А код полностью вот:
Спойлер
/*****************************************************Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 4,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <1wire.h>
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>
#define digit1 PORTC.1 //анод первой цифры
#define digit2 PORTC.2 //анод второй цифры
eeprom int set_temp=50; //переменная с опорной температурой
flash char digits[] = { //создаём массив с цифрами
0b11000000, //0
0b11111001, //1
0b10100100, //2
0b10110000, //3
0b10011001, //4
0b10010010, //5
0b10000010, //6
0b11111000, //7
0b10000000, //8
0b10010000, //9
0b10001001, //Буква Н
0b11111111 //пустота
};
//*******
char digit_out[2], cur_dig; //переменные для работы с LED
volatile unsigned int indication; //переменная для хранения чисел
void recoding(void) { //функция для перекодировки из hex в dec
if (indication<100) { //начинаем преобразование если число < 100 так как 2-х разрядный LED
digit_out[0]=indication/10; //Делим на 10 остаток в масив 1-разряд
digit_out[1]=indication%10; //Делим на 10 число в масив 2-разряд
} //*******
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD=0xFF; //чтобы предотвратить эффект “тени” на соседних индикаторах
switch (cur_dig){
case 0:{digit1=1; digit2=0; break;}; //подаём питание на разряд 2
case 1:{digit2=1; digit1=0; break;}; //подаём питание на разряд 1
}
PORTD=digits[digit_out[cur_dig]]; //выводим с каждым срабатыванием таймера число с мссива в порт В, но не для всех разрядов сразу
cur_dig++; //с каждым срабатыванием таймера, увеличиваем
//переменную cur_dig на 1
if(cur_dig==2) cur_dig=0; //если cur_dig = 2 обнуляем
}
// Declare your global variables here
unsigned char devices;
void main(void)
{
// Declare your local variables here
PORTB=0x03;
DDRB=0x0C;
PORTC=0x00;
DDRC=0x06;
PORTD=0x00;
DDRD=0x7F;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
TCCR0=0x03;
TCNT0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// инициализация 1 Wire
devices=w1_init();
#asm("sei")
while (1)
{
if (PINB.0==0)
{
delay_ms(50);
if (PINB.0==0)
{
if (set_temp<99) set_temp++;
};
};
if (PINB.1==0)
{
delay_ms(50);
if (PINB.1==0)
{
if (set_temp>40) set_temp--;
};
};
indication=set_temp;
recoding();
};
}
Кстати, вот что вырулил: если в теле программы присвоить переменной set_temp какое нибудь значение - тогда все красиво работает (инкремент-декремент, индикация - все пашет). Но в таком случае после включения-выключения питания в этой переменной будет присвоеное значение, зачем тогда ЕЕПРОМ использовать. Все ведь задумывалось так, чтобы эти данные было "энергонезависимы".
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Помогите опросить кнопку
И правда, чего то глаз замылился ))) Насчет присваивания - все логично, пока не присвоите, там мусор, точнее 0xFF, в пределы не попадает и не инкрементируется/декрементируется. Что касается повторной записи при включении, скорее всего, при компиляции создается файл инициализации еепром (*.eep) - начальными значениями, а в коде это не прописывается. Его нужно зашивать отдельно от прошивки один раз. Точнее не скажу, с кодевижном давно не работал, а когда работал то квалификаторами eeprom не пользовался - делал по другому..
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Все таки победил я кнопки!!!! Для перестраховки сделал так:
Опрос сделал вот так
Теперь протеус рисует и опорную температуру с задержкой на отображение 2 сек и если не нажаты кнопки в течении 2 сек - начинает показывать температуру текущую, которая "пришла" с термодатчика. Спасибо всем, кто не остался в стороне, все таки когда мозг в тупике - даже вроде бы незначительный совет может направить на путь истинный. Буду теперь заниматься силовой стороной автоматики: когда что включить, когда что выключить.
Кстати, попутно вопрос, правда не в тему: КТ315 транзистора хватит для управления релюшками РЭС 34, или нужно помощнее ставить???
Код: Выделить всё
if ((set_temp<40)||(set_temp>100)) {set_temp=40;};Опрос сделал вот так
Код: Выделить всё
while (1)
{
if (PINB.0==0)
{
delay_ms(50);
if (PINB.0==0)
{
if (set_temp<99) set_temp++;
delay_ms(2000);
};
};
if (PINB.1==0)
{
delay_ms(50);
if (PINB.1==0)
{
if (set_temp>40) set_temp--;
delay_ms(2000);
};
};
if ((PINB.0==0) || (PINB.1==0)) {indication=set_temp;} else {indication=ds18b20_temperature(0);};
recoding();
};
}Теперь протеус рисует и опорную температуру с задержкой на отображение 2 сек и если не нажаты кнопки в течении 2 сек - начинает показывать температуру текущую, которая "пришла" с термодатчика. Спасибо всем, кто не остался в стороне, все таки когда мозг в тупике - даже вроде бы незначительный совет может направить на путь истинный. Буду теперь заниматься силовой стороной автоматики: когда что включить, когда что выключить.
Кстати, попутно вопрос, правда не в тему: КТ315 транзистора хватит для управления релюшками РЭС 34, или нужно помощнее ставить???
- U235
- Встал на лапы
- Сообщения: 135
- Зарегистрирован: Вт фев 21, 2012 20:42:26
- Откуда: Санкт-Петербург, Россия, Земля
Re: Помогите опросить кнопку
Заработало - это хорошо. То что Вы назвали перестраховкой - это повышение надёжности программы.
Но работу с кнопками я бы посоветовал продолжить. В нынешнем варианте что бы изменить температуру на 10 градусов придётся потратить больше 20 секунд, а это не очень удобно.
Но работу с кнопками я бы посоветовал продолжить. В нынешнем варианте что бы изменить температуру на 10 градусов придётся потратить больше 20 секунд, а это не очень удобно.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Помогите опросить кнопку
Zhursat писал(а):Все таки победил я кнопки!!!! Для перестраховки сделал так:Код: Выделить всё
if ((set_temp<40)||(set_temp>100)) {set_temp=40;};
В принципе, говоря победил, надо все таки уловить суть проблемы, и как с ней бороться. В первом вашем варианте тоже все было правильно, единственное что вы не сделали - это не записали в контроллер файл с именем проекта и расширением eep, находящийся в одной папке с hex-ом. Поскольку при инициализации еепром переменных, а именно
Код: Выделить всё
eeprom int set_temp=50; //переменная с опорной температурой
компилятор не прописывает это в хексе а просто создает вышеуказанный фал. Это сделано специально чтобы можно было инициализировать eeprom переменные без лишней головной боли. Если переменная меняется в коде программы, то понятное дело, в хексе это есть. Впрочем строка
Код: Выделить всё
if ((set_temp<40)||(set_temp>100)) {set_temp=40;};тоже полезна - устанавливает дефолтные значения в случае чего. Но понимать инструментарий нужно...
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Так а я о чем? Я обеими руками "За!".
Вот тут накидал немного "автоматики", и еще уменьшил задержки на индикацию опорной температуры. Неплохо помог мне в этом вот этот сайтик http://www.atmega8.ru/ Это ни в коем случае не реклама, действительно для начинающих, типа меня, самое то.
Вобщем, кто желает посмотреть и покритиковать - во вложении файлы проекта и конечно же протеус
Вот тут накидал немного "автоматики", и еще уменьшил задержки на индикацию опорной температуры. Неплохо помог мне в этом вот этот сайтик http://www.atmega8.ru/ Это ни в коем случае не реклама, действительно для начинающих, типа меня, самое то.
Вобщем, кто желает посмотреть и покритиковать - во вложении файлы проекта и конечно же протеус
- Вложения
-
- _KOTEL_new.rar
- (95.29 КБ) 406 скачиваний
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Помогите опросить кнопку
Первый же вопрос, зачем volatile для indication?
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Выше советовали.... Я если чесно даже не знаю, что это значит. Но работает. Впрочем, работает даже при просто int
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Помогите опросить кнопку
Так U235 сказалПервый же вопрос, зачем volatile для indication?
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Ну не трольте меня
Я уже вычитал, что это такое.... В данном случае использование действительно не оправдано. Просто осталось с прошлых компиляций.....
Я уже вычитал, что это такое.... В данном случае использование действительно не оправдано. Просто осталось с прошлых компиляций.....
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Помогите опросить кнопку
Да всё нормально, не переживайте, это в порядке вещей - Вам посоветовали - Вы сделали.
Видимо, камушек не в Ваш огород был
Видимо, камушек не в Ваш огород был
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Помогите опросить кнопку
Ну и в порядке легкой критики - привыкайте писать вместо
примерно так
Потом не надо будет бегать по всему коду чтоб изменить пределы или переназначить кнопки, да и выглядит понятней.
Код: Выделить всё
if (PINB.0==0)
{
delay_ms(50);
if (PINB.0==0)
{
if (set_temp<99) set_temp++;
delay_ms(500);
};
};
примерно так
Код: Выделить всё
#define BUTTON_UP (!PINB.0)
#define TERM_UP_LIMIT 99
#define DELAY_ANTI_DRB 50
#define DELAY_UP 500
...
if (BUTTON_UP)
{
delay_ms(DELAY_ANTI_DRB);
if (BUTTON_UP)
{
if (set_temp<TERM_UP_LIMIT) set_temp++;
delay_ms(DELAY_UP);
};
};
Потом не надо будет бегать по всему коду чтоб изменить пределы или переназначить кнопки, да и выглядит понятней.
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
-
Zhursat
- Первый раз сказал Мяу!
- Сообщения: 28
- Зарегистрирован: Вт янв 31, 2012 21:09:21
- Откуда: Украина
Re: Помогите опросить кнопку
Вы словно мои мысли прочитали: как раз сидел думал , что нужно поназначать дефайнами то, чем часто пользуешься. Так что критика принимается в полном обьеме. Но есть одно "Но": я уже говорил, что только начинаю знакомство с МК и с языком С в частности. Асм для меня вобще темный лес, а С немного понятней. Поэтому есть желание сразу разобраться во всем (ну или примерно во всем
) без упрощений, чтобы саму логику понять. А потом уже будем превращать "количество в качество".