это не дотошный, это говорит о том что вы не понимаете на чем пишете.
Мастер Ломастер писал(а):int your_result = your_variant(2 | i);
А вот это я и назвал бы извратом. Вы использовали подобную конструкцию в своих программах хоть единожды? Засунуть в макрос _BV() арифметическую операцию еще норм, но это...
изврат или нет - дело десятое. отсутствие скобок вокруг "операнда" в макросе - это потенциальный источник трудноотлавливаемых ошибок, так как отличить "на глаз" макрос с парамтерами от функции в программе практически нереально - для функций любые выражения, передаваемые в параметрах, будут правильно интерпретированы, а для макроса - не всегда, если нет скобок.
сдвиг - одна из низкоприоритетных операций, и для нее скобки кажутся явно лишними, но привычка писать макросы без скобок наверняка приведет не к добру.
битва с дураками проиграна, победители торжествуют. слава победителям!
Надо просто думать, что и как делаешь, когда мыслю на практике воплощаешь. P.S. Когда пару тройку раз головой об шкафчик вмажешься, запоминаешь что он существует , где висит и чем это тебе грозит
BerZerK-ku писал(а):Надо просто думать, что и как делаешь, когда мыслю на практике воплощаешь. P.S. Когда пару тройку раз головой об шкафчик вмажешься, запоминаешь что он существует , где висит и чем это тебе грозит
в принципе, если ограничиться визардом CVAVR, то можно даже и не думать вообще. но если все-таки думать, то думать надо с перспективой на будущее. а эта перспектива выглядит буквально так: сделанное однажды надо просто в будущем повторять, не напрягая мозг. поэтому делать надо так, чтобы спустя время не пришлось ломать голову, почему оно вдруг перестало работать. и в этом контексте скобки вокруг "параметра" макроса, как и вокруг всего "тела" макроса, будут исключительно уместны.
P.S. но вы можете этого не делать - вам можно
битва с дураками проиграна, победители торжествуют. слава победителям!
Вы, уважаемые, о чем спорите-то? Чемпионат по мерянию писюнами? Известно же: кто как хочет, так и. Главное - работоспособность и надежность. Вспоминается стишок о двух баранах на мосту. ps. Мечта у меня - сделать что-нибудь этакое, чтобы потом люди себе лбы расшибали в спорах как это лучше использовать.
Доброго всем времени суток!!! Ребята помогите новичку с программой. В общем в двух словах: При включении на LCD 16х02 должно отбражается "LCD 16x02" и "CodeVision1.25.3, далее при нажатии на int0 должна высвечиваться надпись: "LCD", а при нажатии int1 - "Cool".В Протеусе первая часть программы работает, а обработка прерываний - нет. Текст программы привожу. Подскажите пожалуйста что надо здесь исправить. Заранее очень всем благодарен!!!!
void main( void ) //* Основная функция "main", с которой начинается выполнение всей /* программой процедуры */ { lcd_init( 16 ); //* инициализация на 16 символов */ lcd_clear( ); //* очистка дисплея */ lcd_gotoxy( 4,0 ); //* верхняя строка, 4 позиция */ lcd_putsf( "LCD 16x02" ); //* выводим надпись в указанных координатах */ lcd_gotoxy( 0,1 ); //* нижняя строка, 0 позиция */ lcd_putsf( "CodeVision1.25.3" );
DDRD.2=0; // (INT0) DDRD.3=0; // (INT1) //как входы и включить подтягиващие резисторы для кнопок PORTD.2=1; PORTD.3=1; GICR=0xC0; // тут разрешения прерываний INT0, INT1 MCUCR=0x0A; // тут условия: сейчас стоит по спаду. //Кнопку нажали - сигнал на входе прерывания переключился //с еденицы на ноль (спад) - получили прерывание }
Порты опрашивать по PIN. Операция сравнения ==, а не =. И незачем каждый раз инициализировать ЖКИ. И не вижу смысла в вечном цикле в прерываниях. Вам же вылезти оттуда надо.
Принял исправления как вы сказали, при трасляции ругается на "volatile unsigned char flagInt0 = 0;". В Протеусе также неработает. Подскажите пожалуйста, что еще может быть?
после инициализации в основном цикле нужно остановиться и ждать прерывания в цикле. а у вас он безконтрольно вылетает дальше. while(1) {} поставьте после #asm("sei");
Поставил, но результат тот же. Я извиняюсь!!!! Может я что-то не очень понимаю. Не могли бы Вы скопировать фрагмент моего исходника и показать что по чем...??? Спасибо!!!
void main( void ) //* Основная функция "main", с которой начинается выполнение всей /* программой процедуры */ { lcd_init( 16 ); //* инициализация на 16 символов */ lcd_clear( ); //* очистка дисплея */ lcd_gotoxy( 4,0 ); //* верхняя строка, 4 позиция */ lcd_putsf( "LCD 16x02" ); //* выводим надпись в указанных координатах */ lcd_gotoxy( 0,1 ); //* нижняя строка, 0 позиция */ lcd_putsf( "CodeVision1.25.3" );
DDRD.2=0; // (INT0) DDRD.3=0; // (INT1) //как входы и включить подтягиващие резисторы для кнопок PORTD.2=1; PORTD.3=1; GICR=0xC0; // тут разрешения прерываний INT0, INT1 MCUCR=0x0A; // тут условия: сейчас стоит по спаду. //Кнопку нажали - сигнал на входе прерывания переключился //с еденицы на ноль (спад) - получили прерывание //*******}
#asm("sei"); while(1);//********** можно не ставить, оно и так здесь крутиться будет. }
; 0000 0020 #asm("sei"); 000094 9478 sei ; 0000 0021 while(1);//********** можно не ставить, оно и так здесь крутиться будет. _0xB: 000095 cfff RJMP _0xB ; 0000 0022 } _0xE: 000096 cfff RJMP _0xE
Вот листинг компилированного кода. Заглушку по метке в данном случае _0х0Е компилятор ставит всегда. Ниже вхиле закомментирован.
; 0000 0020 #asm("sei"); 000094 9478 sei ; 0000 0021 //while(1);//********** можно не ставить, оно и так здесь крутиться будет. ; 0000 0022 } _0xB: 000095 cfff RJMP _0xB
Встречный вопрос: не вижу причины несрабатывания другого прерывания.
Ура!!! Теперь все рабатает!!!! Подскажите еще вопрос, как лучше сделать: необходимо создать ну скажем однострочное меню скажем из трех пунктов. При включении чтобы последовательно нажимая скажем INT0, можно было бы переключать пункты меню? Как мне кажется нужно использовать оператор switch(), только как включить его в программу никак неразберусь. Подскажите пожалуйста!!!! Заранее спасибо!!!!
Последний раз редактировалось John-RADIST Пт дек 16, 2011 18:35:17, всего редактировалось 2 раза.