单片机 串口编程之串口通信仿真实验

一、简述

       记--简单的使能串口,串口收发数据的例子。(使用Proteus仿真+虚拟串口调试)

       代码,仿真文件打包:链接: https://pan.baidu.com/s/1nyb46fTJrYcAy_VarFdO3A 提取码: j44s 

         蓝奏:https://www.lanzous.com/i2fx3oh

      虚拟串口调试软件打包:链接: https://pan.baidu.com/s/1qaOgM8P7ZRmXb903NkiMOQ 提取码: r18u 

         蓝奏:https://www.lanzous.com/i2fx41a

二、效果

        PC机通过串口调试助手发送数据给单片机,单片机收到之后回复:I received.。如果单片机收到的是'1'则点亮LED灯,否则熄灭LED灯。

           单片机 串口编程之串口通信仿真实验-LMLPHP

        (真实硬件实验:使用Keil C51将代码编译为HEX文件,用串口线/USB转串口线连接PC机,可以使用STC-ISP软件烧写到51单片机,在PC机可以使用串口调试助手(STC-ISP也有这个功能,也可以是其他软件,当然也可以自己编写串口程序)与单片机进行串口通信。实际中,电脑串口采用232电平,而单片机串口则采用TTL电平,如果不进行电平转换,单片机与电脑就无法正常通信,甚至单片机芯片可能会被烧坏。MAX232 芯片可以进行电平转换,是将单片机输出的TTL电平转换成PC机能接收的232电平或将PC机输出的232电平转换成单片机能接收的TTL电平。​​​​电平是个电压范围,如可能规定输出电压>2.4V则为高电平,输出电压低于<0.4V则为低电平,不同的点击器件、不同的标准有着不同的电压范围​​​)

       注:一个COM一般不能同时被两个程序占用。

三、工程结构及各属性设置

        keil工程

         单片机 串口编程之串口通信仿真实验-LMLPHP

         单片机 串口编程之串口通信仿真实验-LMLPHP

         单片机 串口编程之串口通信仿真实验-LMLPHP

          

        proteus仿真

        单片机 串口编程之串口通信仿真实验-LMLPHP

单片机 串口编程之串口通信仿真实验-LMLPHP

添加虚拟串口

                                单片机 串口编程之串口通信仿真实验-LMLPHP

单片机 串口编程之串口通信仿真实验-LMLPHP

四、源文件

       main.c文件 

#include <reg51.h>
sbit p1_0 = P1^0;

//初始化串口 (设置串口,开启串口中断)
void init_uart(void)
{
	SCON = 0x50;		        // SCON: 方式 1, 8-bit, 允许接收数据 
	TMOD |= 0x20;               // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
	TH1 = 0xFD;               // TH1:  初始值为0xFD  波特率:9600 晶振频率:11.0592MHz  
	TL1 = 0x0;
	TR1 = 1;                  // TR1:  开启定时器1                         
	EA  = 1;                  //打开总中断
	ES  = 1;                  //打开串口中断
}       

           
// 发送一个字节数据
void uart_send_byte(unsigned char dat)
{
	SBUF = dat; // 将数据送到发送缓冲寄存器SBUF,一位一位的发送
	while(!TI); // 等待发送完毕 (发送完毕TI硬件置1)
	TI = 0;// 将TI清零,表示可以发送下一字节数据。
}

// 发送字符串
void uart_send_str(unsigned char *s)
{
	while(*s != '\0')// '\0':字符串结束标志
	{
		uart_send_byte(*s);// 发送1个字节数据,1个字符占8位,1字节
		s++;// 指向下一个字符
	}
}


// 串口中断处理函数 (串口接收到数据,发送数据完毕都可以引起串口中断)
void uart_interrupt(void) interrupt 4 		//也叫串行中断服务程序
{
	unsigned char recv_data;// 用来存放接收到的数据
	unsigned char send_data[] = "I received.\n";// 要发送的信息
	
	if(RI) //接收数据(1字节)完毕,RI会被硬件置1
	{
		RI = 0;            		// 将 接收中断标志位 清零(让串口可以继续接收数据)
		recv_data = SBUF;           	//读取接收到的数据,并存放到data
	
		
		if(recv_data == '1')//如果收到的字符是'0',就让灯灭
		{
			p1_0 = 0;//  p1.0引脚低电平,LED灯亮
		}
		else
		{
			p1_0 = 1;// p1.0引脚高电平,LED灯灭
		} 

	    uart_send_str(send_data); //收到数据之后,发送字符串"I received."给对方
	}
	if(TI)// 发送数据(1字节)完毕
	{
		TI = 0;// 将 发送中断标志位 清零(让串口可以继续发送数据)
	}
} 

void main(void)
{
	init_uart();// 初始化串口
	
	while(1)// 主循环不做任何动作。(死循环)
	{}
}

五、总结

       51单片机系列

      1、单片机的串口相关的寄存器

            1) 串口控制寄存器SCON:(Serial CONtrol)

            2) 串行数据寄存器SBUF:(Serial data BUFfer)

            3)电源管理寄存器PCON:(Power CONtrol)

      2、串口控制寄存器SCON

            用来对串口进行控制,其寄存器地址为0x98,支持位寻址。

            一般来说单片机的寄存器的个数在制作好就已经确定了,MCS-51单片机有一些寄存器是8位的(可以存放8位数据),有一些是16位的,这些寄存器有点像全局变量(寄存器名-变量名),它们分配了固定的地址空间,我们可以对这个寄存器变量进行赋值或读取值。比如我们禁止串口中断,那么我们可以设置相应的值,当系统处理串口相关的任务时,读取到这个我们设置的值时,直到我们要禁止串口中断,那么系统就不会相应串口中断。串口控制寄存器SCON的地址为0x98,我们可以直接对SCON这个"变量"进行赋值,支持位寻址意思是:SCON一共有8位,每1位代表的意思都有不同,可以直接单独对某一位进行设置,有一些寄存器是不可以位寻址的。

           

 

 

      3、串行数据寄存器SBUF

            用于存放串行通信中发送和接收的相关数据。其寄存器地址是0x99。

            SBUF由发送缓冲寄存器和接收缓冲寄存器组成,这两个寄存器占用同一个寄存器地址。其中发送缓冲寄存器只写,接收寄存器只读。

           发送数据:当将一个数据写入SBUF后,单片机立即根据选择的工作方式和波特率将写入的字节数据进行相应的处理然后从TXD(P3.1)引脚串行发送出去,发送完成之后置位相应寄存器的标志位,只有相应的标志位被清除之后才能进行下一次的数据发送。

           接收数据:当RXD(P3.0)引脚根据工作方式和波特率接收到一个完整的数据字节后单片机将该数据字节放入接收缓冲寄存器中,并置位相应的标志位。接收缓冲寄存器是双字节的,这样就可以在单片机读取接收缓冲寄存器的数据时同时进行下一个字节的数据接收。不会发生前后两个字节的数据冲突(数据覆盖)。

      4. 电源管理寄存器PCON

            可以控制串口波特率加倍。

      SMOD:该位与串口通信有关。

      SMOD=0; 串口方式1,2,3时,波特率正常。

      SMOD=1; 串口方式1,2,3时,波特率加倍。

      5、串口的工作方式

            MCS-51单片机的串口一共4种工作方式。其中工作方式0为同步通信方式,其余3种为异步通信。

            工作方式0:外部引脚TXD(P3.0)为数据的输出输入端,外部引脚TXD(P3.1)提供数据的同步脉冲。

                                因此工作在方式0进行串口通信不需要考虑波特率。

           工作方式1:使用定时器作为波特率发生器。

                               波特率的计算  

                                              单片机 串口编程之串口通信仿真实验-LMLPHP

      工作方式2:

                                                                     单片机 串口编程之串口通信仿真实验-LMLPHP

      工作方式3:波特率计算方式与工作方式1相同。 

     

      6.波特率

           波特率是指数据信号对载波的调制速率,它用单位时间内载波调制状态改变的次数来表示。

           在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。

           通信双方约定一致的波特率以便正确的接收数据。(数据发送前可能进行了调制,波特率不同,调制参数不同)

          如果收发双方的波特率不一样,那么调制与解调的参数不一样,就很有可能读取不到正确的数据,从而解读为乱码。

          通常串口工作方式1使用定时器作为波特率发生器。

      7、串口中断

            使能串口中断:打开总中断-中断控制寄存器IE的EA位置1,打开串口中断中断控制寄存器IE的ES位置1

 

     使能串口中断之后,接收到数据(RI置1)/完成发送(TI置1),RI/TI被置1就会触发串口中断事件,然后执行中断处理函数。

     中断处理函数编写格式:               

void 函数名(void) interrupt 4 using 工作寄存器组编号
{
    //要执行的动作
}

      4的含义: 一共5个中断编号为0~4,串口中断的编号为4

      using 寄存器组编号:一共4组工作寄存器组,编号为0~3,如果不写默认为工作寄存器组0。

8、初始化串口为模式1过程。

      1) SCON设置

      SCON = 0x01010000 = 0x50    

       2) PCON设置

       

      PCON = 0x00 (SMOD=0,波特率不加倍)

      PCON = 0x80 (SMOD=1,波特率加倍)

      3) 定时器设置

              工作方式设置:

            开启定时器1:将控制寄存器TCON的TR1置1

            设置定时器1的初值:TH1数据寄存器装载初值的高8位,TL1数据寄存器装载初值的低8位。

            定时器用作波特率发生器时,使用上面的波特率计算公式得到初始值,或直接查看常见的波特率对应的初始值。

            TH1 = 0xFD;// 11.0592MHz的工作频率,9600的波特率 对应的初始值。 

        4) 打开总中断 EA = 1; 打开串口中断 ES = 1;

              

11-26 15:26