STM32.USART Назначение регистров

В контроллерах STM32 для настройки каждого модуля USART и работы с ними имеется по 7 регистров:

  1. USART_SR регистр статуса — содержит флаги, указывающие на состояние модуля;
  2. USART_DR регистр данных — в него пишем передаваемые данные и читаем принятые;
  3. USART_BRR регистр, определяющий скорость обмена;
  4. USART_CR1 управляющий регистр 1;
  5. USART_CR2 управляющий регистр 2;
  6. USART_CR3 управляющий регистр 3;
  7. USART_GTPR регистр делителя и задержки.

Регистров много, но пугаться не надо. Мы начнем с рассмотрения тех регистров и тех разрядов,которые необходимы для обеспечения асинхронного обмена с ПК или другим контроллером.

Начнем с регистра статуса USART_SR. В нем находятся флаги, указывающие на текущее состояние модуля. Анализируя их, ЦПУ должен соотвественно реагировать. Всего имеется 10 флагов, но мы обратим внимание на 6:

  • PE (разряд 0) — ошибка паритета при приеме байта. Можно задавать четное или нечетное число единиц в принимаемом байте. Если приняли байт, а в нем другое количество единиц, значит имеем ошибку (аппаратная проверка на ошибки). Весьма интересный флаг, но я его никогда не использовал (консервативность, что ли?).
  • FE (разряд 1) — ошибка кадра при приеме байта, т.е. первый стоп-бит принятой посылки равен «0″.
  • NE (разряд 2) — флаг наличия шума. Ставится аппаратно, когда обнаружен шум в принимаемом кадре.

Перечисленные выше флаги позволяют определить, что имеет место ошибка при приеме байта (говорю байт, хотя передаваемая посылка может иметь разрядность отличную от 8).
Очищаются они программно, последовательностью операций чтения регистра USART_SR, с последующим чтением регистра USART_DR.

Следующая группа флагов позволяет определить окончание передачи или приема данных:

  • RXNE (разряд 5) — в регистре данных приема есть данные, т.е. принят байт данных, нужно срочно что-то делать. Если в USART_CR1 бит  RXNEIE=1, то генерируется прерывание. Этот бит очищается чтением регистра USART_DR (это согласно описанию, но у меня он очищался только записью в него нуля :roll: ).
  • TC (разряд 6) — передача завершена. Если регистр передачи данных пуст (на что указывает флаг TXE регистра USART_SR) и в USART_CR1 бит TCIE=1, то генерируется прерывание.Очищается чтением USART_SR с последующей записью в USART_DR.
  • TXE (разряд 7) — регистр данных передачи пуст. Очищается программно, записью в регистр USART_DR новых данных.

В чем отличие TXE от TC ?
USART передает данные из сдвигового регистра. А в этот сдвиговый регистр они попадают из регистра DR: процессор записывает данные в DR и в нем они будут находиться  пока сдвиговый регистр не освободится. Как только он освободится (данные будут переданы) информация из DR будет переписана в него и будет установлен флаг TXE (регистр данных пуст). Если процессор на это никак не отреагирует, то по освобождению сдвигового регистра будет установлен также флаг TC.

Регистр USART_DR содержит байт принятых или передаваемых данных. Хотя в программе обращение происходит как бы к одному регистру, на самом деле он состоит из двух  - при чтении информация поступает из регистра приемника модуля, а при записи данные заносятся в регистр передатчика.
Для работы с регистром  данных используется следующая конструкция:
USART1->DR = data;       //передать байт
tmp = USART1->DR;        //прочитать принятый байт

Регистр USART_BRR определяет скорость обмена. Он немножко сложновастенький. Содержит переменную, определяющую скорость обмена. Эта переменная состоит из двух частей — основной и дробной. Благодаря дробной части можно весьма точно отстроить скорость обмена независимо от частоты тактового сигнала.
Скорость обмена вычисляется по формуле:

baud = fck / (16*USARTDIV)
где fck — входной тактовый сигнал (PCLK1 для USART2, 3  и PCLK2 для USART1);
USARTDIV — число с фиксированной точкой, которым закодирован регистр USART_BRR.

Сответственно USARTDIV = fck / (16*baud)

Если нужна скорость 9600 при fck=8MHz : USARTDIV = 8000000/(16*9600)=52,0833

Округляем до двух разрядов после запятой и получаем USARTDIV =52,08

Что же загрузить в USART_BRR? Обратим внимание на его структуру:

  • разряды 0..3 — DIV_Fraction, или дробная часть;
  • разряды 4..15 — DIV_Mantissa, или основная часть.

Не спешите записывать  08 в DIV_Fraction.

08 (т.е. полученный остаток) необходимо умножить на 16.

0.08 * 16 =  1.28 -> окрулив до ближайшего целого числа получим DIV_Fraction = 0×01 (если бы получили 10, то в шестнадцатеричной системе имели бы ox0A).

Преобразовав основную часть в hex, имеем  DIV_Mantissa = 0d52 = 0×34.

И, наконец, имеем значение регистра скорости передачи : USART_BRR = 0×0341.
Для записи в реальный регистр используется следующая запись:

USART1->BRR = 0x0341     //записать значение скорости в BRR модуля USART1

Есть одна маленькая загвоздочка — мы выполнили округление : было  52,08(3), а получили 52,08.
Какая погрешность? Вычислим ее. Для этого необходимо преобразовать полученное значение USART_BRR в  USARTDIV:

целая часть = 0×34 = 0d52,  дробная часть = 1/16 = 0.0625, USARTDIV = 52.0625 вместо первоначальных 52,0833.

Посчитаем ошибку настройки в процентах :

error =  100% - 52.0625*100 / 52,0833 = 0.04%.
Если я не ошибаюсь, ошибка вполне приемлемая.

Да, чуть не забыл. Если в результате вычислений получили DIV_Fraction  после округлений равен 16,
то необходимо выполнить перенос единицы в основную часть.

Постараюсь позже написать утилитку, которая вычисляет значение USART_BRR по заданным fck и baud. :-)

Дальше рассмотрим три управляющих регистра - USART_CR1USART_CR2, USART_CR3.
Рассматривать будем только необходимые для нашей задачи разряды.

Регистр  USART_CR1:

  • UE (разряд 13) разрешение работы USART : 1 — работает; 0 — не работает;
  • M  (разряд 12) длина слова: 0 — 8 бит данных; 1 — 9 бит данных;
  • PCE (разряд 10) разрешение контроля паритета: 0 — отключен; 1 -включен;
  • PS (разряд 9) тип паритета: 0 — четный; 1 — нечетный;
  • PEIE (8 разряд) разрешение прерывания при обнаружении ошибки паритета;
  • TXEIE (разряд 7) разрешение прерывания от TXE (когда регистр передачи пуст);
  • RXNEIE (разряд 6) разрешение прерывания от RXNE (в регистр данных перемещен принятый байт);
  • TE (разряд 3) разрешить работу  передатчика;
  • RE (разряд 2) разрешить работу  приемника;

Регистр  USART_CR2:

STOP(разряды 13,12) формат стоп-битов: 00 — стоп-бит, 01 — 0.5 стоп-бита, 10 -  2 стоп-бита, 11 — 1.5 стоп-бита;

Регистр  USART_CR3:

  • DMAT (разряд 7) разрешить работу передатчика через DMA;
  • DMAR (разряд 6) разрешить работу приемника через DMA;

На этом пока закончим рассматривать регистры.

Продолжим изучение усарта с рассмотрения примеров инициализации.

О первоисточнике можете узнать тут