Технический форум по робототехнике.
HarryStar » 10 дек 2010, 09:29
Нужно мне хранить указатель на порт. Как это делается?
банальное
- Код: Выделить всё • Развернуть
unsigned char *r_port;
r_port = &PORTA;
*r_port = 0xff;
не работает, подскажите как правильно сделать подобную вещь, перерыл кучу документации, не понял, есть ли вообще такая возможность.
МК АТмега32, если это важно, компилятор CVAVR
пока как временное решение приходится городить switch на 4 порта, передавая порт как символ 'A'(В,С,D), но это долго и некрасиво.
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(;;);
}
boez » 10 дек 2010, 12:18
А вот странно - почему код HarryStar не работает? Вроде навскидку ровно то же самое, что и у blindman'а, только без красивостей. &PORTA это ж адрес порта в пространстве ОЗУ, все вроде корректно, компилятору вообще должно быть все равно что там - реальная ячейка ОЗУ или SFR.
HarryStar, а оно не работает или не компилится?
blindman » 10 дек 2010, 13:22
Это код под avr-gcc, там PORTA разворачивается в (*(volatile uint8_t *)((0x1B) + 0x20)), а как в cvavr PORTA определен - фиг его знает.
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(;;);
}
boez » 10 дек 2010, 17:57
Да вот я потому и уточнил - мне кажется HarryStar
нас обманул неточно выразился, и у него именно не компилится, потому что если код
- Код: Выделить всё • Развернуть
r_port = &PORTA
скомпилился, то я не могу представить, во что он мог скомпилиться, кроме
- Код: Выделить всё • Развернуть
r_port = (char*)(0x3B)
avr123, у вас CV есть - что оно на такой код говорит?
blindman » 10 дек 2010, 18:39
CVAVR - это не тру си
Регистры там определяются примерно вот так:
sfrb PORTA = 0x1B;
Хотя могли бы и догадаться сделать оператор взятия адреса применимым к ним.
avr123.nm.ru » 10 дек 2010, 19:02
boez писал(а): avr123, у вас CV есть - что оно на такой код говорит?
Вот так компилится:
- Код: Выделить всё • Развернуть
char* r_port;
r_port = (char*)(0x3B);
HarryStar » 11 дек 2010, 07:39
Ну да, мой пример именно не компилится, я не так выразился, говорит, что SFRB нельзя преобразовать к *uns char.
Спасибо за помощь!
sky-walker » 05 янв 2013, 19:26
Всем привет. Возникла такая же необходимость (делаю класс, в котором можно настроить ноги). Компилятор AVR-GCC (WinAVR).
Написанная выше функция set_port() работает как-то странно - при первом вызове все правильно отрабатывает, а дальше - весь порт выключается. Причем если потом дернуть любую ногу через PORTx - все включается правильно. Как эту проблему можно решить?
И еще вопросик - как считать значение порта по указателю?
P.S: пардон за некропост, думаю это лучше чем создавать новую тему...
dccharacter » 05 янв 2013, 19:39
должно быть не char *addr, так как это не указатель на чар, а просто char addr.
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
Та же ошибка.
Romikgy » 06 янв 2013, 00:37
обращение к портам ввода вывода идет не операциями доступа к памяти , а операциями ввода вывода out & in и есть спец инициализация в кодовиджине sfrb PORTA = 0x1B;
blindman » 06 янв 2013, 07:06
Romikgy писал(а):обращение к портам ввода вывода идет не операциями доступа к памяти , а операциями ввода вывода
Неа. Обращение к любым портам ввода вывода возможно операциями доступа к памяти , а к некоторым - еще и операциями ввода вывода
dccharacter » 06 янв 2013, 13:04
http://www.avrfreaks.net/index.php?name ... 74&start=0http://www.avrfreaks.net/index.php?name ... 44&start=0В общем, пишут то же самое. Теоретически в некоторых случаях это может сработать, но не для всех операций и не во всех компиляторах.