А то в этой теме мне стыдно позориться со своим "мегапроектом".
Модератор тебе правильно сказал. Не стоит темы плодить. И стыдится не стоит. Ты же не колупаешь в носу, время от времени выпрашивая у форумчан пару строчек для себя. Ты учишь, читаешь, рисуешь, исследуешь, ошибаешься, исправляешься. Процесс идет, все в порядке. Для помощи таким и толчется здесь людь знающий и ведающий.
Zhursat Используй функцию опроса кнопок в прерывании от таймера в предоставленном на 4 странице уважаемым пользователем Аlex код опроса кнопок просто велеколепный За что ему ещё раз отдельное спасибо!
Тут вот какое дело.... Убрал я из программы все, и оставил только работу с кнопками, как советовали. Вот код: Спойлер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 тоесть по идее она должна храниться в ЕЕПРОМ и сохранять свое значение даже при выключении схемы (ну или если электричество вырубится). Или я как то неправильно ее инициализирую? Но КодВижн вроде не ругается..... Компилит красиво.
Такое впечатление, что программа не знает, что это за переменная set_temp и что с ней нужно делать.
С этой переменной в программе всё нормально, что бы убедиться в этом достаточно глянуть на ассемблерный листинг. А вот переменную indication функция main хранит в регистре, компилятор так оптимизирует программу. И поскольку выполнение функции никогда не завершается, в регистре все изменения и остаются. Что бы избежать такое, нужно объявить переменную как volatile.
Код:
volatile unsigned int indication;
Тем самым Вы сообщите, что переменная может "внезапно" измениться и к ней нельзя применять оптимизацию.
_________________ А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Вообще-то, CVAVR всегда было пофиг на volatile. Чтоб сказать где проблема нужно увидеть весь код, желательно полный проект, а не огрызок за которым скрывается невесть что.. И еще, почему кнопка на PB0 проверяется на уровень 0, на на PB1 - на уровень 1? Подтянуты по разному что ли?
_________________ Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Вообще-то, 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 *****************************************************/
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]]; //выводим с каждым срабатыванием таймера число с мссива в порт В, но не для всех разрядов сразу
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 какое нибудь значение - тогда все красиво работает (инкремент-декремент, индикация - все пашет). Но в таком случае после включения-выключения питания в этой переменной будет присвоеное значение, зачем тогда ЕЕПРОМ использовать. Все ведь задумывалось так, чтобы эти данные было "энергонезависимы".
И правда, чего то глаз замылился ))) Насчет присваивания - все логично, пока не присвоите, там мусор, точнее 0xFF, в пределы не попадает и не инкрементируется/декрементируется. Что касается повторной записи при включении, скорее всего, при компиляции создается файл инициализации еепром (*.eep) - начальными значениями, а в коде это не прописывается. Его нужно зашивать отдельно от прошивки один раз. Точнее не скажу, с кодевижном давно не работал, а когда работал то квалификаторами eeprom не пользовался - делал по другому..
_________________ Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Все таки победил я кнопки!!!! Для перестраховки сделал так:
Код:
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, или нужно помощнее ставить???
Заработало - это хорошо. То что Вы назвали перестраховкой - это повышение надёжности программы.
Но работу с кнопками я бы посоветовал продолжить. В нынешнем варианте что бы изменить температуру на 10 градусов придётся потратить больше 20 секунд, а это не очень удобно.
_________________ А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Все таки победил я кнопки!!!! Для перестраховки сделал так:
Код:
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;};
тоже полезна - устанавливает дефолтные значения в случае чего. Но понимать инструментарий нужно...
_________________ Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Так а я о чем? Я обеими руками "За!". Вот тут накидал немного "автоматики", и еще уменьшил задержки на индикацию опорной температуры. Неплохо помог мне в этом вот этот сайтик http://www.atmega8.ru/ Это ни в коем случае не реклама, действительно для начинающих, типа меня, самое то. Вобщем, кто желает посмотреть и покритиковать - во вложении файлы проекта и конечно же протеус
Ну не трольте меня Я уже вычитал, что это такое.... В данном случае использование действительно не оправдано. Просто осталось с прошлых компиляций.....
Вы словно мои мысли прочитали: как раз сидел думал , что нужно поназначать дефайнами то, чем часто пользуешься. Так что критика принимается в полном обьеме. Но есть одно "Но": я уже говорил, что только начинаю знакомство с МК и с языком С в частности. Асм для меня вобще темный лес, а С немного понятней. Поэтому есть желание сразу разобраться во всем (ну или примерно во всем ) без упрощений, чтобы саму логику понять. А потом уже будем превращать "количество в качество".
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения