Страница 68 из 421
Добавлено: Ср мар 10, 2010 14:53:37
Александр 2677
Снова я вклиниваюсь со своим кодом.
На этот раз пытаюсь разобраться с прерываниями.
Проверьте пожалуйста . И сразу вопросы что нужно подставить вместо знаков вопроса? И я так понимаю в этом случае используется сигнал со входов МК INT0 и INT1 ? А как сделать допустим срабатывание прерывания с кнопок заведённых на РB1 PB2?
#include <mega8>
#include <stdio>
#include <delay>
// External Interrupt 0 service routine - PD2 any changes
interrupt [EXT_INT0] void ???????(void)
{
PORTD.0 = 0;
delay_ms (1000); // ждем 1 сек. // Place your code here
PORTD.0 = 1;
PORTD.1 = 0;
delay_ms (1000); // ждем 1 сек.
PORTD.1 = 1;
PORTD.2 = 0;
delay_ms (1000); // ждем 1 сек.
PORTD.2 = 1;
PORTD.3 = 0;
delay_ms (1000); // ждем 1 сек.
PORTD.3 = 1;
}
// External Interrupt 1 service routine - PD3 any changes
interrupt [EXT_INT1] void ???????(void)
{
PORTC.0 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.0 = 0; // Place your code here
PORTC.1 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.1 = 0;
PORTC.2 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.2 = 0;
PORTC.3 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.3 = 0;
PORTC.4 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.4 = 0;
}
#include <stdio>
void main(void)
{
PORTB=0x00;
DDRB=0x00;
PORTC=0xff;
DDRC=0xff;
PORTD=0xff;
DDRD=0xff;
#asm("sei") // Global enable interrupts
while (1)
{
PORTD=0x00;
delay_ms (1000);
PORTD=0xff;
delay_ms (1000);
};
}
Заранее спасибо )
Добавлено: Ср мар 10, 2010 16:18:47
ValBag
Александр 2677 писал(а):Снова я вклиниваюсь со своим кодом.
Почему вы пишете
#include <mega8> без расширения "
.h" И что..., компилятор принимает такие включения заголовочных файлов ?
Вместо знаков вопроса, подставьте любые запоминающиеся имена функций обработки прерывания.
Не определены разрешения прерываний INT0, INT1 (регистр GICR) и условия их возникновения: по фронту, по спаду или по нулевому уровню (MCUCR).
Кроме INT0 и INT1, у Mega8 нет источников внешних прерываний. У Mega48/88 - намного больше. Кнопки можно повесить на то, что есть, сгладив дребезг внешней цепочкой или программно.
Добавлено: Ср мар 10, 2010 16:32:50
Александр 2677
Вобще то у меня стоит .h, Ума не приложу как я сюда копировал что они потерялись.
Не определены разрешения прерываний INT0, INT1 (регистр GICR) и условия их возникновения: по фронту, по спаду или по нулевому уровню (MCUCR).
Эта строчка что то мне совсем не ясна. Можете написать Что именно у куда вписать на простом примере.
Добавлено: Ср мар 10, 2010 16:55:54
ValBag
Александр 2677 писал(а):Эта строчка что то мне совсем не ясна. Можете написать Что именно у куда вписать на простом примере.
GICR=0xC0; // тут разрешения прерываний INT0, INT1
MCUCR=0x0A; // тут условия: сейчас стоит по спаду. Кнопку нажали - сигнал на входе прерывания переключился с еденицы на ноль (спад) - получили прерывание
P.S. Надо определить
DDRD.2=0; // (INT0)
DDRD.3=0; // (INT1)
как входы и включить подтягиващие резисторы для кнопок
PORTD.2=1;
PORTD.3=1;
А то, что в проге "навесили" на PORTD.2 и PORTD.3 - убрать (переключить на другие PIN-ы), т. к. эти разряды задействуются на кнопки.
Добавлено: Ср мар 10, 2010 20:43:55
Александр 2677
Большое спасибо за помощь. Всё работает

Добавлено: Чт мар 11, 2010 16:04:34
Александр 2677
А програмно избавиться от дребезга кнопки можно таким образом?
Код: Выделить всё
interrupt [EXT_INT1] void INT1(void)
delay_ms (30);
{
PORTC.0 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.0 = 0; // Place your code here
PORTC.1 = 1;
delay_ms (1000); // ждем 1 сек.
PORTC.1 = 0;
Добавлено: Чт мар 11, 2010 17:08:05
ELcat
Помогите, пожалуйста, уважаемые товарищи коты в следующем вопросе - есть кусочек кода, вроде на GCC:
#byte LATD =0xF8C
#bit LED = LATD.3
------
LED=0;
LED=1;
Как его записать в Code Vision AVR? Заранее спасибо...
Добавлено: Чт мар 11, 2010 18:50:46
ValBag
Александр 2677 писал(а):А програмно избавиться от дребезга кнопки можно таким образом?
interrupt [EXT_INT1] void INT1(void)
delay_ms (30);
....
Можно. Только надо проверить после выдержки, что кнопка действительно осталась нажатой, а затем продолжить операции, либо выйти, если нет.
Добавлено: Чт мар 11, 2010 18:56:00
ARV
ELcat писал(а):Помогите, пожалуйста, уважаемые товарищи коты в следующем вопросе - есть кусочек кода, вроде на GCC:
#byte LATD =0xF8C
#bit LED = LATD.3
------
LED=0;
LED=1;
Как его записать в Code Vision AVR? Заранее спасибо...
это не похоже на GCC. да и на Си тоже мало похоже... или какая-то экзотическая версия Си - не стандартная...
Добавлено: Чт мар 11, 2010 19:25:36
ELcat
Дорогой ARV, я с тобой полностью согласен, на том форуме где я видел этот кусок так и писали, что это не из классической С. Но ты так и не ответил на вопрос, как независимую переменную, пусть это будет unsigned char побить на "обозванные" биты, чтоб CV AVR это понимала?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Сб мар 13, 2010 23:51:58
Pooher
Народ, а подскажите как понимать этот код:
Код: Выделить всё
xstart <<= 1;
xstart += 6;
xend <<= 1;
xend += 7;
spi(0x00 | (xstart & 0x0F));
Я понял так:
Код: Выделить всё
lsl xstart ; сдвинуть xstart в лево
ldi tmp, 6
add xstart, tmp ; xstart=xstart+6
lsl xend; сдвинуть xend в лево
ldi tmp, 7
add xend, tmp ; ; xend=xend+6
clr tmp
andi xstart, 0x0f ; И xstart и 0x0f
or tmp, xstart ;ИЛИ tmp и xstart
rcall SPI_MasterTransmit ; отправить tmp в SPI
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс мар 14, 2010 00:52:49
ARV
Pooher писал(а):Народ, а подскажите как понимать этот код:
Код: Выделить всё
xstart <<= 1;
xstart += 6;
xend <<= 1;
xend += 7;
spi(0x00 | (xstart & 0x0F));
Я понял так:
Код: Выделить всё
lsl xstart ; сдвинуть xstart в лево
ldi tmp, 6
add xstart, tmp ; xstart=xstart+6
lsl xend; сдвинуть xend в лево
ldi tmp, 7
add xend, tmp ; ; xend=xend+6
clr tmp
andi xstart, 0x0f ; И xstart и 0x0f
or tmp, xstart ;ИЛИ tmp и xstart
rcall SPI_MasterTransmit ; отправить tmp в SPI
вроде понял все верно, при условии что переменные
xstart и
xend именно однобайтные. кроме того, операция ИЛИ с нулевым значением смысла не имеет, сточки
clr tmp и
or tmp, xstart лишние (если допустима порча xstart)
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс мар 14, 2010 01:15:44
Pooher
Ну и славненько, уже проверил даже, работает. По поводу нулевого значения - это понятно, просто в других случаях там другие маски, а эта попалась первая. Спасибо за ответ.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт мар 16, 2010 11:49:43
ELcat
Люди, объясните пожалуйста, как в CV AVR можно изменять биты в переменной, делать ветвление с сылкой на конкретный бит переменной?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт мар 16, 2010 12:12:09
AI_Disable
В кодвижионе, если не ошибаюсь, можно обращаться к биту, указывая через точку номер нужного бита.
Код: Выделить всё
if(peremennay.1) {} //если первый бит равен лог. 1, то…
else{}
peremennay.1=1; //Записать лог. 1 в первый бит
peremennay.1=0; //Записать лог. 0 в первый бит
Но правильнее будет использовать логические операции:
Код: Выделить всё
if(peremennay&0b00000010) {}//если первый бит равен лог. 1, то…
else {}
peremennay|=(1<<1); //Записать лог. 1 в первый бит
peremennay&=~(1<<1); //Записать лог. 0 в первый бит
В отличие от первого, это выражение поймёт любой сишный компилятор.
Битовая маска у PORTB - глюк?
Добавлено: Вт мар 16, 2010 12:13:31
DeltaGold
Всем добрый день.
Прошу помочь мне понять, почему компилятор CodeVision не отрабатывает код, который казалось бы должен работать. Я хочу понять - это глюк компилятора (уже встречал несколько глюков CodeVision), или у меня?
Простая схема, мигания светодиодов на ATTiny13.
Итак: есть объявление двух констант компилятора, которые определяют битовую маску для PORTB:
#define SCALE_LIGHTS 0b00001000
#define LAND_LIGHTS 0b00010000
...
В программе эти биты устанавливаются простой операцией, которая работает корректно:
PORTB |= SCALE_LIGHTS | LAND_LIGHTS; // Т.е., для данных констант это эквивалентно PORTB |= 0b00011000
После этого эти биты нужно сбросить. Пишу вот такую инструкцию:
PORTB &= !( SCALE_LIGHTS | LAND_LIGHTS ); // Т.е., для данных констант это эквивалентно PORTB &= 0b11100111
Компилятор этo пропускает, hex строит, только эта конструкция не работает. Под отладчиком видно, что биты PORTB просто сбрасываются в 0, причём все. Приходится обходить этот глюк инструкциями PORTB.3 = 0; и PORTB.4 = 0;, что не хотелось бы.
Поясните, где здесь глюк?
Re: Битовая маска у PORTB - глюк?
Добавлено: Вт мар 16, 2010 12:20:07
ARV
DeltaGold писал(а):После этого эти биты нужно сбросить. Пишу вот такую инструкцию:
PORTB &= !( SCALE_LIGHTS | LAND_LIGHTS ); // Т.е., для данных констант это эквивалентно PORTB &= 0b11100111
Компилятор этo пропускает, hex строит, только эта конструкция не работает. Под отладчиком видно, что биты PORTB просто сбрасываются в 0, причём все. Приходится обходить этот глюк инструкциями PORTB.3 = 0; и PORTB.4 = 0;, что не хотелось бы.
Поясните, где здесь глюк?
глюк заключается в вашем незнании Си

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

Re: Битовая маска у PORTB - глюк?
Добавлено: Вт мар 16, 2010 12:21:49
AI_Disable
DeltaGold писал(а):
PORTB &= !( SCALE_LIGHTS | LAND_LIGHTS );
Замените "!" на "~".
Битовая маска у PORTB - глюк?
Добавлено: Вт мар 16, 2010 13:28:16
DeltaGold
Ну прям сразу "незнании Си". Подзабыл один опреатор.
Спасибо ответившим! А-а-а, понятно, надо делать инвеpсию. Т.е., я сунул туда не оператор, а логическое выражение, которые компилятор корректно отрабатывал: т.е. "!"заставляло его выдать false, поэтому PORTB получал 0.
Это у меня значит был затык. Кстати, был приятно удивлён, как быстро мне ответили на этом форуме.
Спасибо, очень нужное мне решение! Всем хорошего дня, буду обращаться.
P.S.: насчёт предыдущих глюков - не, там причина явно глючная. Компилятор упрямо писал ошибку компиляции нету ";" после оператора, хотя там чёрным по зелёному стоит точка с запятой. Даже пробовал её переписать заново - та же ошибка.
Не долго думая, ставлю ещё одну ";" там, где компайлер хочет. Получается PORTB = 0x2F;; - глупость несусветная . Компилирую - ошибок нет! Дальше ещё интереснее: убираю одну точку с запятой, т.е. восстанавливаю совершенно корректную форму PORTB = 0x2F; Компилирую - ошибок нет, хотя минуту назад были.
И нет до сих пор. Вот такие чудеса

Re: CodeVision AVR в вопросах и ответах
Добавлено: Вт мар 16, 2010 17:16:23
ValBag
ELcat писал(а):Люди, объясните пожалуйста, как в CV AVR можно изменять биты в переменной, делать ветвление с сылкой на конкретный бит переменной?
В CVAVR битовый доступ реализован только к регистрам ввода-вывода и к ...битовой переменной. Обращение: имя_регистра.номер_бита (PORTA.5)