蓝桥杯单片机串口通讯与串口接收代码详解

我们采用串行口1编程,主要用到的特殊功能寄存器有:数据缓冲寄存器SBUF、串行口1方式控制寄存器SCON、辅助寄存器AUXR等
两个补充链接;
C51中的ABSACC.H介绍https://blog.csdn.net/qq_34629988/article/details/53225293.
51单片机 XBYTE说明https://blog.csdn.net/shenhuxi_yu/article/details/54344362.
/*******************************************************************************

  • 文件名称:串口通讯实验
  • 实验目的:
  • 1.掌握51单片机串口工作模式及相关寄存器配置方法
    2.了解51单片机波特率的计算方法
  • 程序说明:
    1.通过USB连接线连接PC机,在计算机硬件管理器中查看串口号
    2.打开串口调试工具软件,并将串口通讯波特率设定为2400
  • 硬件说明:IAP15F2K61S2@11.0592MHz
  • 日期版本:2019-2-12/qingyu
    说明因为延时程序有_nop_();函数,代表一个机器周期,所以用到了定时器,需要进行相关的配置,同时用到了串行口1的中断标志位TI,注意辅助特殊功能寄存器AUXR,能够选择定时器的工作模式(1T和12T,这是和普通八位的区别,复位及默认情况下为12T模式,与普通相同),SBUF为串口的发送与接收数据缓冲器。

*******************************************************************************/

#include "reg52.h"  
#include "intrins.h"
#include "absacc.h"
#define BAUD	     2400  //波特率
#define SYSTEMCLOCK  11059200L  //系统时钟频率
sfr AUXR  = 0x8e;    
void uart_sendstring(unsigned char *str);
void delay() //延时函数
{
	unsigned char i, j, k;
	_nop_();//代表一个机器周期													   
	_nop_();
	
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

//主函数
void main(void)
{ 
    SCON = 0x50;                 //	串行口1的方式控制寄存器sm0,SM1为工作方式选择位,先择了方式1REN允许接收位,为1有效 ;
    AUXR = 0x40;                //1T选择定时器1的1T模式
    TMOD = 0x00;                // 采用系统时钟作为计数脉冲
    TL1 = (65536 - (SYSTEMCLOCK/4/BAUD)); 		//设置定时初值与终值,为固定模板
    TH1 = (65536 - (SYSTEMCLOCK/4/BAUD))>>8;
    TR1 = 1;    //运行控制位 启动定时器1               
   
    while(1){
		uart_sendstring("hello,world.\r\n");  //串口发送函数
		delay();
	}
}

//通过串口发送字符串
void uart_sendstring(unsigned char *str) //指针变量
{
    unsigned char *p;
    
    p = str;
    while(*p != '\0')
    {
        SBUF = *p; //用作串口1的发送和接受数据缓存器
		while(TI == 0);  //等待发送标志位置位,TI为串口1的中断标志
		TI = 0;
        p++;
    }
}

/*******************************************************************************

  • 文件名称:串口通讯实验
  • 实验目的:
  • 1.掌握51单片机串口工作模式及相关寄存器配置方法
    2.了解51单片机波特率的计算方法
    3.掌握单片机串口接收中断服务函数的设计方法
    程序说明:
    1.通过USB连接线连接PC机,在计算机硬件管理器中查看串口号
    2.打开串口调试工具软件,并将串口通讯波特率设定为2400
    3.将跳线J13配置为IO模式
    4.输入1-8字符,控制8个LED指示灯状态
  • 硬件说明:IAP15F2K61S2 @11.0592MHz
  • 日期版本:2019-2-12/qingyu
    进行串行口1的相关寄存器配置,定时器1的配置,打开串行口中断和总中断 。我们需要定义一个串口的终端服务函数,若PC向单片机发送其他数据时,我们需要它进行向我们发送一段数据表示它受到,因此我们需要定义一个串行口发送数据的函数。最后是构建PC发送不同的数据,单片机会接受并执行对应操作的函数

*******************************************************************************/

#include "reg52.h"  //定义51单片机特殊功能寄存器
#include "absacc.h"

#define BAUD	     2400  		//波特率
#define SYSTEMCLOCK  11059200L  //系统时钟频率

sfr AUXR  = 0x8e; 

bit rxc = 0;
char rx = '1';
void uart_sendstring(unsigned char *str);
void interrupt_scan();

//主函数
void main(void)
{ 
    SCON = 0x50;  //串行口1选取工作方式1               

    AUXR = 0x40;                //特殊功能寄存器配置成1T模式
    TMOD = 0x00;                //采用系统时钟作为计数脉冲
    TL1 = (65536 - (SYSTEMCLOCK/4/BAUD));   //
    TH1 = (65536 - (SYSTEMCLOCK/4/BAUD))>>8;
    TR1 = 1; //TMOD中的GATE位为0时,打开TR1即可采用定时器1 计数 
	ES = 1;//打开串行口1 的中断允许位
	EA = 1;	//打开总中断
	
    while(1)
    {
	  interrupt_scan();
    }
}
//构建PC发送不同的数据,单片机会接受并执行对应操作的函数
void interrupt_scan()
{
	if(rxc == 1)
	{
				rxc = 0;
				switch(rx)
				{
					case '1':
						P2=0X80;P0=0XFE;
						break;
					case '2':
					    P2=0X80;P0=0xFD;
						break;
					case '3':
						P2=0X80;P0=0xFB;
						break;
					case '4':
						P2=0X80;P0=0xF7;
						break;
					case '5':
						P2=0X80;P0=0xEF;
						break;
					case '6':
						P2=0X80;P0=0xDF;
						break;
					case '7':
						P2=0X80;P0=0xBF;
						break;
					case '8':
						P2=0X80;P0=0x7F;
						break;
					default:
						uart_sendstring("error\r\n");	//输入其他数据返回error
						break;
				}

				ES = 1;//再次打开串行口1的中断允许位
			}
}

//串口中断服务函数
void isr_uart(void) interrupt 4
{
    if(RI)
    {
        RI = 0;  //清除接收中断标志位 除方式0的其他方式下(本程序在SCON中设置SM0,SM1为01,为方式1)
		        //接受到停止位置1,向CPU发起中断,中断结束后必须由软件置0!!)
        rx = SBUF;//将数据缓存器的数据给rx
		ES = 0;//关闭串行口1的中断允许位
		rxc = 1;
	}
}

//通过串口发送字符串
void uart_sendstring(unsigned char *str)
{
    unsigned char *p;
    
    p = str;
    while(*p != '\0')
    {
        SBUF = *p;
		while(TI == 0);  //等待发送标志位置位
		TI = 0;
        p++;
    }
}

也可采用寄存器编程,将void interrupt_scan()函数修改,同时将开发板的J13接到MM即可

void interrupt_scan()
{
	if(rxc == 1)
	{
				rxc = 0;
				switch(rx)
				{
					case '1':
						XBYTE[0x8000] = 0xFE;
						break;
					case '2':
						XBYTE[0x8000] = 0xFD;
						break;
					case '3':
						XBYTE[0x8000] = 0xFB;
						break;
					case '4':
						XBYTE[0x8000] = 0xF7;
						break;
					case '5':
						XBYTE[0x8000] = 0xEF;
						break;
					case '6':
						XBYTE[0x8000] = 0xDF;
						break;
					case '7':
						XBYTE[0x8000] = 0xBF;
						break;
					case '8':
						XBYTE[0x8000] = 0x7F;
						break;
					default:
						uart_sendstring("error\r\n");	//输入其他数据返回error
						break;
				}

				ES = 1;//再次打开串行口1的中断允许位
			}
}

  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
单片机串口通信接收字符串的步骤如下: 1. 初始化串口模块,确定波特率、数据位、停止位、校验位等参数。 2. 等待接收串口数据,一般使用中断方式接收数据,即设置串口接收中断函数。 3. 接收串口数据后,将数据存储到内存中。 4. 检查接收到的数据是否为完整的字符串,判断方法可以是判断是否有结束符(如'\0')或者判断接收到的字节数是否达到预期。 5. 如果接收到完整字符串,则处理数据,完成后清空缓存区,等待下一次接收。 下面是一段接收字符串的示例代码: ```c #include <reg52.h> #include <stdio.h> #define UART_BAUDRATE 9600 // 串口波特率 #define UART_BUFFERSIZE 32 // 串口缓冲区大小 unsigned char uart_buffer[UART_BUFFERSIZE]; // 串口缓冲区 unsigned char valid_data = 0; // 有效数据长度 void uart_init() { /* 初始化串口模块 */ TMOD |= 0x20; // 定时器1工作在模式2,允许自动重装载 TH1 = 0xFD; // 波特率计算公式:TH1 = 256 - (晶振频率 / (32 * 波特率)),晶振频率为11.0592 MHz TL1 = 0xFD; PCON = 0x80; // SMOD = 1,波特率加倍 SCON = 0x50; // SCON的D7和D6位分别表示串口工作模式和接收允许位 IE = 0x90; // 开启串口中断和定时器中断 TR1 = 1; // 启动定时器1 } void uart_receive() interrupt 4 { /* 串口接收中断函数 */ if (RI) { /* 接收数据 */ unsigned char data = SBUF; if (valid_data < UART_BUFFERSIZE) { uart_buffer[valid_data] = data; valid_data++; } RI = 0; } } void main() { uart_init(); while (1) { if (valid_data > 0) { /* 接收到有效数据 */ if (uart_buffer[valid_data - 1] == '\0') { /* 数据接收完成 */ printf("Received: %s\r\n", uart_buffer); // 处理数据 valid_data = 0; // 清空缓冲区,等待下一次接收 } } } } ``` 在上面的代码中,初始化了串口模块并设置了串口接收中断函数。在主函数中,不断检查串口接收缓冲区中是否有数据,如果有数据则判断是否为完整字符串,如果是则处理数据并清空缓冲区。如果缓冲区中的数据不足以组成完整的字符串,则继续等待接收
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

稚肩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值