roboforum.ru

Технический форум по робототехнике.

Указатель на порт

Указатель на порт

HarryStar » 10 дек 2010, 09:29

Нужно мне хранить указатель на порт. Как это делается?
банальное
Код: Выделить всёРазвернуть
unsigned char *r_port;
r_port = &PORTA;

*r_port = 0xff;


не работает, подскажите как правильно сделать подобную вещь, перерыл кучу документации, не понял, есть ли вообще такая возможность.
МК АТмега32, если это важно, компилятор CVAVR

пока как временное решение приходится городить switch на 4 порта, передавая порт как символ 'A'(В,С,D), но это долго и некрасиво.

Re: Указатель на порт

blindman » 10 дек 2010, 10:24

avr-gcc:

Код: Выделить всёРазвернуть
#include <avr/io.h>
#include <inttypes.h>

void set_port(uint8_t *addr, uint8_t value)
{
   *addr = value;
}

int main(void)
{
   uint8_t* port = (uint8_t*)&PORTA;
   set_port(port, 0xFF);
   for(;;);
}


Любой компилятор:
Код: Выделить всёРазвернуть
#include <blahblahblah>
void set_port(uint8_t *addr, uint8_t value)
{
   *addr = value;
}

int main(void)
{
   uint8_t* port = (uint8_t*)(0x3B); // адрес порта A
   set_port(port, 0xFF);
   for(;;);
}

Re: Указатель на порт

boez » 10 дек 2010, 12:18

А вот странно - почему код HarryStar не работает? Вроде навскидку ровно то же самое, что и у blindman'а, только без красивостей. &PORTA это ж адрес порта в пространстве ОЗУ, все вроде корректно, компилятору вообще должно быть все равно что там - реальная ячейка ОЗУ или SFR.
HarryStar, а оно не работает или не компилится?

Re: Указатель на порт

blindman » 10 дек 2010, 13:22

Это код под avr-gcc, там PORTA разворачивается в (*(volatile uint8_t *)((0x1B) + 0x20)), а как в cvavr PORTA определен - фиг его знает.

Re: Указатель на порт

avr123.nm.ru » 10 дек 2010, 14:34

Вот так в CVAVR скомпилилось.


Код: Выделить всёРазвернуть
void set_port(char *addr, char value)
{
   *addr = value;
}

void main(void)
{
   char* port = (char*)(0x3B); // адрес порта A
   set_port(port, 0xFF);
   for(;;);
}

Re: Указатель на порт

boez » 10 дек 2010, 17:57

Да вот я потому и уточнил - мне кажется HarryStar нас обманул неточно выразился, и у него именно не компилится, потому что если код
Код: Выделить всёРазвернуть
r_port = &PORTA
скомпилился, то я не могу представить, во что он мог скомпилиться, кроме
Код: Выделить всёРазвернуть
r_port = (char*)(0x3B)

avr123, у вас CV есть - что оно на такой код говорит?

Re: Указатель на порт

blindman » 10 дек 2010, 18:39

CVAVR - это не тру си :)

Регистры там определяются примерно вот так:

sfrb PORTA = 0x1B;

Хотя могли бы и догадаться сделать оператор взятия адреса применимым к ним.

Re: Указатель на порт

avr123.nm.ru » 10 дек 2010, 19:02

boez писал(а): avr123, у вас CV есть - что оно на такой код говорит?


Вот так компилится:

Код: Выделить всёРазвернуть
    char* r_port; 

        r_port = (char*)(0x3B);

Re: Указатель на порт

HarryStar » 11 дек 2010, 07:39

Ну да, мой пример именно не компилится, я не так выразился, говорит, что SFRB нельзя преобразовать к *uns char.
Спасибо за помощь!

Re: Указатель на порт

sky-walker » 05 янв 2013, 19:26

Всем привет. Возникла такая же необходимость (делаю класс, в котором можно настроить ноги). Компилятор AVR-GCC (WinAVR).
Написанная выше функция set_port() работает как-то странно - при первом вызове все правильно отрабатывает, а дальше - весь порт выключается. Причем если потом дернуть любую ногу через PORTx - все включается правильно. Как эту проблему можно решить?

И еще вопросик - как считать значение порта по указателю?

P.S: пардон за некропост, думаю это лучше чем создавать новую тему...

Re: Указатель на порт

dccharacter » 05 янв 2013, 19:39

должно быть не char *addr, так как это не указатель на чар, а просто char addr.

Re: Указатель на порт

sky-walker » 05 янв 2013, 19:47

Спасибо за быстрый ответ.

Так?
Код: Выделить всёРазвернуть
void set_port(char addr, char value)
{
   *addr = value;
}

Вышибает ошибку invalid type argument of 'unary *' (have 'int').

Нашел в поиске:
Код: Выделить всёРазвернуть
//Допустим регистр данных порта расположен по адресу 0x16
unsigned char Port;
Port = 0x16;
*Port = 0xFF; //Записали в порт соответствующий регистру расположенному по адресу 0x16 число 255

Та же ошибка.

Re: Указатель на порт

Romikgy » 06 янв 2013, 00:37

обращение к портам ввода вывода идет не операциями доступа к памяти , а операциями ввода вывода out & in и есть спец инициализация в кодовиджине sfrb PORTA = 0x1B;

Re: Указатель на порт

blindman » 06 янв 2013, 07:06

Romikgy писал(а):обращение к портам ввода вывода идет не операциями доступа к памяти , а операциями ввода вывода

Неа. Обращение к любым портам ввода вывода возможно операциями доступа к памяти , а к некоторым - еще и операциями ввода вывода

Re: Указатель на порт

dccharacter » 06 янв 2013, 13:04

http://www.avrfreaks.net/index.php?name ... 74&start=0
http://www.avrfreaks.net/index.php?name ... 44&start=0

В общем, пишут то же самое. Теоретически в некоторых случаях это может сработать, но не для всех операций и не во всех компиляторах.


Rambler\'s Top100 Mail.ru counter