Разбираемся с UART
Сегодня я решил рассказать об UART'е. Вместо ведения будет выдержка из моего дипломного проекта:
«Универсальный асинхронный или универсальный синхронно / асинхронный приемопередатчик (Universal Synchronous / Asynchronous Receiver and Transmitter - UART или USART) - удобный и простой последовательный интерфейс для организации информационного канала обмена данными микроконтроллера с внешним миром. Способен работать в полудуплексном(только прием или передача данных) и полнодуплексном режиме (одновременная передача и прием данных). UART поддерживает протокол стандарта RS-232, что обеспечивает возможность быстрой организации связи с персональным компьютером.»
Осталось добавить, что используется всего 2 сигнальных провода: первый – прием,второй – передача данных. Обозначаются RX и TX соответственно, ну и общий GND…куда ж без него?
Теперь, что касается USART STM32. Управляет этим модулем 7 регистров:
SR – status register
DR – data register
BRR – baud rate register
CR1 – control register 1
CR2 – control register 2
CR3 – control register 3
GTPR – guard time and prescaler register
Самое сложное, как на мой взгляд – настройка предделителя тактовой частоты (регистр BRR). Он несколько хитро устроен. Дело в том, что с помощью целых значений этого регистра можно очень точно кодировать дробные значения предделителя.
Итак, приступим: из руководства по программированию известно, что модуль UART STM32 тактируется от шины АРВ2(стр. 83). В моей отадочной плате STM32F1-Discovery шина АРВ2 настроена на частоту 24 МГц, а модуль UART я хочу настроить на скорость обмена в 9600 бод. Воспользовавшись формулой из руководства по программированию (стр. 588) считаем:
FUART=FAPB2/(16*BRR), где
FUART – желаемая частота UART.
FAPB2 – частота шины АРВ2.
BRR – значение предделителя.
Если с первыми двумя составляющими все ясно. То со третьим мне пришлось поломать голову. Итого, имеем следующие параметры:
FUART – 9600 бод
FAPB2 – 24 000 000 Гц
BRR – считаем!
BRR= (FAPB2/ FUART)/16
Подставляем значения и получаем => (24000000/9600)/16
Сначала действия в скобках ;) => 2500/16
Итого значение предделителя равно => 156,25
Теперь посмотрим на регистр BRR. Он состоит из 2х частей:
0-3 биты – дробная часть значения.
15-4 биты – целое число.
Сперва вычисляем дробное значение: для этого умножим дробную часть на 16. В нашем примере: 0,25*16=4 (4h). Если получилось дробное число, то необходимо округлить по правилам математики, например: из8,3 получаем 8, а из 2,9 получаем 3.
Теперь вычисляем целую часть: Если после вычисления дробной части в результате не получилось число 16, то просто напросто отбрасываем дробную составляющую и записываем в регистр, т.е в текущем примере просто пишем 156 ( 9Ch ). Но если бы у нас дробное значение получилось 16, то его надо было бы анулировать, а в значение к целой части прибавить 1.
Итак, в нашем примере значение регистра BRR = 9C4h.
Еще один пример:
FUART – 2400 бод
FAPB2 – 997632 Гц
BRR –считаем!
BRR= (FAPB2/ FUART)/16
Подставляем значения и получаем => (997632/2400)/16
Сначала действия в скобках ;) => 415,68/16
Итого значение предделителя равно => 25,98
Вычисляем дробное значение: 0,98*16=15,68 - округляем по правилам математики и получаем до 16 Тогда целое значение равно 25+1=26 (1Ah), а дробное 0. Таким образом значение регистра BRR = 1А0h.
Конечно, такая тактовая частота шины АРВ2 является вымышленной, но например в тех же AVR часто используются кварцевые резонаторы с дробной частотой( например, 4.433619 МГц или 8.867238 МГц), которые позволяют получить точные значения предделителя UART. Такие заморочки нужны потому, что интерфейс UART AVR очень скромный в плане всяких настроек. А синхронизация обмена данными происходт по времени, и если в приемнике и передатчике один такт будет длиться разное время, то передача может пойти с ошибками.
Таким образом можно сделать вывод, что в STM32 настройка несущих частот программная, а в AVR – аппаратная. Это, как для меня, еще один плюс 32-х разрядникам!