Цифровые интерфейсы МК. UART, RS-232, RS-422, RS-485

Интерфейс и протокол

Интерфейс

... - физический/логический способ взаимодействия между компонентами
Определяет:

Примеры интерфейсов:

Протокол

... - набор правил, определяющих формат и порядок обмена данными
Описывает:

Примеры протоколов:

Схуяли что то типа SPI называют и интерфейсом, и протоколом?

SPI - интерфейс, включающий в себя протокол
Как интерфейс:

Как протокол:

Отсюда и смешение терминов

Ключевое отличие интерфейс/протокол

Протоколы UART, USART

UART (Universal Asynchronous Receiver-Transmitter)

... - Асинхронный последовательный протокол передачи данных
Работает без тактового сигнала
Использует два основных сигнала - TX (передача), RX (приём)
Данные передаются последовательно:

Особенности UART

Временная диаграмма UART

Диаграмма передачи байта 0b01001101
Pasted image 20250402104226.png
UART - асинхронный протокол, но для правильного приёма/передачи данных нужны битовая и кадровая синхронизации

Кадровая синхронизация UART

Кадровая синхронизация - корректное определение начала и конца каждого кадра

Контроль чётности UART

Битовая синхронизация

Обеспечивает правильное определение границ каждого бита
Особенно важно ибо приёмник и передатчик работают на одном битрейте, но без тактвого сигнала
Как достигается:

Ошибки синхронизации UART

Битовой:

Кадровой:

USART (Universal Syncronous/Asynchronous Receiver-Transmitter)

USART - более универсальный протокол, поддерживающий и синхронную и асинхронную передачу данных
В синхронном режиме юзает тактовый сигнал (duh)

Особенности USART

Временная диаграмма USART, синхронный режим

Pasted image 20250402110523.png

Схемы поключения

Pasted image 20250402110600.png

Примеры работы с UART

AVR

// UART init
#include <avr/io.h>

#define F_CPU 16000000UL
#define BAUD 9600
#define UBRR_VAL ((F_CPU / 16 / BAUD) - 1)

void UART_init() {
    // Transmission speed
    UBRR0H = (uint8_t)(UBRR_VAL >> 8);
    UBRR0L = (uint8_t)UBRR_VAL;
    
    // Turn on i/o
    UCSR0B = (1 << TXEN0) | (1 << RXEN0);
    
    // No parity control
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
// Data output (TX)
void UART_SendChar(uint8_t data) {
    // Wait for buffer to be freed
    while (!(UCSR0A) & (1 << UDRE0)));
    
    // Write to buffer
    UDR0 = data;
}

void UART_SendString(const char* str) {
    while (*str) {
        UART_SendChar(*str++);
    }
}
// ^ Sends a whole ass string daymn
// Data input (RX)
uin8_t UART_ReceiveChar() {
    // Wait for buffer
    while (!(UCSR0A & (1 << RXC0)));
    
    return UDR0;
}
// Usage example
int main() {
    UART_init();
    UART_SendString("Hello, UART!\r\n");
    
    while (1) {
        uint8_t received = UART_ReceiveChar();
        UART_SendChar(received); // echo
    }
}