Eugene's MCU

Среда, 19.11.2014, 06:54

Главная | | Мой профиль | Выход | RSS
Меню сайта
Категории каталога
Рекламный блок





Рекомендовать этот сайт:

Главная » Статьи » » STM8


Модуль UART STM8. Справочные данные

     Модули UART микроконтроллеров STM8 реализованы в трёх различных исполнениях: UART1, UART2 и UART3. При этом цифровые индексы в названиях модулей для конкретной модели указывают именно на вариант исполнения, а не на их порядковый номер в составе данной модели.
     Все вместе модули UART обеспечивают следующие основные возможности:
  • Асинхронный режим с поддержкой многопроцессорного обмена;
  • Синхронный режим;
  • Режим "Smartcard” ;
  • Режим поддержки инфракрасных приёмопередатчиков IrDA;
  • Полудуплексный (однопроводной) режим;
  • Интерфейс LIN в режиме master и slave.
     При этом модуль UART1 поддерживает весь указанный набор функций, кроме режима  LIN Slave. UART2 не поддерживает обмен данными в однопроводном режиме. UART3 может работать только в асинхронном режиме с поддержкой многопроцессорного обмена, а так же режимах LIN master и slave.
     Далее будет описана последовательность действий по инициализации модулей UART для работы в традиционном асинхронном режиме обмена.

§ > Разрешение выводов UART  
  
     Для переключения выводов UART из состояния портов общего назначения в состояние UART_RX, TX необходимо установить биты TEN и REN регистра UART_CR2:
 
   
   #include "iostm8s105c6.h" 
   UART2_CR2 |= (MASK_UART2_CR2_REN)|(MASK_UART2_CR2_TEN); // Разрешить TX, RX.

       Примечание: здесь и далее имена регистров и битовых масок под компилятор IAR.

§ > Задание скорости обмена 
   
     Скорость обмена (BaudRate) определяется значением регистра делителя частоты тактирования UART, которое не может быть меньше 16 и рассчитывается по формуле:
     UART_DIV =  Fmaster / BaudRate.
 
     Два байта значения UART_DIV записываются в регистры делителя по следующему правилу: старшая и младшая тетрады шестнадцати разрядов коэффициента деления записываются в старшую и младшую тетраду регистра BRR2, две средние тетрады значения UART_DIV записываются в регистр BRR1. При этом вначале необходимо записывать регистр BRR2, а затем BRR1.
     Программа для расчёта инициализационных значений регистров BRR1, BRR2 приведена в конце статьи. Так, например, для UART1 с тактированием от 16МГц, при скорости обмена 9600 bps, значение коэффициента деления будет равно 0x0683, а инициализационный код должен выглядеть так:
  
       
   UART1_BRR2 = 0x03; UART1_BRR1 = 0x68;
  
 
§ > Формат кадра
  
     Длина слова данных кадра UART определяется состоянием бита M в регистре UARTn_CR1. Если он сброшен, осуществляется приём и передача 8 бит данных, если установлен – 9 бит. В девятибитном режиме обмена значение девятого разряда при передаче извлекается из бита T8 регистра UARTn_CR1, а при приёме копируется в бит R8 того же регистра.
     Количество стоп-битов задаётся комбинаций разрядов 4 и 5 в регистре  UARTn_CR3:
 
     Bits 5:4= 00: 1 стоп бит;
     Bits 5:4= 01: Зарезервировано;
     Bits 5:4= 10: 2 стоп бита;
     Bits 5:4= 11: 1.5 стоп бита (используется в режиме "Smartcard”).

     Для включения режима контроля чётности/нечётности необходимо установить бит PCEN регистра UARTn_CR1. При этом контрольный разряд займёт место последнего бита данных, бит7 и бит 8 для 8- и 9-разрядного режима обмена соответственно. Назначение контрольного разряда определяется состоянием бита PS в регистре UARTn_CR1: 
 
     Bit 1 = 0: Even parity (контроль чётности);
     Bit 1 = 1: Odd parity (контроль нечётности).
 
     Бит чётности устанавливается в единицу при нечётном количестве установленных разрядов в слове данных, бит нечётности при чётном. Таким образом, биты дополняют число единичных битов до чётного и нечётного значений соответственно. В режиме передачи контрольный разряд формируется автоматически, при приёме происходит его расчёт и сравнение с принятым значением. В случае получения ошибочного значения контрольного разряда в статусном регистре UARTn_SR устанавливается бит PE (Parity error).
  
      Пример инициализации:
   
   // Разрешить выводы TX, RX.   
   UART2_CR2 |= (MASK_UART2_CR2_REN)|(MASK_UART2_CR2_TEN); 
   UART2_CR3_STOP=2; // Bits 5:4= 10 два стоп-бита.
   // Режим 9 бит, контроль нечётности.
   UART2_CR1 |= (MASK_UART2_CR1_M)|(MASK_UART2_CR1_PCEN)|(MASK_UART2_CR1_PS);
   UART2_BRR2 = 0x0B; UART2_BRR1 = 0x08; // BaudRate = 115200.

  

§ > Режим передачи данных
 
     Передающий тракт UART состоит из двух регистров: предварительного буферного регистра TDR и сдвигового регистра, осуществляющего непосредственную побитовую отправку кадра в линию TXD.
После записи байта в регистр UART_DR он сразу же перемещается в буферный регистр TDR, при этом сбрасывается флаг готовности буфера TXE в регистре UARTn_SR. Если на текущий момент сдвиговый регистр оказывается свободным, байт переписывается в него, начинается его отправка и флаг TXE снова устанавливается в единицу. Если же сдвиговый регистр занят, записанный байт будет ожидать завершения отправки текущего байта в буфере TDR. Таким образом повторная запись в UART_DR при занятом буфере (бит TXE сброшен) приведёт к потере ожидающего отправки байта.
  
      Пример кода для циклической отправки байта по флагу TXE:
   while(1)
   {
       while (!(UART2_SR_TXE)) {} // Ожидать освобождения буфера TDR.
       UART2_DR='S'; // Отправить символ "S".
   }

     
      Для индикации фактического завершения передачи байта по UART предназначен флаг TC (transmission is complete) регистра UARTn_CR2. Он устанавливается аппаратно после передачи последнего бита в линию TXD, но при условии, что в передающем буфере TDR нет байта ожидающего пересылки в сдвиговый регистр (TXE=1). Таким образом, при непрерывной передаче конечной последовательности байт по факту освобождения буфера TXE=1, из-за постоянной его занятости, флаг TC установиться только один раз после фактической передачи последнего байта последовательности.
 
      При установке флагов TXE и TC возможен вызов прерывания, если при этом в регистре UARTn_CR2 установлены биты TIEN и TCIEN соответственно. Режиму передачи UART сопоставлен всего один вектор прерывания, а значит при разрешении двух прерываний одновременно, фактический источник, вызвавший данное прерывание нужно определять программно по состоянию соответствующих флагов.
  
      Пример программы передающей строку по прерыванию от TXE:
   
   #include "iostm8s105c6.h" 
   #include "intrinsics.h" // Здесь описана функция __enable_interrupt ().
   unsigned char HELLO[]="Hello, I'm STM8S105C6, but who are you?";
   unsigned char *byteNum = HELLO; // Указатель на передаваемый байт.
   void main (void)
   {
        CLK_ECKR_HSEEN=1; // Разрешаем работу генератора с внешним кварцем (HSEEN). 
        CLK_SWCR_SWEN=1; // Разрешаем переключение генераторов. 
        CLK_SWR=0xB4; // Тактирование от кварцевого генератора (HSE). 
        CLK_CKDIVR=0;  //  Делители частоты на 1 - частота ядра максимальная. 
        while (CLK_CMSR!=0xB4);  // Ждем стабилизации частоты.
        UART2_CR2_REN=UART2_CR2_TEN=1; // Разрешить выводы TX, RX. 
        UART2_BRR2 = 0x0B; UART2_BRR1 = 0x08; // BaudRate = 115200. 
        UART2_CR2_TIEN=1;  // Разрешить прерывание по TXE. Начало передачи. 
        __enable_interrupt (); // Разрешаем прерывания. 
        while (1)
        {
        }
   }
   #pragma vector=UART2_T_TXE_vector // Прерывание по освобождению буфера.
   __interrupt void UART2_TXE(void)
   {
        if (*byteNum) {
UART2_DR=*byteNum; byteNum++; } // Отправить байт.
        else UART2_CR2_TIEN=0; // Запретить прерывания по TXE, всё передано.
   }

      
  
§ > Режим приёма данных

     По завершении приёма, байт данных из сдвигового регистра перемещается в буферный регистр RDR, при этом устанавливается бит RXNE регистра статуса UARTn_SR. После чего принятый байт становиться доступным при помощи чтения регистра данных UART_DR, которое, в свою очередь, сбрасывает флаг RXNE.
     Если до момента окончания приёма очередного байта, значение байта хранящегося в RDR не было считано или бит RXNE не был сброшен принудительно, микроконтроллер зафиксирует ошибку переполнения входного буфера (Overrun error),  устанавливив бит OR регистра UARTn_SR. Для разрешения прерывания по флагу RXNE необходимо установить бит RIEN регистра UARTn_CR2. 
     Пример программы с приёмом, декрементом и отправкой байта по UART:
 
  
     #include "iostm8s105c6.h"
     #include "intrinsics.h" //Здесь описана функция __enable_interrupt()

     void main( void )
     {
          CLK_ECKR_HSEEN=1; // Разрешаем работу генератора с внешним кварцем (HSEEN)
          CLK_SWCR_SWEN=1; // Разрешаем переключение генераторов;
          CLK_SWR=0xB4; //Выбираем clock от кварцевого генератора (HSE)
          CLK_CKDIVR=0; //Делители частоты на 1 - частота ядра максимальная.
          while(CLK_CMSR!=0xB4); //Ждем стабилизации частоты
          UART2_CR2_REN=UART2_CR2_TEN=1; // Разрешить выводы TX, RX.
          UART2_BRR2 = 0x0B; UART2_BRR1 = 0x08; // BaudRate = 115200.
          UART2_CR2_RIEN=1; // Разрешить прерывание по RXE.
          __enable_interrupt(); //Разрешаем прерывания
          while(1)
          {
          }
     }

     #pragma vector=UART2_R_OR_vector
     __interrupt void UART2_RXE(void)
     {
          UART2_DR=++UART2_DR; // Декремент и отправка принятого числа.
     }
      
 
     Проект IAR_STM8 >> STM8UART.RAR

Автоматический расчёт битрейта UART STM8 и его точности.

Введите частоту тактирования UART, МГц:
Введите ожидаемый битрейт, bps





При использовании материалов сайта ссылка на данный источник обязательна.

Категория: STM8 | Добавил: eugenemcu (17.11.2010) | Автор:

Просмотров: 10996 | Комментарии: 3 | Рейтинг: 4.0/2 |
Всего комментариев: 3
0 Спам
* 1 (21.12.2010 05:24) [Материал]
Правильней писать не
UART2_CR2 |= (MASK_UART2_CR2_REN)|(MASK_UART2_CR2_TEN); // Разрешить TX, RX.
а
UART2_CR2 = (MASK_UART2_CR2_REN)|(MASK_UART2_CR2_TEN); // Разрешить TX, RX.
Сравните код и вы поймёте.

0 Спам
* 2 eugenemcu (21.12.2010 09:58) [Материал]
К сожалению, не понял Вашу мысль. Зачем мне сбрасывать остальные биты в этом регистре? Может быть, я посреди программы решил воспользоваться этими выводами как GPIO, а потом снова решил вернуться к работе с UART. И при этом не хочу сбрасывать, скажем, разрешения прерываний, которые установил до этого.
В инициализационной части программы сделал бы точно так, как вы написали. А это общий пример работы с битами, не должен зависеть от контекста программы.

0 Спам
* 3 (31.08.2011 04:11) [Материал]
Блин, у меня почему то RXNE не сбрасывается!! Написал тупо эхо - без прерываний, хотя и с ними пробовал. Работаю от RC внутреннего.

while (1) {

if (UART2_SR_bit.RXNE == 1) {
Result = UART2_DR;
UART2_DR = Result }

и как только отправляю что нибудь в МК, на выход сразу же бесконечно много этих символов! В чём проблема, не подскажете?!

Статистика

Наш магазин




Какую среду разработки Вы используете?

[ Результаты · Архив опросов ]
Всего ответов: 1628



Им нужна Ваша помощь: