串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信。51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。
一、串口向电脑发送数据
SCON=0x40; 这里用的是8位自动重装模式
#include <STC89C5xRC.H>
#include "Delay.h"
void UART_Init()
{
SCON=0x40; //这里不使能 STC给的代码是50 REN位0/1
PCON &= 0x7F; //波特率不倍速
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式(用定时器1,8位自动重装)
TL1 = 0xFA; //设置定时初值
TH1 = 0xFA; //设置定时重装值
//这里UpTL/TH两个都是0xF3,试过了不行
TR1 = 1; //定时器1开始计时
ET1 = 0; //禁止定时器1中断,确保定时器只用来控制波特率
}
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI==0);
TI=0;//刚开始发送数据是0,发送成功自动置1,跳出while需要人工置0
}
void main()
{
UART_Init();
while(1)
{
UART_SendByte(0x47);
Delay(500);
}
}
以上代码为了方便看没有模块化。
二、电脑通过串口控制LED
SCON=0x50;单片机发送不需要中断,是因为电脑程序员可以循环读取缓冲区,接收需要中断,因为不知道什么时候接收到,因此需要通过串口接收中断来及时响应接收到的数据,接收到的时候触发中断,需要打开中断的相应配置(ESEA和优先级)。
EA=1;ES=1
测试代码(已经模块化后)
void UART_Init()
{
SCON=0x50; //这里不使能 STC给的代码是50 REN位0/1(表示接收)
PCON &= 0x7F; //波特率不倍速
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式(用定时器1,8位自动重装)
TL1 = 0xFA; //设置定时初值
TH1 = 0xFA; //设置定时重装值
//这里UpTL/TH两个都是0xF3,试过了不行
TR1 = 1; //定时器1开始计时
ET1 = 0; //禁止定时器1中断,确保定时器只用来控制波特率
EA = 1;
ES = 1;
}
#include <STC89C5xRC.H>
#include "Delay.h"
#include "UART.h"
unsigned char sec;
void main()
{
UART_Init();
while(1)
{
}
}
void UART_Routine() interrupt 4
{
P2=0x00;
}
问了一下GPT,它意思也可以用如下方式类似TI进行中断处理,但是会浪费大量资源。
while(1)
{
// 监测接收标志位 RI,等待接收到数据
while(RI == 0); // 等待数据接收完成
RI = 0; // 清除接收中断标志位
unsigned char received_data = SBUF; // 读取接收到的数据
// 处理接收到的数据
}
-----------------------------------------
#include <STC89C5xRC.H>
#include "Delay.h"
#include "UART.h"
unsigned char sec;
void main()
{
UART_Init();
while(1)
{
}
}
void UART_Routine() interrupt 4
{
if(RI==1) //排除是发送的干扰
{
P2=~SBUF;
UART_SendByte(SBUF); //这个不能既在主函数main出现又在中断中出现
RI=0;
}
}
三、波特率(TLTH)
以老师的0xF3为例,243 256溢出-每13us就溢出 1/13us:定时器T1溢出频率 0.07692Mhz
设置倍速走上面1; 0.07692除以16 就是实际波特率 0.00480769Mhz 4807.69hz
四、数据显示模式
HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
文本模式/字符模式:以原始数据编码后的形式显示