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

我们采用串行口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
  • 硬件说明:[email protected]
  • 日期版本: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的中断允许位
			}
}

你可能感兴趣的:(蓝桥杯,单片机,串口通讯)