STC89C52_51单片机_串口配置_UART串口通信

STC89C52_51单片机_串口配置_UART串口通信







寄存器配置

PCON电源管理寄存器

位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0
//不能位寻址

SCON串口控制寄存器

位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0
/*  SCON  */
sbit SM0   = SCON^7;
sbit SM1   = SCON^6;
sbit SM2   = SCON^5;
sbit REN   = SCON^4;
sbit TB8   = SCON^3;
sbit RB8   = SCON^2;
sbit TI    = SCON^1;
sbit RI    = SCON^0;

模式&波特率(宋雪松P183)

SCON主要用模式1,的波特率
对应的,要用定时器T1&T2的模式2

TH1 = TL1 = 256 - 晶振值/12/2/16/波特率
(256是TL1的溢出值,12指12个时钟周期,16是硬件因素)

SBUF

两个SBUF寄存器,分别负责接收和发送缓冲

流程

配置串口为模式1
配置定时器T1为模式2
根据波特率计算TH0&TL0的值
配置PCON&SCON寄存器
打开定时器







代码及链接







IO口模拟UART串口通信

UART串口传送数据示意图

STC89C52_51单片机_串口配置_UART串口通信_第1张图片

挖坑:波特率&TH0是怎么算的?


#include

sbit PIN_RXD = P3^0;
sbit PIN_TXD = P3^1;

bit RxdOrTxd = 0;
bit RxdEnd = 0;
bit TxdEnd = 0;
unsigned char RxdBuf = 0;
unsigned char TxdBuf = 0;

void configUART(unsigned long baud);
void startRXD(void);
void startTXD(unsigned char dat);

void main(void)
{
	EA = 1;
	configUART(9600);

	while(1)
	{
		while(PIN_RXD);
		startRXD();
		while(!RxdEnd);
		startTXD(RxdBuf+1);
		while(!TxdEnd);
	}
}

void configUART(unsigned long baud)
{
	TMOD &= ~(0xF<<0);
	TMOD |= 0x1<<1;
	TH0 = 256 - (11059200 / 12) / baud;
}

void startRXD(void)
{
	TL0 = 256 - ((256 - TH0) >> 1);

	ET0 = 1;
	TR0 = 1;

	RxdEnd = 0;
	RxdOrTxd = 0;
}

void startTXD(unsigned char dat)
{
	TxdBuf = dat;

	TL0 = TH0;

	ET0 = 1;
	TR0 = 1;

	PIN_TXD = 0;
	RxdEnd = 0;
	RxdOrTxd = 1;
}

void timer0(void) interrupt 1
{
	static unsigned char cnt = 0;

	if(RxdOrTxd)
	{
		cnt++;
		if(cnt<=8)
		{
			PIN_TXD = TxdBuf & 0x01;
			TxdBuf >>= 1;
		}
		else if(cnt==9)
		{
			PIN_TXD = 1;
		}
		else 
		{
			cnt = 0;
			TR0 = 0;
			TxdEnd = 1;
		}
	}

	else
	{
		if(cnt==0)
		{
			if(!PIN_RXD)
			{
				RxdBuf = 0;
				cnt++;
			}
			else
			{
				TR0 = 0;
			}
		}
		else if(cnt<=8)
		{
			RxdBuf >>= 1;
			if(PIN_RXD)
			{
				RxdBuf |= 0x80;
			}
			cnt++;
		}
		else
		{
			cnt = 0;
			TR0 = 0;
			if(PIN_RXD)
			{
				RxdEnd = 1;
			}
		}
	}
}







UART串口通信

教学版


#include

void configUART(unsigned long baud);

void main(void)
{
	configUART(9600);
	while(!RI);
	RI = 0;
	SBUF = SBUF + 1;
	while(!TI);
	TI = 0;
}

void configUART(unsigned long baud)
{
	SCON = 0x50;

	TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
	TL1 = TH1;
	TMOD &= ~(0xF<<4);
	TMOD |= 0x2<<4;
	ET1 = 0;
	TR1 = 1;
}


工业版


#include

void configUART(unsigned long baud);

void main(void)
{
	EA = 1;
	configUART(9600);
	while(1);
}

void configUART(unsigned long baud)
{
	SCON = 0x50;

	TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
	TL1 = TH0;
	TMOD &= ~(0xF<<4);
	TMOD |= 0x2<<4;
	ET1 = 0;
	ES = 1;
	TR1 = 1;
}

void UART(void) interrupt 4
{
	if(RI)
	{
		RI = 0;
		SBUF = SBUF + 1;
	}
	if(TI)
	{
		TI = 0;
	}
}







计算机发送数据,在数码管中显示


#include

sbit wei = P2^7;
sbit duan = P2^6;

unsigned char code weitable[6] = 
{
	~0x20,~0x10,~0x08,~0x04,~0x02,~0x01
};

unsigned char code duantable[16] = 
{
	0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
	0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
};

unsigned char ledbuff[6] = 
{
	0x00,0x00,0x00,0x00,0x00,0x00
};

unsigned char T0RH = 0,T0RL = 0;
unsigned char RxdByte = 0;

void configtimer0(unsigned char ms);
void configUART(unsigned long baud);

void main(void)
{
	EA = 1;
	configtimer0(1);
	configUART(9600);
	while(1)
	{
		ledbuff[0] = duantable[RxdByte & 0x0F];
		ledbuff[1] = duantable[RxdByte >> 4];
	}
}

void configtimer0(unsigned char ms)
{
	unsigned long tmp;

	tmp = 11059200 / 12;
	tmp = (tmp * ms) / 1000;
	tmp = 65536 - tmp;
	tmp = tmp + 12;

	T0RH = (unsigned char)(tmp>>8);
	T0RL = (unsigned char)tmp;

	TH0 = T0RH;
	TL0 = T0RL;
	TMOD &= ~(0xF<<0);
	TMOD |= 0x1<<0;
	ET0 = 1;
	TR0 = 1;
}

void configUART(unsigned long baud)
{
	TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
	TL1 = TH0;
	SCON = 0x50;
	TMOD &= ~(0xF<<4);
	TMOD |= 0x2<<4;
	ET1 = 0;
	ES = 1;
	TR1 = 1;
}

void ledscan(void)
{
	static unsigned char i = 0;

	P0 = 0x00;
	duan = 1;
	duan = 0;

	P0 = weitable[i];
	wei = 1;
	wei = 0;
	P0 = ledbuff[i];   
	duan = 1;
	duan = 0;

	if(i<5)
		i++;
	else
		i = 0;
}

void timer0(void) interrupt 1
{
	TH0 = T0RH;
	TL0 = T0RL;

	ledscan();
}

void UART(void) interrupt 4
{
	if(RI)
	{
		RI = 0;
		RxdByte = SBUF;
		SBUF = RxdByte;
	}
	if(TI)
	{
		TI = 0;
	}
}

你可能感兴趣的:(STC89C52_51单片机_串口配置_UART串口通信)