Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не могу получить бит PORTX.Y
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Артем Бум
Следующий код:
Код
#include <avr/io.h>

int main (void)
{
    DDRA = 0x00; // Настройка порта A для ввода

32:    if(PORTA.1 == 1){
        DDRA = 0xFF; // Настройка порта A для вывода
        PORTA = 0;
35:        PORTA.2 = 1;
    }
}


выдаёт ошибку

Код
SOS.c: In function 'main':
SOS.c:32: error: expected ')' before numeric constant
SOS.c:35: error: expected ';' before numeric constant
uriy
Хоть бы написали что за компилятор. Если IAR то там вроде как есть такие макросы PORTx.x, если вы хотите считать вход то вроде как надо вот так PINx.x. В CodeVision вроде можно читать и писать порт целиком, например PORTA = 0x23;
if(PINA && 0x01) {}
Возможно я что-то напутал. Смотрите экземплы в своем компиляторе.
Не обязательно постоянно менять направление работы порта. У вас можно записать DDRA = 0xFD. В таком случае бит 1 будет настроен на вход, все остальные биты порта на выход.
GDI
А где такая форма записи доступа к биту описана? Хидеры то подключены соответствующие? Может тогда лучше записать более переносимо? Например так:
Код
if ((PORTA & 0x01) == 0x01)


Судя по #include <avr/io.h> это ВинАВР или АВРГЦЦ.
MrYuran
Цитата
if(PINA && 0x01) {}
Возможно я что-то напутал

точно. &&-унарная логическая операция
bb-offtopic.gif
PS: вот за что мне всё больше нравится GCC, так это за то что учит писать нормальным человеческим СИ, не привязанным к фичам конкретного компилятора
Артем Бум
Такая форма записи доступа к биту описана в книге:
Шпак Ю.А. Программирование на языке С для AVR и PIC микроконтроллеров. МК-Пресс, Киев, 2006.djvu

среди операторов языка С.

Компилирую WinAVR.

Данный способ мне кажется более ясным для восприятия, пусть и не переносимым.

Не подскажете какие хеадеры нужно подключать и где?
VladimirYU
Цитата(Артем Бум @ May 27 2008, 12:48) *
Такая форма записи доступа к биту описана в книге:
Шпак Ю.А. Программирование на языке С для AVR и PIC микроконтроллеров. МК-Пресс, Киев, 2006.djvu

среди операторов языка С.

Компилирую WinAVR.

Данный способ мне кажется более ясным для восприятия, пусть и не переносимым.

Не подскажете какие хеадеры нужно подключать и где?


Это у вас видимо привычка с MCS51 осталась, но в AVR нет прямой битовой адресации, поэтому рекомендации использовать макросы, которые Вы в состоянии написать сами, будет более правильно и не менее понятным для восприятия.
uriy
Хидер можно оставить тот же самый.
А вот тут я действительно напутал
Код
if(PINA && 0x01) {}

Это условие будет всегда выполняться, надо писать так
Код
if(PINA & 0x01) {}

Это эквивалентно вашему в какой то мере
Код
if(PORTA.1 == 1)

В io.h инклудятся другие хидеры, например посмотрим iom128.h это для мега128
/* Data Register, Port A */
#define PORTA _SFR_IO8(0x1B)
т.е. это для выдачи данных в порт

/* Input Pins, Port A */
#define PINA _SFR_IO8(0x19)
а это для чтения данных с порта
MrYuran
Цитата(Артем Бум @ May 27 2008, 11:48) *
Компилирую WinAVR.

тогда лучше придерживаться стандартов
Цитата
Данный способ мне кажется более ясным для восприятия, пусть и не переносимым.

А мне вот почему-то более ясным для восприятия кажется другая форма:
Код
#define BIT0 0
#define BIT1 1
...
#define BIT7 0x80
#define SETBIT(reg,bit) reg|=bit
#define CLRBIT(reg,bit) reg&=~bit

void main()
{
  ...
  SETBIT(PORTA,BIT3);
  ...
  CLRBIT(PORTA,(BIT1|BIT3|BIT5));
  ...
}
Nick_Shl
Цитата(MrYuran @ May 27 2008, 12:02) *
А мне вот почему-то более ясным для восприятия кажется другая форма:
Код
#define SETBIT(reg,bit) reg|=bit
#define CLRBIT(reg,bit) reg&=~bit
А мне больше такая:
Код
#define PORTX.Y(x) PORTX = (PORTX & ~(1 << Y)) | (x << Y)
Это для конкретного порта и пина. x должен быть или 0 или 1.
Использовал в CodeVision - в нем на атмеге128 нельзя обратится к PORTG.x потому как он лежит за пределами памяти адресуемой in/out-ами(если я конечно правильно понял)...
Артем Бум
Код
#include <avr/io.h>
#define PINA.1 (PINA & 0x01)

int main (void)
{
    if(PINA.1 == 1)
    {

    }
}


выдаёт ошибку

Код
SOS.c: In function 'main':
SOS.c:8: error: 'PINA' undeclared (first use in this function)
SOS.c:8: error: (Each undeclared identifier is reported only once
SOS.c:8: error: for each function it appears in.)
SOS.c:8: error: called object '1.00000001490116119384765625e-1' is not a function
SOS.c:8: error: expected ')' before numeric constant
make.exe: *** [SOS.o] Error 1
MrYuran
не поленитесь, найдите файл io.h и хотя бы бегло его просмотрите. (вместе с входящими инклудами)
Меньше будет недоразумений.
А ещё у ВинАВР отличная документация (имхо)
Barni
Может лучше не PORTA.1, а PINA.1, я так понимаю надо вход проверять.
Артем Бум
это работает
Код
#include <avr/io.h>

int c1 = 0;

int main (void)
{
    DDRA = 0x00;

    while([b]c1!=1[/b])
    {
        if(PINA & 0x01)
        {
            c1 = 1;
        }    
    }
}


а здесь c1 всё время в нуле
Код
#include <avr/io.h>

int c1 = 0;

int main (void)
{
    DDRA = 0x00;

    while([b]1[/b])
    {
        if(PINA & 0x01)
        {
            c1 = 1;
        }    
    }
}


Дебажу код по F11 (Step Into). На ходу меняю значение PINA в окне IO VIEW (AVR Studio)
GDI
Кстати PINA.1 будет (PINA & 0x02), нумерация битов в байте начинается с 0

Все эти имена PINA, PORTB и т.д. должны быть описаны в соответствующих заголовочных файлах и они, эти файлы, должны быть подключены в проект, т.е. это не какие то встроенные типы компилятора - компилятор о них не имеет никакого представления, особенно кросплатформенный ГЦЦ.
Палыч
Цитата(Артем Бум @ May 28 2008, 09:06) *
это работает
...
а здесь c1 всё время в нуле
...
ИМХО, это - результат оптимизации. В последнем случае PINA, вероятно, берется в регистр (вынесено из цикла), и с содержимым регистра производится вычисление reg & 0x01. Естественно, регистр не меняется (уже) и результат - тоже. В WinAVR можно воспользоваться макросом bit_is_set из sfr_defs.h. Ну, или отключить оптимизацию...
XVR
Цитата(Nick_Shl @ May 27 2008, 13:46) *
А мне больше такая:
Код
#define PORTX.Y(x) PORTX = (PORTX & ~(1 << Y)) | (x << Y)
Это для конкретного порта и пина. x должен быть или 0 или 1.
По стандарту С (и С++) после #define должен быть ИДЕНТИФИКАТОР, т.е. нечто, состоящее из букв (английских), цифр и знака '_'. Точка ('.') к этому набору не относится, так что ЛЮБОЙ С компилятор имеет полное право обругаться на эту конструкцию, или трактовать ее как

Код
#define PORTX   .Y(x) PORTX = (PORTX & ~(1 << Y)) | (x << Y)
что для PORTX.Y(1) будет раскрываться в
Код
.Y(x) PORTX = (PORTX & ~(1 << Y)) | (x << Y) .Y(1)
что явно не то, что хотел автор
Цитата
Использовал в CodeVision
Очень повезло, что CodeVision разрешил точку в имени define'а, gcc (он же WinAvr) трактовал это иначе sad.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.