单片机串口通信的多字节传输

题目: 一个8XX51单片机的双机通信系统波特率为9600bps,fosc=12MHz,用中断方式编写程序,将甲机片内RAM 30H ~ 3FH的数据块通过串行口传送到乙机的片内RAM 40 ~ 4FH单元中。


串口通信是一个字节一个字节的发送与接收,但实际上我们一般都是用来多字节的传输,而当我们用来多字节传输时,我们会发现,一旦我们传输速率加快,我们传输的数据就容易出错(我认为其实会出现数据传输不完全的情况)。

那这怎么解决呢?

这个就与我们单片机的晶振与我们设置的波特率有关了,当我们采用时钟周期为11.0592Mhz的晶振时,不管设置波特率多少(1200-115200范围,11.0592的最大波特率为115200,也是常用的波特率),误差为0,也就是说,假如当我们用11.0592Mhz的晶振产生9600的波特率,结果是刚刚好的。但是当我们采用12Mhz的晶振时,波特率越大误差越大, 这个时候一般常常使用波特率加倍减小误差(但是波特率越大,加倍其实也减小不了多少误差了,甚至误差不变)。

其实,我们可以通过延时来减小传输数据的误差,让其传输慢一点

比如题目要求我们要传输16个字节的数据,这个延时不加的话,会有问题(我出现了传输字节不够的情况,即没有传输到16个字节)。

发送数据时这个延时不能少,而当我们接收数据时,这个延时似乎是可以不要的(因为测试的时候我没有发现问题,原因我也不清楚),我为了保险,也进行了延时。

	//发送数据
	SBUF=*p;    //将p指向的地址所存储的值放进缓存区
	delay1ms(1);   //延时1ms
	//接收数据
	*p=SBUF;      //读取缓冲区的值
	delay1ms(1);  //延时1ms

完整代码如下

//发送数据

#include <reg52.h>
#include "Delay.h"

unsigned  char *p;  //指针,用来指向内存地址

void UART_Init()
{
	TMOD=0x20;    //设置计数器工作方式2
	SCON=0x40;    //串行口设置为工作方式1
	TH1=0XFD;     //计数器重装载值设置
	TL1=0XFD;    	//计数器初始值设置
	TR1=1;   			//打开计数器
	ES=1;     		//打开接收中断
	EA=1;   			//打开总中断
	
	p=0x30;     //p指向内存地址为0x30的空间
	SBUF=*p;    //将0x30这个地址所存储的值放进缓存区
	delay1ms(1);   //延时1ms
}

void main()
{
	unsigned  char k=0;
	p=0x30;
	*p=k;
	while(p!=0x3F)  //给30H ~ 3FH的内存地址赋值
	{
		p++;
		k++;
		*p=k;
	}
	
	UART_Init();   //中断初始化
	while(1);
}

void UART_Routine() interrupt 4
{
	TI=0;       //清除发送完成位标志
	p++;
	SBUF=*p;      //将值存入缓冲区
	delay1ms(1);  //延时1ms
	if(P==0x3F)
		EA=0;   //关闭总中断
}



//接收数据

#include <reg52.h>
#include "Delay.h"

unsigned char  *p;

void UART_Init()
{
	TMOD=0x20;    //设置计数器工作方式2
	SCON=0x50;     //串行口设置为工作方式1,并允许接受
	TH1=0XFD;     //计数器重装载值设置
	TL1=0XFD;     //计数器初始值设置
	TR1=1;        //打开计数器
	ES=1;        //打开接收中断
	EA=1;        //打开总中断
	p=0x40;
}

void main()
{	
	UART_Init();
	while(1);
}

void UART_Routine() interrupt 4
{
	RI=0;         //清除接收完成位标志
	*p=SBUF;      //读取缓冲区的值
	delay1ms(1);  //延时1ms
	p++;
	if(P==0x4F)
		EA=0;     //关闭总中断
}

测试结果
在这里插入图片描述
在这里插入图片描述

如果发现错误,请告知。

  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值