Перейти к содержанию
    

Не могу получить бит PORTX.Y

Следующий код:

#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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хоть бы написали что за компилятор. Если IAR то там вроде как есть такие макросы PORTx.x, если вы хотите считать вход то вроде как надо вот так PINx.x. В CodeVision вроде можно читать и писать порт целиком, например PORTA = 0x23;

if(PINA && 0x01) {}

Возможно я что-то напутал. Смотрите экземплы в своем компиляторе.

Не обязательно постоянно менять направление работы порта. У вас можно записать DDRA = 0xFD. В таком случае бит 1 будет настроен на вход, все остальные биты порта на выход.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где такая форма записи доступа к биту описана? Хидеры то подключены соответствующие? Может тогда лучше записать более переносимо? Например так:

if ((PORTA & 0x01) == 0x01)

 

Судя по #include <avr/io.h> это ВинАВР или АВРГЦЦ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if(PINA && 0x01) {}

Возможно я что-то напутал

точно. &&-унарная логическая операция

:bb-offtopic:

PS: вот за что мне всё больше нравится GCC, так это за то что учит писать нормальным человеческим СИ, не привязанным к фичам конкретного компилятора

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такая форма записи доступа к биту описана в книге:

Шпак Ю.А. Программирование на языке С для AVR и PIC микроконтроллеров. МК-Пресс, Киев, 2006.djvu

 

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

 

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такая форма записи доступа к биту описана в книге:

Шпак Ю.А. Программирование на языке С для AVR и PIC микроконтроллеров. МК-Пресс, Киев, 2006.djvu

 

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

 

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

 

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

 

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

 

Это у вас видимо привычка с MCS51 осталась, но в AVR нет прямой битовой адресации, поэтому рекомендации использовать макросы, которые Вы в состоянии написать сами, будет более правильно и не менее понятным для восприятия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хидер можно оставить тот же самый.

А вот тут я действительно напутал

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)

а это для чтения данных с порта

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилирую 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));
  ...
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мне вот почему-то более ясным для восприятия кажется другая форма:

#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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не поленитесь, найдите файл io.h и хотя бы бегло его просмотрите. (вместе с входящими инклудами)

Меньше будет недоразумений.

А ещё у ВинАВР отличная документация (имхо)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это работает

#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)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати PINA.1 будет (PINA & 0x02), нумерация битов в байте начинается с 0

 

Все эти имена PINA, PORTB и т.д. должны быть описаны в соответствующих заголовочных файлах и они, эти файлы, должны быть подключены в проект, т.е. это не какие то встроенные типы компилятора - компилятор о них не имеет никакого представления, особенно кросплатформенный ГЦЦ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это работает

...

а здесь c1 всё время в нуле

...

ИМХО, это - результат оптимизации. В последнем случае PINA, вероятно, берется в регистр (вынесено из цикла), и с содержимым регистра производится вычисление reg & 0x01. Естественно, регистр не меняется (уже) и результат - тоже. В WinAVR можно воспользоваться макросом bit_is_set из sfr_defs.h. Ну, или отключить оптимизацию...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...