#include <stc8h.h> #include <delay.c> #include <intrins.h> #define uchar unsigned char

void UartInit(void) //9600bps@24.000MHz { SCON = 0x50; //8位数据, 可变波特率 AUXR |= 0x40; //串口1T模式 AUXR &= 0xFE; TMOD &= 0x0F;
TL1 = 0x8F;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
}

void Uart1_Isr() interrupt 4 using 1 { if (RI) { RI = 0; // 处理接收到的数据 } if (TI) { TI = 0; } }

void main() { uchar data = 0; // 初始化变量 UartInit();

SBUF = 'A';
while (!TI);  
TI = 0;  

// 添加超时判断
unsigned int timeout = 0;
while (!RI && timeout < 10000)
{
	timeout++;
	// ...
}

if (RI)
{
	data = SBUF;
	RI = 0; 
}

// ...

}

// ...

// 代码问题分析:

  1. 缺少头文件声明: 代码中缺少 #include <intrins.h> 头文件,该头文件包含了单片机内部函数的声明。

  2. 接收数据处理: 在 Uart1_Isr() 函数中,没有处理接收到的数据,需要在 RI = 0; 前加入处理代码。

  3. 变量初始化: main() 函数中的变量 data 没有初始化,应该赋初值。

  4. 发送数据超时判断: main() 函数中,使用 SBUF 发送数据时需要等待 TI 标志位置 1 才能继续下一步操作,但是 TI 标志位在发送完成后自动清零,因此此处的 while 循环可能会一直等待下去,导致死循环。可以在 while 循环中加入超时判断,或者使用中断方式发送数据。

  5. 接收数据误置判断: main() 函数中,接收数据时需要等待 RI 标志位置 1 才能读取 SBUF 中的数据,但是 RI 标志位也可能在发送数据时被误置为 1,因此需要在接收数据前先判断 TI 标志位是否为 1。

// ...

// 代码优化方案:

  1. 添加头文件声明 #include <intrins.h>。

  2. 在 Uart1_Isr() 函数中,在 RI = 0; 前加入处理接收到的数据的代码。

  3. 在 main() 函数中,将变量 data 初始化为 0。

  4. 在 main() 函数中,使用 while 循环发送数据时,加入超时判断,如果超时则退出循环。

  5. 在 main() 函数中,接收数据前先判断 TI 标志位是否为 1,如果为 1,则表示正在发送数据,需要等待发送完成后才能接收数据。

// ...

STC8 单片机 UART 通信代码分析及优化

原文地址: https://www.cveoy.top/t/topic/oGtd 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录