Застрял на регистрах stm32. Может кто нибудь подскажет? Вопрос не в самих регистрах, а в языке Си.
Немного об устройстве регистров как я это вижу: В файле stm32f10x.h находится структура: typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef Я эту структуру у себя не нашёл, так же как и этот файл.
Затем делаются указатели для каждого порта и регистров. #define GPIOA ((GPIO_TypeDef*)0x48000); Я думаю затем заполняется где то вся эта структура GPIO_TypeDef, но где я не нашёл.
Затем идёт настройка регистров GPIOA->ODR |=1UL<<14; ---------- В принципе то что выше можно не учитывать, я пример упрощу. У меня не получается заполнить структуру по указателю. Visual Studio выдаёт ошибку. МК у меня ещё нет, тренируюсь на обычных IDE.
Этот способ является правильным для заполнения структуры? struct gpio { int reg; }; int main(void) { ((struct gpio*)0x45000)->reg=1; } Если да, то как вывести, увидеть, проверить значение находящееся по адресу 0x45000? Не используя HEX код? Так не получается printf("%d\n", *((int*)0x45000));
И разве не надо прежде чем присваивать значение указателю, сначала присвоить этому указателю структурную переменную? struct gpio { int reg; } new_struct; int main() { struct gpio *ptr; ptr=&new_struct; ptr->reg=1; } То есть разница. Здесь ((struct gpio*)0x45000)->reg=1; напрямую указателю присваивается. Спасибо.
Этот способ является правильным для заполнения структуры?
На "обычных IDE" нет. Операционная система вам не разрешит писать по произвольным адресам. Я слышал, в последних версиях Протеуса добавили поддержку STM'ок, платформо-зависимые вещи лучше тестировать там, если реального железа нет.
Цитата:
В файле stm32f10x.h находится структура: Я эту структуру у себя не нашёл, так же как и этот файл.
Файл лучше поищите, может даже просто поиском по файловой системе, мало ли в какую щель его затолкали.
Если создавать не пустой проект, а проект непосредственно под этот микроконтроллер, то необходимые файлы автоматически скопируются. В крайнем случае, их можно найти на просторах инета. И в разных IDE файлы могут немного отличаться.
Касательно самого принципа. Там пишется структура, ей задается имя, а задем создается указатель на эту структуру и этот указатель накладывается на адрес первого регистра периферии. Таким образом, последовательные адреса становятся сгруппированы в созданную структуру. Физически не создается никаких дополнительных переменных. Просто на последовательные адреса от и до как бы натягивается коробка с именованными ячейками заданного размера, где GPIOA - это имя коробки, а ODR - имя ячейки в этой коробке. Таким образом, запись GPIOA->ODR вызывает обращение к ячейке коробки, а адрес этой ячейки вычисляется как адрес коробки + порядковый номер ячейки в коробке. Вот так образно это и описывается. Чтобы упростить для программиста запись, введены переопределения, маскирующие полноценную запись *((uint16_t*)0x4001080C) = 1; в простую и понятную GPIOA->ODR = 1. И наоборот, если надо прочитать, то uint16_t read = *((uint16_t*)0x4001080C) что соответствует read = GPIOA->ODR. Для того, чтобы понять, как работают структуры и указатели на структуры, нужно прочитать соответствующие разделы в учебнике по языку Си (авторы Керниган, Ритчи).
В любом IDE есть настройки: ведь то же подчеркивание ошибок и автодополнение для своей работы как-то должно знать, как ваши функции/макросы/переменные/структуры выглядят! Соответственно, должна быть настройка путей к директориям с заголовочными файлами, а также настройка каких-то макросов, определяемых в Makefile или CMakeLists.txt. Могу подсказать, как в qt-creator это делается. Продукцией мелкомягких [censored] я по понятным причинам не пользуюсь.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Eddy_Em, >>Соответственно, должна быть настройка путей к директориям с заголовочными файлами, а также настройка каких-то макросов, Вы про файл stm32f10x.h? Я пока что CubeMx пользуюсь. Почему то или нет файла или я не нашёл где объявлена структура GPIO_TypeDef, все файлы конечно обыскал. Но я разберусь. Чтоб в Qt Creator или в Visual Studio писать нужно много настроек самому делать Я это обятательно позже буду делать, так как CMSIS освоить хочу, но сейчас сложновато сразу.
Добавлено after 1 hour 1 minute 50 seconds: Никакие header почему то Cube Mx не создаёт вместе с проектом. Может их отдельно загружать надо?
Нашёл причину. В Cube Mx надо поставить галочку на: аdd necessary library files as reference in the toolchain project configuration file А реальная причина была в том что в IAR, в опциях проекта не были заполнены пути для заголовочных файлов.
Странно, почему опция copy all used libraries into the project folder неправильно срабатывает. Хмм, копирует то оно копирует заголовочные файлы, но не привязывает, неужели это должно быть в двух действиях.
Заголовок сообщения: Re: Структура GPIO_TypeDef для регистров. STM32
Добавлено: Пн май 02, 2022 09:51:28
Держит паяльник хвостом
Карма: 16
Рейтинг сообщений: 205
Зарегистрирован: Вс дек 02, 2012 16:58:33 Сообщений: 936 Откуда: от туда
Рейтинг сообщения:1
koeltrad, струкруру GPIO_TypeDef заполнять не надо. Почему никто не сказал, что это просто способ определить регистры GPIO, отображаемые в адресное пространство процессора? Именно обращение к ячейке памяти по адресу GPIOA->ODR устанавливает режим GPIO регистра ODR. А в оперативной памяти эту структуру создавать и поддерживать не надо. Почитайте про распределение адресного пространства в вашем процессоре между флэш, ОЗУ и периферией, тогда по адресу в памяти сразу поймёте, куда обращаетесь.
Ну как ет не сказал? Вроде ж как написал, что такое "указатель на структуру" и как он работает. Запись GPIOA->ODE после раздефайнивания превратится в указатель на структуру переменных.
Если в этой структуре поменять порядок следования регистров, то получим адреса несоответствующие регистрам? Правильный порядок такой: Moder Ottyper Ospeedr Pupdr IDR ODR BSRR А если сделать такой порядок: Ottyper Moder Pupdr Ospeedr ODR IDR BSRR То названия регистров не будут соответствовать адресам?
Если в структуре изменить порядок ячеек, то их названия уже не будут совпадать с названиями регистров. И да, в разных микроконтроллерах (в разных сериях) могут быть различия по составу регистров в периферии, это нормально. Все вопросы с регистрами проясняются после просмотра референс-мануала на микроконтроллер. в показанной таблице регистры IDR, ODR имеют только 16 активных бит, но в адресном пространстве занимают полные 4 байта. Поэтому в структуре сделаны промежутки в 16 бит, а регистры тоже представлены 16-битным типом.
И да, в разных микроконтроллерах (в разных сериях) могут быть различия по составу регистров в периферии, это нормально.
...А в некоторых микроконтроллерах имеет значение и разрядность операций обращения к регистру: в одних МК могут работать как 32- так и 16-битные и 8-битные обращения (к одному и тому же регистру), а в других МК - обращения с неверной разрядностью приводят к неверному результату или даже к fault-у. Поэтому - правильное описание регистра (как 8-разрядного, 16-разрядного или 32-разрядного) - важно. Оно не только из-за промежутков в адресации.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения