单片机_串口通信详解(转)

https://blog.csdn.net/xuewei_Li/article/details/87925015
单片机_串口通信详解
  
  楼主在实际的项目开发过程中,特别是用一些比较常见的传感器,使用最多的通信方式可能就是串口通信了,特别是UART(通用异步收发器),线少,虽然传输速度没有并行传输高,但是对我们要求不高的项目中,足够了!足够了!足够了!最重要的是简单!简单!简单!

理论篇

串行通信和并行通信
  速度和资源的问题,比如说一个字节八位,如果一位一位通过一根线传输那就是串行通信,但要是八位同时通过八根线一起发,就是并行通信。

串行通信的三种传送方式
  单工: 数据传输只支持数据在一个方向上传输,应用如监视器、电视机
  半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信,应用如对讲机,只能一个人讲一个人听,但是两个人都可以讲和听。不能同时进行。
  全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。应用如打电话,两个人可以同时讲话,同时听到对方的内容。

串行通信的两种通信方式

前面说过,串行通信是通过一根线来接受发送的,问题来了,怎么发送是不是就是一个问题?

如果我想什么时候发送给你一帧数据(包括由起始位1位、数据位8位、奇偶校验位1位和停止位1位组成),没有约定,也就是一帧数据发送完到下一帧数据中间间隔的时间是不确定的,这种就是异步通信。

图片来自:https://blog.csdn.net/u012160319/article/details/43486995

注意这里每个字符都是固定的格式,但是中间的空闲位是不确定的。

但如果,我们规定好1秒钟你就必须发送给我9600位数据,这个时候你也想既然时间都定了,没必要没一帧数据都加一个起始位、奇偶校验位、停止位,就在开始发送一两个同步字符,告诉我开始发了,后面连续按顺序传送数据,没有间隙,知道一块数据发送完成。这就叫同步通信

图片来自:https://blog.csdn.net/u012160319/article/details/43486995

注意这里在数据流的开始有规定的1或2个约定的同步字符后数据是连续按顺序的。

所以同步和异步最重要的区别就是有没有同步时钟。而且同步通信是有一根时钟线的。
  异步通信传输是以字节为单位的,但是同步通信传输是以数据块(帧)为单位的。

常见的串行通信

这里说一下USART,USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。他是和UART兼容的,但是USART是支持同步的,所以如果你想使用其进行同步通信,还要接其时钟线,但是我们实际上都是按照UART用。  //手动滑稽

波特率、奇偶校验位、停止位 (摘自百度)
  
  波特率:指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,这是一个衡量符号传输速率的参数。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。

起始位:提示接收器数据传输即将开始,即标志传输一个字符的开始。必须是持续一个比特时间的逻辑0(低电平),使数据线处于逻辑0低电平状态,发送器通过发送起始位而开始一个字符传送,接收方可用起始位使自己的接收时钟与发送方的数据同步。
  奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。
  停止位:用于表示单个数据包的最后一位。典型的值为1*,1.5和2位*。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

看到这里,博主突然想到一个问题,不知道大家有没有发现一个问题,就是我们平时使用的串口小助手,当我们用UART时候,我们使用设置了有无就检验,既然没有同步时钟,为啥还要有一个波特率的设置呢?

看到没,看到没,这里下次给大家说明一下哦!

实战篇

//这里转自郭天祥单片机的串行口测试程序,使用51单片机的定时器1确定比特率,具体通信方式为UART
//补充一个知识点—串口中断,当单片机接收到一帧数据后,RI会置1,向CPU申请中断,若之前有中断允许,
//则产生了中断,进入中断服务程序。当然,单片机发送完一帧数据,TI也会置1,同样会产生中断!

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

#define BAUDRATE 2400 //波特率
#define SYSTEMCLOCK 12000000 //系统时钟频率

void uart_sendstring(unsigned char *str);

//主函数
void main(void)
{

SCON = 0x50;
TMOD |= 0x20;
TH1 = 256 - (unsigned int)(SYSTEMCLOCK/BAUDRATE/384+0.5); 
ES = 1;  //时能串口中断
EA = 1;
TR1 = 1;  //启动定时器1

uart_sendstring("hello,world.\r\n");

while(1); 

}

//通过串口发送字符串
void uart_sendstring(unsigned char *str)
{
unsigned char *p;

p = str;
while(*p != '\0')
{
    SBUF = *p;
	while(TI == 0);  //等待发送标志位置位
	TI = 0;
    p++;
}

}
//这部分程序很简单,就是发送一串字符串,可用
————————————————
版权声明:本文为CSDN博主「xuewei_Li」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xuewei_Li/article/details/87925015

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值