Страница 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;, что не хотелось бы.

Поясните, где здесь глюк?
глюк заключается в вашем незнании Си :) чтобы сбросить биты, надо выполнить логическое И с проинвертированной маской, т.е. сделать вот так:

Код: Выделить всё

PORTB &= ~( SCALE_LIGHTS  |  LAND_LIGHTS );
вы уточните на счет предыдущих глюков - наверняка причина та же самая :)

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)