【蓝桥杯06】——串行通信

  1. 基本概念
    (1) 串行通信是指数据一位接一位地顺序发送或接收。
    (2) 串行通信有SPI、IIC、UART等多种,最常见最通用的是指UART。
    (3) 串行通信的制式有:单工、半双工、全双工三种。
    (4) 波特率:每秒钟传输的位数,9600波特率就是指每秒钟传输9600位。
    (5)注意:在51单片机中需要使用定时器1来产生波特率,因此,如果使用串口通信,则定时器1就不能做其他用途,在初始化串行接口模块的时候,除了要配置SCON寄存器之外,还有根据波特率参数设置定时器1的技术初值。
  2. 对于传统的51单片机,与串口相关的寄存器有:
    (1)TH1和TL1:设置波特率参数。
    (2)MOD:设置定时器1的工作模式。
    (3)SBUF:串行通信数据的发送和接收缓冲器。
    (4)SCON:串行接口控制寄存器。
    (5)STC15F2K602单片机,还需要对新增的辅助寄存器AUXR进行设置,否则是无法进行串口数据收发的,对于传统的89C52单片机,则不需要这个步骤。在这里插入图片描述
  3. 串口通信的编程思路
    在串口通信的程序设计中,主要有串口初始化和数据收发两个部分。
    在初始化函数中,基本步骤如下:
    (1)设置定时器1的工作模式,也就是对TMOD寄存器赋值。
    (2) 计算波特率参数,并赋值给TH1和TL1寄存器。
    (3) 打开定时器1。
    如果使用的是STC 12系统单片机,则要设置AUXR寄存器。
    (4) 设置SCON寄存器。
    (5) 使能串口中断ES。
    (6) 使能总中断EA。
    数据的发送通常采用查询方式,而数据的接收则采用中断方式。

利用单片机的串行接口与上位机建立传输信道进行数据的收发

  1. 采用8位的UART模式,即模式1,波特率为9600BPS。
  2. 数据发送采用查询方式,数据接受采用中断方式。
  3. 系统上电初始化之后,单片机向上机位发送两个字节:0x5a和0xa5,然后等待接收上位机的数据,每接收到一个字节后,在该字节的基础上加1。
#include <STC15F2K60S2.H>
void send(unsigned char d);
void ruart();
sbit beer=P0^6;

void main()
{
    
    
	  P2=0xA0;beer=0;P2 &= 0x1f;;//上电电位不稳,先关闭蜂鸣器
	  ruart();
    send(0x5a);
    send(0xa5);
	  while(1);
}

//串口初始化函数
void ruart()
{
    
    
	TMOD=0x20;        //定时器1工作模式为自动重装
    TH1=0xfd;         //设置波特率为9600
    TL1=0xfd;         //11.0592M或12M的12分频
    AUXR=0x00;        //bit7=1:定时器1不分频,0则12分频
		
    TR1=1;            //启动定时器1
    SCON = 0x50;      //串口参数为模式1和允许接收
    ES=1;             //使能串口中断
    EA=1;             //使能总中断
}

unsigned char dat;

//串口中断服务函数
void serviceuart() interrupt 4
{
    
    
	if(RI==1) //接收到一个完整的字节  如果RI==1就说明接收到一个完整的数据
	{
    
    
		RI=0; //人工清零  清除接收完成标志
		dat=SBUF; //接收到的数据放在 dat 里面
		send(dat+1);
  }
}

//发送单个字节函数
void send(unsigned char d)
{
    
    
	  SBUF = d;            //将数据放进SBUF缓冲器
    while(TI == 0);        //等待发送数据完成
    TI = 0;                //清除发送完成标志
}

串口调试:
在这里插入图片描述

利用单片机的串行接口与上位机建立传输数据信道。

  1. 采用8位的UART模式,即模式1,波特率为9600BPS。
  2. 数据发送采用查询方式,数据接受采用中断方式。
  3. 系统上电初始化之后,关闭蜂鸣器和继电器等无关设备,并向上位机发送字符串:“Welcome to XMF system!”,回车换行。
  4. 上位机通过串口发送单字节命令可以控制下位机的8个LED灯开关。
  5. 上位机通过串口发送单字节命令可以读取下位机运行信息。
  6. 通信规约如下表:

在这里插入图片描述

#include <STC15F2K60S2.H>

void init();
void uart();
void selectHC(unsigned char n);
void sendByte(unsigned char dat);
void sendString(unsigned char *str);
void working();

void main()
{
    
    
	init();
	uart();
	sendString("Welcome to XMF system!\r\n");
	while(1)
	{
    
    
		working();
  }
}

void selectHC(unsigned char n)
{
    
    
	switch(n)
	{
    
    
		case 4:P2=(P2&0x1f)|0x80;break;  //LED灯
		case 5:P2=(P2&0x1f)|0xa0;break;  //蜂鸣器,继电器
		case 6:P2=(P2&0x1f)|0xc0;break;  //数码管位选
		case 7:P2=(P2&0x1f)|0xe0;break;  //数码管段选
		case 0:P2=(P2&0x1f)|0x00;break;
  }
}

//关闭蜂鸣器和继电器,LED灯都熄灭
void init()
{
    
    
	selectHC(5);P0=0x00;
	selectHC(4);P0=0xff;
}

//初始化
void uart()
{
    
    
	TMOD=0X20;  //定时器1工作模式为自动重装
	TH1=0XFD;   //设置波特率为9600,  11.0592M或12M的12分频
	TL1=0XFD;
	TR1=1;      //启动定时器1
	AUXR=0X00;  //bit7=1:定时器1不分频,0则12分频
	           
  SCON = 0x50;      //串口参数为模式1和允许接收
  ES=1;             //使能串口中断
  EA=1;             //使能总中断

}

//串口中断  串口数据接收
unsigned char c=0x00;
void serviceuart() interrupt 4
{
    
    
	if(RI==1)  //接收到一个完整的字节  如果RI==1就说明接收到一个完整的数据
	{
    
    
		c=SBUF;  //接收到的数据放在 dat 里面
		RI=0;    //人工清零  清除接收完成标志
  }
}

void working()
{
    
    
	if(c!=0x00)
	{
    
    
		switch(c&0xf0)  //取出高四位,判断是a还是b,进行对L1-L4还是L5-L8进行判断
		{
    
    
			case 0xa0:    //输入的高4位是a,则对L1-L4进行操作
				P0=(P0|0x0f)&(~c|0xf0);
				c=0x00;
				break;
			case 0xb0:   //输入的高4位是b,则对L5-L8进行操作
				P0=(P0|0xf0)&((~c<<4)|0x0f);
				c=0x00;
				break;
			case 0xc0:   //输出c0,返回指定信息
				sendString("The System is Running...\r\n");
				c=0x00;
			  break;
	  }
	}
}

//发送单字节
void sendByte(unsigned char dat)
{
    
    
	SBUF=dat;     //将数据放进SBUF缓冲器
	while(TI==0); //等待发送数据完成
	TI=0;         //清除发送完成标志             
}

//发送字符串
void sendString(unsigned char *str)
{
    
    
	while(*str!='\0')
	{
    
    
		sendByte(*str++);
  }
}

猜你喜欢

转载自blog.csdn.net/z3447643805/article/details/113771656