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.