Ponte Serial entre STC8H e ESP8266 com Encaminhamento Transparente de Dados

A implementação de uma ponte de comunicação serial entre o microcontrolador STC8H e o módulo ESP8266 requer o gerenciamento simultâneo de duas interfaces UART independentes. A UART1 é alocada para o enlace de depuração com o computador, enquanto a UART2 estabelece o canal de dados com o módulo Wi-Fi. O objetivo técnico é configurar um roteamento transparente de bytes, permitindo que os pacotes MQTT recebidos pela rede sejam encaminhados integralmente para o terminal serial, validando a integridade do enlace físico e a sincronização dos buffers antes da etapa de decodificação de payloads.

Topologia de Conexão

O barramento deve operar em nível lógico de 3.3V com referência de terra comum. O mapeamento de sinais segue a configuração abaixo:

ESP8266 STC8H
RX P1.1 (TxD2)
TX P1.0 (RxD2)
3.3V 3.3V
GND GND

Firmware de Roteamento Serial

O firmware utiliza buffers circulares alocados em memória externa (xdata) para armazenar os bytes recebidos via interrupção. O laço principal consulta os índices de leitura e escrita, realizando o encaminhamento cruzado entre os canais sem bloquear a execução do processador.

#include "stc8h.h"
#include "intrins.h"

#define CLOCK_FREQ      11059200UL
#define BAUD_RELOAD_VAL (65536 - (CLOCK_FREQ / 9600 + 2) / 4)
#define RX_QUEUE_LEN    256

/* Enlace PC (UART1) */
volatile bit tx1_pending = 0;
volatile unsigned char rx1_head = 0;
volatile unsigned char rx1_tail = 0;
xdata unsigned char queue_pc[RX_QUEUE_LEN];

/* Enlace ESP (UART2) */
volatile bit tx2_pending = 0;
volatile unsigned char rx2_head = 0;
volatile unsigned char rx2_tail = 0;
xdata unsigned char queue_esp[RX_QUEUE_LEN];

void ISR_UART1(void) interrupt 4
{
    if (TI) { TI = 0; tx1_pending = 0; }
    if (RI) {
        RI = 0;
        queue_pc[rx1_head] = SBUF;
        if (++rx1_head >= RX_QUEUE_LEN) rx1_head = 0;
    }
}

void ISR_UART2(void) interrupt 8
{
    if (S2CON & 0x02) { S2CON &= ~0x02; tx2_pending = 0; }
    if (S2CON & 0x01) {
        S2CON &= ~0x01;
        queue_esp[rx2_head] = S2BUF;
        if (++rx2_head >= RX_QUEUE_LEN) rx2_head = 0;
    }
}

void setup_serial_links(void)
{
    SCON = 0x50;
    T2L = BAUD_RELOAD_VAL & 0xFF;
    T2H = BAUD_RELOAD_VAL >> 8;
    AUXR = 0x15;

    S2CON = 0x50;
    T2L = BAUD_RELOAD_VAL & 0xFF;
    T2H = BAUD_RELOAD_VAL >> 8;
    AUXR |= 0x04;
    S2CON &= ~0x08;

    rx1_head = rx1_tail = 0;
    tx1_pending = 0;
    rx2_head = rx2_tail = 0;
    tx2_pending = 0;
}

void transmit_ch1(unsigned char val)
{
    while (tx1_pending);
    tx1_pending = 1;
    SBUF = val;
}

void transmit_ch2(unsigned char val)
{
    while (tx2_pending);
    tx2_pending = 1;
    S2BUF = val;
}

void main(void)
{
    unsigned char incoming;

    P_SW2 |= 0x80;
    P0M0 = P0M1 = P1M0 = P1M1 = P2M0 = P2M1 = 0x00;
    P3M0 = P3M1 = P4M0 = P4M1 = P5M0 = P5M1 = 0x00;

    setup_serial_links();
    ES = 1;
    IE2 |= 0x01;
    EA = 1;

    const char *boot = "\r\n[BRIDGE] STC8H <-> ESP8266 Link Established\r\n";
    while (*boot) transmit_ch1(*boot++);

    while (1)
    {
        if (rx1_tail != rx1_head) {
            incoming = queue_pc[rx1_tail];
            if (++rx1_tail >= RX_QUEUE_LEN) rx1_tail = 0;
            transmit_ch2(incoming);
        }

        if (rx2_tail != rx2_head) {
            incoming = queue_esp[rx2_tail];
            if (++rx2_tail >= RX_QUEUE_LEN) rx2_tail = 0;
            transmit_ch1(incoming);
        }
    }
}

Monitoramento do Tráfego MQTT

Com a ponte ativa, o assistente serial captura o fluxo de dados originado na interface web e retransmitido pelo ESP8266. O registro abaixo ilustra a sequência de associação à rede, autenticação no broker e a chegada dos comandos JSON:

[11:37:05.522] RX <- x?
[11:42:58.768] RX <- Conectando ao broker MQTT...
[11:43:03.791] RX <- Falha, rc=-2
                    === Configuração WiFi ===
                    SSID: ESP8266_Hotspot
                    
[11:43:04.272] RX <- .
[11:43:04.772] RX <- .
[11:43:05.267] RX <- .
[11:43:05.768] RX <- .
[11:43:06.265] RX <- .
[11:43:06.772] RX <- .
[11:43:07.269] RX <- .
[11:43:07.767] RX <- .
[11:43:08.263] RX <- .
[11:43:08.775] RX <- .
[11:43:09.275] RX <- .
[11:43:09.774] RX <- .
[11:43:10.271] RX <- .
[11:43:10.765] RX <- .
[11:43:11.266] RX <- .
[11:43:11.764] RX <- .
[11:43:12.265] RX <- .
[11:43:12.762] RX <- .
[11:43:13.261] RX <- .
[11:43:13.775] RX <- .
[11:43:14.275] RX <- .
[11:43:14.775] RX <- .
[11:43:15.273] RX <- .
[11:43:15.767] RX <- .
[11:43:16.264] RX <- .
[11:43:16.764] RX <- .
[11:43:17.262] RX <- .
[11:43:17.774] RX <- .
[11:43:18.272] RX <- .
[11:43:19.247] RX <- .
[11:43:19.743] RX <- .
[11:43:20.240] RX <- .
[11:43:20.750] RX <- .
[11:43:21.248] RX <- .
[11:43:21.776] RX <- .
                    WiFi conectado!
                    IP: 192.168.137.70
                    Conectando ao broker MQTT...
[11:43:22.737] RX <- Sucesso!
                    Tópico subscrito: IOT_LAB_TEACHER/device/LED_CONTROLLER_10422628/control
                    
[11:51:29.774] RX <- [MQTT->UART] 138 bytes recebidos
                    {"protocol":"iot_v1","typ
[11:51:29.852] RX <- e":"command","id":"cmd_1_1764906689236","device":"controller_001","timestamp":1764906689,"cmd":"get","params":{}}
                    
[11:51:31.917] RX <- [MQTT->UART] 146 bytes recebidos
[11:51:31.963] RX <- 
                    {"protocol":"iot_v1","type":"command","id":"cmd_2_1764906691463","device":"controller_001","timestamp":1764906691,"cmd":"set","params":{"led1":1}}
                    
[11:51:32.226] RX <- [MQTT->UART] 138 bytes recebidos
                    {"protocol":"iot_v1","type":"command","id":"cmd_3_1764906
[11:51:32.335] RX <- 691764","device":"controller_001","timestamp":1764906691,"cmd":"get","params":{}}
                    
[11:51:37.968] RX <- [MQTT->UART] 146 bytes recebidos
                    {"protocol":"iot_v1","typ
[11:51:38.044] RX <- e":"command","id":"cmd_4_1764906697565","device":"controller_001","timestamp":1764906697,"cmd":"set","params":{"led1":0}}
                    
[11:51:38.372] RX <- [MQTT->UART] 138 bytes recebidos
                    {"protocol":"iot_v1","typ
[11:51:38.450] RX <- e":"command","id":"cmd_5_1764906697867","device":"controller_001","timestamp":1764906697,"cmd":"get","params":{}}
                    
[11:51:42.373] RX <- [MQTT->UART] 146 bytes recebidos
                    {"protocol":"iot_v1","typ
[11:51:42.450] RX <- e":"command","id":"cmd_6_1764906701807","device":"controller_001","timestamp":1764906701,"cmd":"set","params":{"led2":1}}
                    
[11:51:42.681] RX <- [MQTT->UART] 138 bytes recebidos
                    {"protocol":"iot_v1","type":"command","id":"cmd_7_1764906702108","device":"controller_001","timestamp":1764906702,"cmd":"get","params":{}}
                    
[11:51:45.745] RX <- [MQTT->UART] 146 bytes recebidos
                    {"protocol":"iot_v1","type":"command","id":"cmd_8_1764906
[11:51:45.839] RX <- 705174","device":"controller_001","timestamp":1764906705,"cmd":"set","params":{"led2":0}}
                    [MQTT->UART] 138 bytes recebidos
                    {"protocol":"iot_v1","type":"command","id":"cmd_9_1764906705476","device":"controller_001","timestamp":1764906705,"cmd":"get","params":{}}
                    
[11:51:49.241] RX <- [MQTT->UART] 139 bytes recebidos
                    {"protocol":"iot_v1","type":"command","id":"cmd_10_1764906708568","device":"controller_001","timestamp":1764906708,"cmd":"get","params":{}}

A saída do terminal confirma que a arquitetura de encaminhamento opera com transparência total. Os payloads JSON gerados pela aplicação web são repassados pelo módulo Wi-Fi e etnregues à UART de depuração com a estrutura original preservada, validando o dimensionamento dos buffers circulares e a sincronização das interrupções para a taxa de transmissão configurada.

Tags: STC8H ESP8266 UART Buffer Circular Comunicação Serial

Publicado em 10-4 02:56