单片机——串口初探及串口+中断

简介

  • 设备间接线通信的一种方式
  • 数据一位一位地顺序传送
  • 双向通信,全双工
    • 全双工:A向B发消息时,B也可以向A发消息
    • 半双工:A向B发消息时,B不可以向A发消息,只有当A发完时,B才可以向A发消息
  • 传送速度较慢

常用串口的电器标准协议

RS-232(标准串口,9针,20kb/s,点对点,全双工,15m)、RS-422(一对多,比232更强,10Mb/s)和RS-485(比422更强)

串口的电平

UART:异步串行,通用异步接受/发送。UART包含TTL电平的串口和RS232电平的串口

  • RS-232电平:逻辑1:-3~-15V电压;逻辑0:3~15V电压
  • TTL电平:0V = 0, +5V=1
    • 输入高电平>=2.4V,输出低电平<=0.4V;
    • 输入高电平>=2.0V,输入低电平 <= 0.8V;

串口通信

串口接线方式

  • RXD:数据输入引脚,数据接受;STC89系列对应P3.0口
  • TXD:数据发送引脚,数据发送;STC89系列对应P3.1口
  • 接线方式:交叉接线

image.png

串口编程要素

  • 输入/输出数据缓冲器都叫做SBUF,都使用99H地址码,但是是两个独立的8位寄存器
  • 代码体现为:接收数据:char data = SBUF,发送数据SBUF = data
  • UART是异步串行接口,通信双方使用时钟不同,因为霜分硬件配置不同,但是需要约定通信速度,也就是波特率。
    • 对于电脑,使用现成的软件即可,但对于单片机的波特率配置,需要自己写

串口编程

波特率初始化一

  1. 设置串口的工作方式
  2. 设置波特率是否加倍
  3. 设置定时器的模式
  4. 根据波特率,设置定时器常数TH和TL
  5. 启动定时器
void UartInit(void)		//9600bps@11.0592MHz
{
	//AUXR避免辐射
	AUXR = 0x01;
	//设置串行口的工作方式
	SCON = 0x40;
	//设置波特率不加倍
	PCON = 0x10;
	
	//设置定时器模式,8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置定时器常数
	TH1 = 0xFD;
	TL1 = 0xFD;
	//启动定时器
	TR1 = 1;
}

判断数据是否发送完毕

根据串行口控制寄存器SCON中B1下的TI
image.png
意思就是当串行发送数据结束时,TI=1,会先主机请求中断。

串口发送字符串

#include "reg52.h"
#include <intrins.h>

sfr AUXR = 0x8E;
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UartInit(void)		//9600bps@11.0592MHz
{
	//AUXR避免辐射
	AUXR = 0x01;
	//设置串行口的工作方式
	SCON = 0x40;
	//设置波特率不加倍
	PCON = 0x10;
	
	//设置定时器模式,8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置定时器常数
	TH1 = 0xFD;
	TL1 = 0xFD;
	
	//启动定时器
	TR1 = 1;
}

void sendCh(char ch){
	SBUF = ch;
	while(!TI);//防止字符串还没有发送完毕,SBUF就发生了改变
	TI = 0;
}
//发送字符串
void sendString(char* str){
	while(*str != '\0'){
		sendCh(*str);
		str++;
	}
}


void main(){
	char data_mark = 'a';
	
	//配置C51串口的通信方式
	UartInit();
	
	while(1){
		Delay1000ms();
		sendString("hello word\r\n");
	}
}

注意上面代码中有一行while(!T1);这一行是给程序延时的,防止串行数据还没发送完毕时,SBUF就发生了改变,这也是发送的数据发生乱序的原因

向串口发送字符

#include "reg52.h"
#include <intrins.h>

sfr AUXR = 0x8E;
sbit led1 = P3^7;

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UartInit(void)		//9600bps@11.0592MHz
{
	//AUXR±ÜÃâ·øÉä
	AUXR = 0x01;

	SCON = 0x50;

	PCON = 0x10;
	TMOD &= 0x0F;
	TMOD |= 0x20;

	TH1 = 0xFD;
	TL1 = 0xFD;
	TR1 = 1;
}

void main(){
	char cmd;
	UartInit();
	
	while(1){
		Delay1000ms();
		if(RI == 1){
			RI = 0;
			cmd = SBUF;
			if(cmd == 'o'){
				led1 = 0;
			}
			if(cmd == 'c'){
				led1 = 1;
			}
		}
	}
}

向串口发送字符串控制开关灯,以中断的方式——简易

#include "reg52.h"
#include <intrins.h>
#include <string.h>

sfr AUXR = 0x8E;
sbit led1 = P3^7;

char arr[12];

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UartInit(void)		//9600bps@11.0592MHz
{
	//AUXR避免辐射
	AUXR = 0x01;
	//设置串行口的工作方式,使能接收串口数据
	SCON = 0x50;
	//设置波特率不加倍
	PCON = 0x10;
	
	//设置定时器模式,8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置定时器常数
	TH1 = 0xFD;
	TL1 = 0xFD;
	
	//启动定时器
	TR1 = 1;
	//开启全局中断开关
	EA  = 1;
	//开启串行UART中断
	ES = 1;

}

void sendCh(char ch){
	SBUF = ch;
	while(!TI);//防止字符串还没有发送完毕,SBUF就发生了改变
	TI = 0;
}
//发送字符串
void sendString(char* str){
	while(*str != '\0'){
		sendCh(*str);
		str++;
	}
}

void main(){
	//配置C51串口的通信方式
	UartInit();
	while(1){
		Delay1000ms();
		sendString("hello word\r\n");
		
	}
}

void UART_Handle(void) interrupt 4
{
	static int i;
	
	if(RI){
		RI=0;
		arr[i++] = SBUF;
		if(i==12){
			i = 0;
		}
		
		if(strcmp(arr,"open") == 0){
			led1 = 0;
			i=0;
			memset(arr,'\0',12);
		}
		
		if(strcmp(arr,"close") == 0){
			led1 = 1;
			i=0;
			memset(arr,'\0',12);
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值