
UART – один из наиболее распространённых интерфейсов для обмена данными между микроконтроллерами и периферией. В среде разработки Keil C51 его настройка требует точного управления регистрами контроллера серии 8051. Для эффективной реализации передачи данных важно учитывать скорость передачи, формат кадра и обработку ошибок.
В Keil C51 настройка UART начинается с конфигурации регистров SCON и TMOD, а также выбора подходящего таймера для генерации baud rate. Практические примеры показывают, как добиться стабильной передачи при стандартных скоростях 9600 и 115200 бод, используя таймеры 0 или 1 в режиме 2 или 1 соответственно.
Обработка прерываний UART значительно повышает надёжность передачи данных. В статье рассмотрены методы реализации приёмника и передатчика с использованием флагов TI и RI, а также советы по минимизации потерь данных при высоких скоростях передачи. Особое внимание уделено синхронизации и буферизации, что критично для приложений реального времени.
Настройка регистров UART для передачи в микроконтроллерах 8051

Для корректной передачи данных по UART в 8051 необходимо последовательно настроить несколько ключевых регистров, обеспечивающих работу последовательного интерфейса.
- SCON (Serial Control) – основной регистр управления UART.
- Режим работы задаётся битами SM0 и SM1:
- SM0=0, SM1=1 – режим 1, 8-битный UART с переменной скоростью.
- Этот режим наиболее часто используется для стандартного обмена.
- Регистр также содержит биты REN (разрешение приёма) и TI (флаг окончания передачи).
- Перед передачей TI нужно сбросить в 0, затем установка TI в 1 указывает на готовность к следующему байту.
- Режим работы задаётся битами SM0 и SM1:
- TMOD (Timer Mode) – настройка таймера, служащего генератором скорости передачи.
- Для UART в режиме 1 обычно используется таймер 1 в режиме 2 (8-битный авто-перезагрузка).
- Для этого необходимо записать в TMOD значение 0x20 (Timer1 – режим 2).
- TH1 (Timer 1 High Byte) – загрузка значения, определяющего скорость передачи.
- Формула расчёта: TH1 = 256 — (Oscillator Frequency / (12 × 32 × Baud Rate))
- Например, для кварца 11.0592 МГц и скорости 9600 бод TH1 = 256 — (11059200 / (12 × 32 × 9600)) = 256 — 36 = 220 (0xDC).
- TCON (Timer Control) – запуск таймера.
- Установить бит TR1 (Timer 1 Run) в 1 для запуска таймера.
Последовательность настройки для передачи по UART в режиме 1 выглядит следующим образом:
- Установить в TMOD режим 2 для Timer 1:
TMOD |= 0x20; - Загрузить рассчитанное значение скорости в TH1:
TH1 = 0xDC; - Запустить таймер 1:
TR1 = 1; - Настроить SCON:
SCON = 0x50;(SM0=0, SM1=1, REN=1) - Сбросить флаг передачи TI:
TI = 0;
Такое конфигурирование гарантирует корректную и стабильную работу UART для передачи данных в микроконтроллерах серии 8051.
Программирование функции отправки одного байта через UART в C51

Основная последовательность действий: передача байта в регистр SBUF, ожидание установки флага TI и сброс этого флага для подготовки к следующей передаче.
Пример функции на C51:
void UART_SendByte(unsigned char data) {
SBUF = data;
while (!TI);
TI = 0;
}
Объяснение:
- SBUF – регистр данных UART, куда записывается передаваемый байт.
- TI – флаг окончания передачи, который устанавливается аппаратно при завершении отправки байта.
- Ожидание
while (!TI);гарантирует, что функция не завершится до фактической передачи. - Сброс
TI = 0;обязателен для корректной работы следующей передачи.
Рекомендуется использовать прерывания UART для более эффективной передачи при больших объемах данных, но для простых задач или отладки данная функция является базовой и надежной.
Организация передачи строковых данных по UART на языке C

Передача строк по UART в Keil C51 требует последовательной отправки каждого символа с контролем готовности передатчика. Основной механизм – ожидание флага передачи, установленного аппаратным UART после завершения передачи предыдущего байта.
Для передачи строки используется функция, принимающая указатель на массив символов (строку). В цикле по символам вызывается отправка каждого символа через регистр SBUF, после чего программа ждет установки бита TI (Transmit Interrupt flag), указывающего на завершение передачи.
Пример функции передачи строки:
void UART_SendString(char *str)
{
while(*str) {
SBUF = *str++;
while(!TI);
TI = 0;
}
}
Перед вызовом функции важно инициализировать UART, указав скорость передачи и режим работы. При отправке строк следует учитывать, что окончание определяется нулевым символом ‘\0’. Прерывания при передаче обычно отключают, чтобы избежать конфликтов.
Для передачи фиксированных строк можно использовать константные указатели, что уменьшит использование RAM. При необходимости передачи динамических строк, предварительно убедитесь в корректном завершении строки.
Оптимизация передачи достигается использованием аппаратных FIFO (если поддерживаются) или программным буфером с обработкой прерываний передачи для повышения производительности и снижения нагрузки на процессор.
Рекомендуется очищать флаг TI сразу после его обнаружения, чтобы избежать пропуска следующих передач. Задержки или дополнительные проверки между символами не нужны при правильной настройке UART.
Использование прерываний UART для приёма данных в Keil C51

Для эффективного приёма данных по UART в микроконтроллерах семейства 8051 с помощью Keil C51 рекомендуется использовать аппаратные прерывания UART. Это позволяет освободить основной поток исполнения программы от постоянной проверки состояния приёмника (polling), снижая нагрузку на CPU и обеспечивая своевременную обработку входящих данных.
Основные шаги реализации приёма данных с помощью прерываний UART:
- Настройка UART на нужную скорость передачи (baud rate) с помощью таймера.
- Включение прерываний UART, активация глобальных прерываний.
- Реализация обработчика прерывания, который считывает принятый байт из регистра SBUF и сохраняет его в буфер.
- Обеспечение защиты данных от возможных конфликтов при обращении к буферу.
Пример настройки и обработки прерывания UART в Keil C51:
void UART_Init(void) {
TMOD = 0x20; // Таймер 1 в режиме 2 (автоперезагрузка)
TH1 = 0xFD; // Скорость 9600 при 11.0592 МГц
SCON = 0x50; // UART режим 1, прием разрешён
TR1 = 1; // Запуск таймера 1
ES = 1; // Включение прерывания UART
EA = 1; // Глобальное разрешение прерываний
}
volatile unsigned char rx_buffer[64];
volatile unsigned char rx_write_pos = 0;
void UART_ISR(void) interrupt 4 using 1 {
if (RI) {
RI = 0; // Сброс флага приёма
rx_buffer[rx_write_pos++] = SBUF; // Сохранение данных
if (rx_write_pos >= sizeof(rx_buffer)) {
rx_write_pos = 0; // Защита от переполнения буфера
}
}
}
Рекомендации по реализации:
- Размер буфера подбирайте с запасом, исходя из максимального ожидаемого объёма данных между обработками.
- В обработчике прерывания не используйте длительные или блокирующие операции.
- При необходимости организуйте чтение данных из буфера в основном цикле программы с контролем индексов.
- Для многобайтовых протоколов реализуйте механизм обнаружения начала и конца сообщения, чтобы корректно собирать данные.
- При частых прерываниях и больших объемах данных рассмотрите использование кольцевого буфера для предотвращения потери информации.
Использование прерываний UART в Keil C51 обеспечивает точный и своевременный приём данных без постоянного опроса, что повышает производительность и надёжность системы.
Отладка передачи данных UART с помощью встроенных средств Keil

Для эффективной отладки UART в Keil C51 используйте встроенный симулятор и средства просмотра регистров. В первую очередь настройте частоту таймера, обеспечивающую корректный битрейт. В разделе Peripherals выберите UART и активируйте отображение регистров SCON, SBUF, TI и RI.
Запустите программу в режиме симуляции. При передаче данных контролируйте значение регистра SBUF – он должен содержать отправляемый байт. Флаг TI устанавливается при завершении передачи, его сброс необходим для подготовки следующего байта. Аналогично, при приеме данных флаг RI сигнализирует о наличии новых данных в SBUF.
Для пошагового анализа используйте Breakpoint на строках с записью в SBUF или проверкой флагов. Это позволит проследить моменты загрузки и выгрузки данных из буфера UART. В окне Watch добавьте переменные и регистры UART, чтобы следить за изменениями в реальном времени.
При работе с аппаратным отладчиком через Keil ULINK проверьте физические линии TX и RX с помощью логического анализатора или осциллографа. Сравните данные на линии с содержимым SBUF и состоянием флагов в отладчике для подтверждения правильности передачи.
Рекомендуется дополнительно реализовать контроль ошибок через флаги в SCON и обработку прерываний UART, что позволяет выявить случаи потери данных или неверной синхронизации.
Передача данных по UART с использованием таймера для задания скорости

Для настройки UART в микроконтроллерах семейства 8051 с использованием компилятора Keil C51 необходимо задать скорость передачи данных через таймер. Обычно применяется таймер 1 в режиме 2 (автоперезагрузка), который генерирует необходимую частоту тактового сигнала для UART.
В режиме 2 таймер 1 загружается значением TH1, которое определяет скорость передачи по формуле:
Baud Rate = (2^SMOD / 32) × (Oscillator Frequency / 12 / (256 — TH1)),
где SMOD – бит в регистре PCON, отвечающий за удвоение скорости (обычно 0 или 1).
Для стандартного кварца 11.0592 МГц и скорости 9600 бод следует загрузить TH1 значением 0xFD (253). Это обеспечит точное совпадение скорости.
Пример инициализации таймера 1 для UART:
TMOD = 0x20; // Таймер 1, режим 2
TH1 = 0xFD; // Значение для 9600 бод при 11.0592 МГц
