jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба Я хочу получить адресс пина. из стандартных дефайнов мы имеем #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) #define GPIO_IDR_IDR1 ((uint16_t)0x0002) И тогда #define GPIOA_PIN_1 (GPIOA + GPIO_IDR_IDR1) И потом я могу обратиться по адресу if(GPIOA_PIN_1) //do something Правильны ли мои умозаключения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба А к регистру IDR обращаться вы собираетесь? К отдельному биту регистров обратиться можно с помощью механизма bit-band. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 (изменено) · Жалоба А к регистру IDR обращаться вы собираетесь? К отдельному биту регистров обратиться можно с помощью механизма bit-band. я могу протестировать пин и так. static inline uint8_t PIN_SYG(GPIO_TypeDef * GPIOx, uint16_t PINx) { if((GPIOx->IDR&PINx)!=0) return 1; else return 0;} } но мне нужно как то сохранить адрес пина чтоб знать в последствии какой пин опрашивать. в принципе я мог бы сохранить номер пина и вставлять его в функцию но у меня уже есть член в структуре - указатель на переменную (void * var). не хочется городить лишние члены. Изменено 28 марта, 2016 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба И тогда Код #define GPIOA_PIN_1 (GPIOA + GPIO_IDR_IDR1) И потом я могу обратиться по адресу Код if(GPIOA_PIN_1) //do something Правильны ли мои умозаключения? Нет. GPIO_IDR_IDR1 это маска для наложжения на регистр, чтобы протестировать(или изменить) конкретный бит. Адрес пина... К сожалению такого понятия нет, т.к. нельзя взять адрес бита. Т.е. вам в каком-то виде придется таки иметь дело с регистром(он конечно же имеет адрес) и номером бита в этом регистре. И уже эту парочку передавать там куда вам нужно.... Все это может иметь самые различные варианты реализации, но смысл остается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба Нет. GPIO_IDR_IDR1 это маска для наложжения на регистр, чтобы протестировать(или изменить) конкретный бит. Адрес пина... К сожалению такого понятия нет, т.к. нельзя взять адрес бита. Т.е. вам в каком-то виде придется таки иметь дело с регистром(он конечно же имеет адрес) и номером бита в этом регистре. И уже эту парочку передавать там куда вам нужно.... Все это может иметь самые различные варианты реализации, но смысл остается. я понял. спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба Адрес пина... К сожалению такого понятия нет, т.к. нельзя взять адрес бита. А разве в Вашем МК пространство GPIO периферии на наложено на bitband-регион??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 (изменено) · Жалоба А разве в Вашем МК пространство GPIO периферии на наложено на bitband-регион??? так надо же знать с чем битбайндить. а я вот думаю а что если создать искуственный адрес. скажем мне нужен пин PA1 - я делаю так GPIOA+1 и потом в соответствии с адресом тестирую соответствующий пин. Изменено 28 марта, 2016 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба так надо же знать с чем битбайндить.Нет - достаточно прочитать, что это такое и как оно работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба так надо же знать с чем битбайндить. В смысле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба Ну bitband то ясно. Это, скажем так, наворот конкретного процессора. Размышляя на уровне языка Си такое вот GPIOA+1 не буде работать как ожидается. Вы, похоже, так толком и не разобрались с указателями. Вопрос вам для размышления: Предположим GPIOA определен как указатель на uint32(а оно так и будет обычно). т.е. как-то так: uint32_t *GPIOA = (uint32_t *)0x04; В памяти регистры расположены подряд(оно обычно тоже так и бывает). GPIOA - у него например адрес в памяти 0x04, на него сейчас указывает наш указатель. GPIOB - у него уже адрес в памяти 0x08 далее есть некий указатель. Пусть даже это будет параметр функции. Ну т.е. нечто, что вы собиираетесь передавать куда-то.... Сделаем как вы предложили. Применим +1 uint32_t *p = GPIOA + 1; На что теперь указывает p? Если сделать вот так uintptr_t addr = &*p; то чему будет равен addr? После ответов на эти вопросы вы наконец должны понять как работают указатели ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 (изменено) · Жалоба понятно. просто у меня нет члена в структуре для хранения bit mask вот и пытаюсь придумать что то. я не думал использовать адресс по назначению. я бы сделал что нибудь такое. case GPIOA+1: bit_mask =1; case GPIOA+2: bit_mask =2; или так case (GPIOA->IDR + 1) : bit_mask =1; case (GPIOA->IDR + 2) : bit_mask =2; Изменено 28 марта, 2016 пользователем Herz Избыточное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба Месье знает толк в извращениях ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба следующая тема, чувствую, будет опять "как в этой лапше выгадать 3 такта". Jenya7, предлагаю: - забыть слово "адресс" (а то придёт Herz, и научит Вас русскому языку) - написать модуль-прослойку, у которого на входе не некие странные "GPIOA+1", а вполне понятные "вход кнопка 1", "вход XXX". Тогда привязка функции входа к конкретной ноге будет ровно в одном месте. Не, ну можно, конечно, благо у STM'ок адреса разных портов GPIO различаются аж на 0x400. uint32_t get_input (uint32_t param) { GPIO_TypeDef * port = (GPIO_TypeDef *) (param & ~0x1F); uint32_t pin = param & 0x1F; return port->IDR & (1UL << pin); } ... get_input (GPIOA | 1); get_input (GPIOB | 31); Но всё равно, не надо так делать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 марта, 2016 Опубликовано 28 марта, 2016 (изменено) · Жалоба Месье знает толк в извращениях ))) я не хочу вводить новый член (bit-mask) в структуру. в массиве из x элементов в большинстве случаев он будет пустовать. следующая тема, чувствую, будет опять "как в этой лапше выгадать 3 такта". Jenya7, предлагаю: ... Но всё равно, не надо так делать. вот это ближе к телу как говорил Мопасан. :) мне просто надо какое нибудь число записать. оно не обязано быть реальным адресом. а зачем обнулять первые 32 бита? они и так нулевые. Изменено 28 марта, 2016 пользователем Herz Избыточное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 28 марта, 2016 Опубликовано 28 марта, 2016 · Жалоба bitband #define ALIAS(VarAddr, BitNum) \ *((volatile uint32_t *)(((VarAddr) & 0xF0000000) | 0x02000000 \ + (((VarAddr) & 0xFFFFF) << 5) | ((BitNum) << 2))) #define ALIAS_PTR(VarPtr, BitNum) \ *((volatile uint32_t *)(((uint32_t)&(VarPtr) & 0xF0000000) | 0x02000000 \ + (((uint32_t)&(VarPtr) & 0xFFFFF) << 5) | ((BitNum) << 2))) upd. Присмотрелся к коду, добавил скобок, убрал пробелов. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться