Главная > STM32 > STM32 и неработающий USART

STM32 и неработающий USART

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

 

В данный момент я работаю над чем-то вроде транслятора протокола для проприетарной системы устройств. Этот самый транслятор собран на контроллере STM32F100C8 по той причине, что в оном чипе есть необходимые три USART’а. С ними (точнее, как будет видно дальше, с выводами контроллера, к которым они подключаются) и приключились странности. Я написал код, залил его в чип и приготовился наблюдать данные, выходящие со всех трех USART’ов (тест). Однако данные наблюдались только с одного канала, притом что, естесственно, инициализация у всех каналов абсолютно одинаковая. Я чесал репу, тыкал осциллографом и удивлялся; грешил на непропай… Но нет, все цепи звонились вполне нормально.

Потом я заметил интересную закономерность: проявлял себя ровно тот USART,  к которому был подключен мой переходничок USB-UART. Все выглядело так, как будто выходы сконфигурированы в режиме открытого стока — переходник подтягивает шину данных к единице и все работает, а когда тыкаешь осциллографом, то, конечно, ничего не видно. Но отчего? Я ведь конфигурировал их в режиме двухтактного выхода.

Разгадка оказалась простой. Режим работы конкретного вывода задается в регистрах GPIOx_CRH и GPIOx_CRL. Для каждой ножки там имеется набор из двух битов MODE и двух битов CNF. Биты MODE задают режим работы — вход или выход с задаваемой максимальной скоростью; биты CNF — режим работы, в случае выхода это открытый коллектор или двухтактный выход. При этом, назначение битов CNF меняется соответственно режиму, заданному битами MODE.

Проблема оказалась в том, что изначально выходы настроены на высокоимпедансный вход. Это, конечно, разумно. Только вот высокоимпедансный вход в виде CNF-битов обозначается вовсе не нулем, а значением 0b01.

Чтобы в режиме выхода подключить двухтактный каскад для альтернативной функции, надо записать в CNF значение 0b10. Ну я и записал — операцией побитового ИЛИ. Однако же, очевидно, при этом там осталась и единичка по умолчанию, стоящая в младшем бите соответствующего CNF-поля. Таким образом, суммарно там получилось 0b11, а это значение уже обозначает режим открытого стока, который я и наблюдал. Вот так.

Решил я это простым обнулением регистров GPIOx_CRH/ GPIOx_CRL перед записью в них конфигов, чтобы не заморачиваться со снятием конкретных битов. При этом для остальных выводов получается, что они находятся в режиме аналогового входа, что, в общем, не страшно.

Для большей понятности цитата из даташита с комментариями:

gpio_configКакая мораль? Безусловно, ненулевое по умолчанию значение регистра — это плохо, так как сбивает с толку. Тем более, что чаще всего встречаются регистры, после сброса все же содержащие ноль во всех битах. А тут какая-то экзотика… Тем не менее да, внимательное чтение документации спасает и тут.

Рубрики:STM32
  1. neiver
    07/04/2014 в 17:19

    Лучше настраивать всю периферию так, чтоб не зависить от значений по умолчанию. Состояние в момент инициализации чего-либо может быть не вполне определено всилу разных причин: использованный загрузчик, невнимательное чтение документации, ошибки в документации, различное поведение в разных ревизиях чипов. Я придерживаюсь практики инициализировать все причастные биты во всех причастных регистрах явно, даже если значение по умолчанию устраивают — потом меньше сюрпризов.

    • YS
      07/04/2014 в 19:12

      Это-то да, самый правильный метод, разумеется. Просто я очень привык, что в регистрах после сброса всегда ноль.🙂 Тем более, что загрузчиков я тут не использую.

  2. Алексей
    06/04/2014 в 10:20

    Эх, хотелось бы продолжения про фильтры)). Спасибо за статьи!

    • YS
      06/04/2014 в 13:31

      OK, как только появится время, напишу. В принципе, у меня и сырой материал уже лежит, все делалось одновременно с первой статьей. Но пока у меня есть две заботы — доделать ту систему, про которую говорится в этой статье, и сделать так, чтобы меня все же не выперли из универа.🙂

      • Алексей
        06/04/2014 в 13:40

        Удачи! Будем ждать..

        • YS
          06/04/2014 в 14:35

          Спасибо.

          Ну вот, напомнили тут, открыл маткад, начал свертку мучать.🙂

  3. shads
    05/04/2014 в 21:54

    У меня тоже лежат 10шт именно таких же, программатор есть, но я все никак не возьму себя в руки, чтобы стартануть :)…
    Вроде и страничек нарыл с быстрыми стартами, да все никак не решусь…

    А вы с STM-ками давно работаете? Ну в общем у вас с ними быстро дело пошло?

    • YS
      05/04/2014 в 23:02

      Врать не буду, это мой первый серьезный коммерческий проект на STM32. До этого только развлекался с демоплатами, которые в избытке нахаляву выдавали на семинарах.🙂

      На самом деле, в STM32 нет ничего ужасно сложного в смысле освоения; если отбросить маркетинговую шелуху — контроллер как контроллер. Вообще, со временем ко мне пришло понимание что, в общем, все контроллеры одинаковы по парадигме, а в смысле освоения отличаются только названиями регистров и структурой документации.🙂 Последняя, в принципе, после AVR может слегка удивлять, потому что сведения тут раскиданы по куче документов, но все не так сложно, как может показаться. Так что смело беритесь за них, если есть такое желание и/или необходимость. Кстати о необходимости — у меня, например, нет задач для старших серий STM, так что я их даже не трогаю.

      Если интересует мое мнение, то я мог бы сформулировать несколько постулатов из опыта:

      1. STM очень агрессивно пропихивает свою библиотеку стандартных драйверов для периферии (StdPeriphLib). Мне кажется, что это чисто маркетинговая вещь — код с использованием этой самой библиотеки выглядит слишком нагроможденным и скрывает суть происходящего, притом что по факту не слишком отличается от прямой записи в регистры — то же распихивание значений по структурам. Мало того, эта самая библиотека местами еще и глючна.

      Так что я послал эту StdPeriphLib лесом и работаю напрямую с регистрами. Для меня это выглядит гораздо понятнее, да и если какие глюки есть, так только глюки аппаратуры.

      2. Лучшая среда для написания кода и отладки — ИМХО IAR. Даже kickstart-версии вполне хватает для большинства задач. Хотя некоторые люди, привыкшие к Visual Studio, жалуются, что он слишком аскетичен. Но меня устраивает.

      3. В принципе, есть некоторые новые моменты, связанные, в основном, с настройкой IDE при создании проекта и, например, обработкой прерываний (сразу скажу, что она, на самом деле, очень проста), но все это не слишком принципиально.

    • YS
      05/04/2014 в 23:07

      Может быть, при наличии интереса у аудитории, когда буду посвободнее, я даже напишу статейку про освоение STM32 после AVR. Но, боюсь, теперь время писать серьезные статьи у меня появится не раньше лета.

      • shads
        07/04/2014 в 23:55

        И тем не менее… будем ждать описания «красочных очучений», испытываемых при переходе с AVR-ок на STM-ки :)…..

        • Vga
          08/04/2014 в 07:37

          Самое красочное ощущение — «FUCK YEAH, ОТЛАДКА!!!». В остальном — никакой разницы.

        • YS
          08/04/2014 в 16:08

          В целом, Vga прав.🙂 Вопреки дифирамбам маркетологов, ничего сверхвыдающегося/сверхсложного в STM32 нет. Контроллеры как контроллеры, со своими преимуществами и своими недостатками.

          Я вот кстати недолюбливаю ST за маркетинговый шум.

          Отладка через SWD/JTAG это да, прикольно. Можно остановить выполнение в реальном устройстве, наживую посмотреть значения регистров и прочего. Но я сознательно написал «прикольно» а не «полезно». Особой суперпользы от этого я не заметил; от запоминающего осциллографа, например, в смысле отладки в большинстве случаев пользы на порядок больше. Но прикольно, да.

          И я, к слову, сознательно пишу не «переход» а «освоение». Я, например, ныне по мере необходимости использую и AVR (дешевле в мелких партиях), и STM32 (дешевле в крупных партиях), и MSP430 (очень приятная архитектура, легко управлять энергопотреблением). Надо будет — и на PIC сделаю, я с ними работал на предыдущей работе. На STM8 тоже устройство было, чисто ради интереса. Просто AVR занимают место в моем сердце на правах первой любви, а MSP430 приятны как аскетичые (особенно в младших сериях) МК.🙂

          А так, если говорить о освоении STM32 с базы в виде AVR, то самое сложное — привыкнуть к структуре документации, понять, что где искать — если таки сподоблюсь написать философскую статью на тему, остановлюсь на этом специально. После возникновения этого понимания все протекает совершенно спокойно.

  1. No trackbacks yet.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s