蓝桥杯单片机比赛学习:7、中断系统之串口中断的基本原理

文章详细介绍了蓝桥杯单片机比赛中关于串口通信的中断处理,包括串行通信与并行通信的区别,单片机STC15F2K60S2的串口1和串口2,以及涉及的寄存器如T2H/T2L、AUXR、SCON、SBUF、IE、IP等。还讲解了如何初始化串口、设置波特率以及编写串口发送和接收函数。同时,给出了串口中断服务函数的示例代码,实现了特定的通信响应逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一节我们讲一下蓝桥杯单片机比赛中断中的最后一个模块——串口。中断的其他模块在我的个人主页(4条消息) Do My Best的博客_优快云博客-蓝桥杯单片机比赛学习领域博主有兴趣的可以去学习。

通信的方式

串行通信:一条总线,一次只能传输1bit。只需要一根线节省成本,但是传输速率慢。

并行通信:多条总线,支持多位同时传输。需要多根线浪费资源,但是传输速率快。

串行通信还包括:单工、半双工、全双工方式

单工:只能发送或者只能接受。

半双工:既能发送又能接受,但不能同时进行。

全双工:能同时发送并且接受。

我们使用的串口是串行全双工通信方式。下面我们来讲一下串口相关的寄存器,如果不想了解串口的这些繁琐的寄存器,想快速入手使用串口那么请看最下面的串口的使用步骤。

串口相关的寄存器

如下图,我们是用的单片机是STC15F2K60S2系列的,所以说此单片机只有两个串口——串口1和串口2,通常情况下我们只会使用串口1.

 使用串口时,我们主要使用的寄存器如下图,我们只要大致了解它的功能,不需要死记硬背,况且考试的时候也是可以查手册的。主要的有T2H/T2L、AUXR、SCON、SBUF、IE、IP等寄存器

T2H/T2L寄存器:这里我使用的定时器2来产生波特率,所以我们需要使用T2H/T2L寄存器,这里我们为什么使用定时器2而不使用定时器1、定时器0呢?主要的还是定时器2只有一种工作方式并且功能少,而定时器0/1有4种工作方式,这里用定时器2生成波特率避免浪费资源。因为定时器只能实现一种功能,当我们使用它产生波特率时就不能使用作为其他功能了,所以这里我们采用定时器2产生波特率,避免资源浪费。这里不强求使用定时器2,看自己心情!

AUXR寄存器

SCON寄存器

SM0、SM1:控制串口的工作方式,共有4种工作方式,如下图,在这里我们主要使用的是方式1——8位UART波特率可变。这里的波特率计算规则我们这里不需要明白。

SM2:允许/禁止多机位控制

REN:接收端使能位,REN=1,允许接收;REN=0,禁止接收。

TI:发送中断请求标志位,当TI=1时表示发送完成,此时必须软件清0(手动清0)才能继续下一次的发送。

RI:接收中断请求标志位,与TI位类似,当RI=1时表示接收完成,此时必须软件清0(手动清0)才能继续下一次的发送。

这几位是我们使用最多的几位,一般的SCON=0x50;

IE寄存器

 一般的,在我们使用串口中断时,需要使能EA和ES分别置1,表示打开串口中断,这样就可以在串口中断中处理程序。

PCON寄存器

SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。

串口的使用步骤

1.使用烧写软件STC-ISP软件生成初始化好的串口代码,如下图

 生成如下的代码:波特率为9600、8位数据、定时器2的频率为1MHz。我们发现这只是初始化串口1和定时器2,并没有中断的相关代码,所以如果你想使用中断也需要加上 EA=1; ES=1; 

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xE6;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
}

 2.写串口发送数据函数,发送字节、发送字符串函数。

void Send_Byte(unsigned char dat)    /* 发送一个字节(8bit) */
{
	SBUF=dat;            /* 将要发送的数据放在数据缓冲寄存器里 */
	while(TI==0);        /* 等待发送完成(等待TI=1) */
	TI=0;                /* 手动清0,便于下次发送 */
}
void Send_String(unsigned char *dat)    /* 发送字符串函数 */
{ 
	while(*dat != '0')            /* 判断每个字符是否为‘0’,为‘0’说明字符串发送完毕 */
	{
		Send_Byte(*dat++);        /* 调用发送字节函数,发送每一个字符 */
	}
}

3.如果使用中断的话还要编写串口中断服务函数,如下为我编写的串口中断服务函数

void Uart1Service(void)  interrupt 4
{
	if(RI==1)                /* 判断是否接受数据(判断上位机(电脑)是否向单片机发送数据) */
	{
		RI=0;                /* 手动清0 */
		rdat=SBUF;
		if(rdat==0x01)
			Send_String("I LOVE YOU");
		else
			Send_Byte(rdat+1);
	}
}

代码实现:

题目:单片机向上位机(电脑)发送16进制0x11、0x22,通过上位机向单片机发送数据,如是0x01那么上位机接收到 “I LOVE YOU ” ,否则上位机收到+1后的数据。这里我们的接收和发送模式选择时注意,是HEX模式还是文本模式。

 

#include "stc15f2k60s2.h"
#include "intrins.h"


/* 选择通道并且输入数据 */
void slect_138_573(unsigned char channel, unsigned char dat)
{
	P0 = 0x00;
	P0 = dat;										/* 这里用P0而不用其他端口是因为我们操作LED、数码管、继电器、蜂鸣器都是对P0进行操作 */
	switch(channel)							/* 选择通道 */
	{
		case 4:										/* 使Y4输出低电平0,也就是操作LED */
			P2 = (P2 & 0x1f) | 0x80;/* (P2 & 0x1f)就是将前3位清0,再操作前3位。将0x80转为2进制1000 0000,这里只看前3位100就是Y4 */
		break;
		case 5:										/* 使Y5输出低电平0,也就是操作继电器和蜂鸣器 */
			P2 = (P2 & 0x1f) | 0xa0;
		break;
		case 6:										/* 使Y6输出低电平0,也就是操作8个数码管 */
			P2 = (P2 & 0x1f) | 0xc0;
		break;
		case 7:										/* 使Y7输出低电平0,也就是操作8个数码管中的1个数码管显示值 */
			P2 = (P2 & 0x1f) | 0xe0;
		break;
		case 0:										/* 关闭所有通道 */
			P2 = (P2 & 0x1f) | 0x00;
		break;
	}
	P2 = (P2 & 0x1f) | 0x00;		/* 使用后,关闭所有通道 */
	
}

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xE6;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	
	EA=1;
	ES=1;
}


void Send_Byte(unsigned char dat)
{
	SBUF=dat;
	while(TI==0);
	TI=0;
}

void Send_String(unsigned char *dat)
{
	while(*dat != '0')
	{
		Send_Byte(*dat++);
	}
}

unsigned char rdat;
void Uart1Service(void)  interrupt 4
{
	if(RI==1)
	{
		RI=0;
		rdat=SBUF;
		if(rdat==0x01)
			Send_String("I LOVE YOU");
		else
			Send_Byte(rdat+1);
	}
}


void System_init(void)
{
	slect_138_573(4,0xff);
	slect_138_573(5,0x00);
	UartInit();
}

void main(void)
{
	System_init();
	Send_Byte(0x11);
	Send_Byte(0x22);
	while(1)
	{
	}
}

以上为本节的全部内容,如有错误请各位大佬指正,或有遗漏请指出。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Do My Best

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值