Вопросы по регистрам GPIO

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Сообщение TmYAG »

Здравствуйте уважаемые форумчане.
Начал изучение stm32f4, имея на руках платку discovery.
Решил помигать диодиками. В процессе изучения Reference manual и ознакомления с заголовочным файлом stm32f4xx.h появились вопросы.
1. В заголовочных файлах есть описания регистров BSRRL и BSRRH один регистр GPIO port bit set/reset low register другой GPIO port bit set/reset high register. Прошу пояснения в чем разница между ними?
2. Так же в том же файле есть описания
#define GPIO_MODER_MODER0 ((uint32_t)0x00000003)
#define GPIO_MODER_MODER0_0 ((uint32_t)0x00000001)
#define GPIO_MODER_MODER0_1 ((uint32_t)0x00000002)
И так на каждую лини по три таких строчки
MODER -это регистр установки линии порта на вход выход, аналоговый сигнал или режим альтернативного функционирования. Вот и возник вопрос почему режима четыре, а строчки три? Или я чего-то не понял?
А еще совсем нубский вопрос касающийся шестнадцатиричных чисел. И записи в регистр какого-либо значения.
Допустим есть регистр MODER. Чтобы проинициализировать каждый вывод регистра надо 2 бита. 16 линий => 32 бита надо установить. Пусть 15, 14, 13, 12 линии я конфигурирую как 01, значит в регистр я должен записать 01010101000000000000000000000000 (это двоичная система-верно? ноль вначале можно откинуть?). Теперь к вопросу. Я в примерах встречал что эта запись аналогична записи в 16х системе 0х55000000 собственно как это получается? И почему у меня в наглую не получилось записать в регистр MODER двоичное число? Спасибо за ответ
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3793
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

1. Верхняя часть регистра для установки соответствующего пина порта в 0 а нижняя - в 1. См. описание BSRR регистра в ДШ.

2. Константа MODER0_0 - для установки одного из битов, определяющих режим порта, MODER0_1 - для другого, а MODER0 - для обоих сразу. При конфигурировании бита на ввод, никакую из этих констант в регистр PORTx_MODER загружать не надо.

По поводу 16-ичной системы, см. в гугле. Например здесь:
http://www.5byte.ru/11/0006.php

Можно и двоичное число в регистр записать. См. синтаксис в документации на свой компилятор. В наглую не получится, т.к. откуда компилятору знать что это двоичное число, а не огромное десятичное? Даже если число маленькое и укладывается в диапазон int, например 101. Если напишете 101 то компилятор по дефолту воспримет его как десятичное, а не 5.
Последний раз редактировалось Ser60 Чт май 29, 2014 00:12:34, всего редактировалось 1 раз.
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Сообщение Myp3ik »

1. Запись "1" в BSRRL устанавливает порт в "1", а запись "1" в BSRRH устанавливает порт в "0";

2. Запустите в виндовс калькулятор и нажмите Alt+3
Иван Сусанин - первый полупроводник :solder:
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Сообщение TmYAG »

1. Ага понятно. Я просто думал, что для выставления высокого/низкого уровней надо в регистр писать 1 или 0. Оказывается для каждого из состояний свой регистр.
2.
Константа MODER0_0 - для установки одного из битов, определяющих режим порта, MODER0_1 - для другого, а MODER0 - для обоих сразу. При конфигурировании бита на ввод, никакую из этих констант в регистр PORTx_MODER загружать не надо.
То есть MODER0 устанавливает 1:1, что соответствует аналоговому режиму; MODER0_0 устанавливает 1:0, это альтернативный режим; MODER0_1 устанавливает 0:1 это режим выхода. А для состояния 0:0 константы нет?
3. Тут более менее понятно.
А чем тогда отличаются константы GPIO_BSRR_BS_x и GPIO_BSRR_BR_x ? В своей программе я использовал GPIO_BSRR_BS_x, чтобы вкл/выкл светодиоды. Для чего нужен второй?
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3793
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Константа для состояния 0:0 не нужна, т.к. она равна 0.

Похоже, вы так и не поняли: BS (bit set) - для установки 1, а BR - (bit reset) - для установки 0. Попробуйте их в отладчике и посмотрите что будет - так дойдет быстрее.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

TmYAG писал(а):То есть MODER0 устанавливает 1:1, что соответствует аналоговому режиму; MODER0_0 устанавливает 1:0, это альтернативный режим; MODER0_1 устанавливает 0:1 это режим выхода. А для состояния 0:0 константы нет?
В общем случае нет, не верно. Допустим значение регистра REG равно 111 (здесь и далее все в двоичной системе), тогда конструкция REG=MODER0_0 установит альтернативный режим, вместе с этим сбросив все остальные биты в ноль, что скорее всего не требовалось, то есть так делать нельзя.

Конструкция REG|=MODER0_0 не затронет чужие биты, но и свои в ноль не сбросит и значение REG останется равным 111, то есть альтернативный режим не будет выбран. Это сработает только в том случае, если первые два бита REG будут равны нулю. С другими режимами будут те же проблемы, неохота перечислять все возможные комбинации.

Чтобы наверняка задать нужный режим, не повредив при этом остальные биты необходимо делать так:

Код: Выделить всё

REG &= ~MODER0;
REG |= MODER0_0; // Или другой необходимый режим.
Я это все к тому, что тупое присвоение REG=MODER0_0 или REG=MODER0_1 скорее всего не будет работать как надо и является в общем случае неправильным.
Ser60 писал(а):Можно и двоичное число в регистр записать. См. синтаксис в документации на свой компилятор.
Стандарт Си, как и Си++ не поддерживает целочисленные литералы в двоичном формате, поэтому не стоит их использовать.
Реклама
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Сообщение TmYAG »

Ser60 писал(а): Похоже, вы так и не поняли: BS (bit set) - для установки 1, а BR - (bit reset) - для установки 0. Попробуйте их в отладчике и посмотрите что будет - так дойдет быстрее.
На самом деле вопрос возник не на пустом месте. Про сет/ресет я понял. Просто в этом фрагменте

Код: Выделить всё

GPIOD->BSRRL = GPIO_BSRR_BS_12;
  SystemDelay(2000000);
  GPIOD->BSRRL = GPIO_BSRR_BS_13;
  SystemDelay(2000000);
  GPIOD->BSRRL = GPIO_BSRR_BS_14;
  SystemDelay(2000000);
  GPIOD->BSRRL = GPIO_BSRR_BS_15;
  SystemDelay(2000000);
  GPIOD->BSRRH = GPIO_BSRR_BS_12;
  SystemDelay(2000000);
  GPIOD->BSRRH = GPIO_BSRR_BS_13;
  SystemDelay(2000000);
  GPIOD->BSRRH = GPIO_BSRR_BS_14;
  SystemDelay(2000000);
  GPIOD->BSRRH = GPIO_BSRR_BS_15;
Если я захочу погасить светодиоды я использую

Код: Выделить всё

 GPIOD->BSRRH = GPIO_BSRR_BS_x;
В то же время исходя из того, что я узнал, можно не использовать BSRRH, для установки на нужном выводе 0
А можно сделать его ресет. То есть я могу написать:

Код: Выделить всё

 GPIOD->BSRRL = GPIO_BSRR_BR_x;
Но при такой записи IAR выдает предупреждение:
Warning[Pe069]: integer conversion resulted in truncation C:\Users\User\Documents\IAR Projects\ARMProjects\main.c 34
Вот я и подумал, что делаю что-то не так.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

TmYAG писал(а): Но при такой записи IAR выдает предупреждение:
Warning[Pe069]: integer conversion resulted in truncation C:\Users\User\Documents\IAR Projects\ARMProjects\main.c 34
Вот я и подумал, что делаю что-то не так.
пАтамуШта в хэдере у F4 косяк .
Друг Кота
Аватара пользователя
Сообщения: 3793
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

menzoda писал(а):Стандарт Си, как и Си++ не поддерживает целочисленные литералы в двоичном формате
Согласен. Однако некоторые С компиляторы поддерживают различные расширения С. Например, GCC допускает префих 0b для инициализации в двоичной системе. В нем инструкция "int a = 0b101;" присвоит переменной а значение 5.
TmYAG писал(а):Но при такой записи IAR выдает предупреждение ...
Это только предупреждение. Работает-ли сама программа?
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

Ser60 писал(а):Это только предупреждение. Работает-ли сама программа?
Как оно может работать... если там косяк??? Злокопипаст... рудимент...
"Я не даю готовых решений, я заставляю думать!"(С)
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Сообщение TmYAG »

Ser60 писал(а):Это только предупреждение. Работает-ли сама программа?
Нет, программа не работает. Значит единственно верный вариант это устанавливать BSRRH в 1
Но тогда вопрос остается открытым. для чего нужен BR (даже если он bit reset)
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Сообщение Myp3ik »

TmYAG, BR был нужен для контроллеров 100 серии где BSRR 32-разрядный, там младшая его часть отвечает за установку порта, а старшая за сброс. Здесь BSSRL 16 бит и маски BR устанавливают биты за его пределы, вот IAR и не понимает как же так :shock:
Иван Сусанин - первый полупроводник :solder:
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Myp3ik писал(а):TmYAG, BR был нужен для контроллеров 100 серии где BSRR 32-разрядный
Ты не поверишь ... Он как был 32х разрядным так и остался . :)))


Изображение



Блажь пришла в головы индусам .


Здесь как.
Или править хедер


Код: Выделить всё

typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
 // __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
 // __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t BSRR;
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;
Или юзать BSRRH и BSSRL применяя только маски GPIO_BSRR_BS_x


В любом случае TmYAG в первую очередь надо научится читать документацию ...
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Сообщение Myp3ik »

dosikus, а я и не говорил, что его разрядность изменилась 8) . У 400 серии он разбросан по двум 16-разрядным полям структуры. Мы же говорим о работе с регистрами через описывающую его структуру, а не напрямую через область памяти.

А даташит я посмотрел в первую очередь :solder:

Код: Выделить всё

typedef struct
{
  __IO uint32_t MODER;      /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;     /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;      /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;          /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;         /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint16_t BSRRL;      /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;     /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;       /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];     /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;

Иван Сусанин - первый полупроводник :solder:
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Myp3ik писал(а):dosikus, а я и не говорил, что его разрядность изменилась 8) .
Надо же . :))) А это - "BR был нужен для контроллеров 100 серии где BSRR 32-разрядный," не твои слова ?
На остальное я уже дал ответ ...
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Сообщение Myp3ik »

Да неоднозначно. Имелось в виду, что в структуре ему было выделено 32 бита :roll:
Иван Сусанин - первый полупроводник :solder:
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Сообщение TmYAG »

dosikus писал(а):
В любом случае TmYAG в первую очередь надо научится читать документацию ...
Дав том и дело, что в документации про BSRRL BSRRH ничего не написано, а написано про BSRR. А в структуре наоборот)))
В любом случае не ругайтесь((( я новичок)))) еще не раз глупые вопросы увидите от меня на этом форуме. Я настырный. А иначе не научиться :roll:
Ответить

Вернуться в «ARM»