基本介绍
单片机通信是指单片机和单片机 或者 单片机和计算机的相互通信,一般比较多都是单片机(下位机)和计算机(上位机)作为通信。
串行通信其实用的还是挺多的,就比如我们在调试程序时,可以通过串行口来调试程序。像什么蓝牙模块、语音模块等等也挺多是用串行通信。
一般通信方式为两种:并行通信 和 串行通信。
通信制式
一共为3种:
单双工: 一个只能发送,一个只能接收。(相当于两个人,一个只能说话,一个只能听)
半双工:都可以发送和接收,但是同一时刻不能发送和接收同时进行。相当于一般的对讲机 你说话的时候 你是接收不了对方说的话的。
全双工:就是可以同时发送或者接收。相当于现在我们的手机打电话一样。可以两个人互骂哈哈
波特率
常用串口波特率一般为2400、4800、9600、115200…也有更低点的。
波特率是什么?
其实就是我们传输的速度,相当于两个人说话的语言语速,在通信时,我们得需要约定好大家的波特率。大家得统一。
1波特率(bps) = 1位/秒 (8位1字节)
如果想每秒传输 960 个字符 且是1个起始位、8个数据位、1个停止位(共10位) (960 X 10 = 9600)那9600bps 就是 1秒传输9600位数据。
一般波特率越高 传输距离短(不适宜长距离传输) 波特率低 传输距离可以远点,这样稳定点。
当比特率超过1000 bps 时,最大传输距离迅速下降,如9600 bps 时最大距离下降到只有76m(约250英尺)。
通信校验
一、奇偶校验
在发送数据时,数据位尾随的奇偶校验位(0或1)。
奇校验时:数据中的‘1’的个数与校验位‘1’的个数加起来为奇数。
偶校验时:数据中的‘1’的个数与校验位‘1’的个数加起来为偶数。
接收字符时,对于‘1’的个数进行校验,如果发现不一致,说明这个数据有错误。
二、和校验
和校验是发送方将所有数据块加起来(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块末尾,接收端接收数据同时对数据块(除校验字节外)加一起,(或者各字节异或),将所得的结果与发送方的校验和进行比较,如果相同则正确,相反则接收错误。
三、CAC校验
CRC校验通过某种数字运算实现有效信息与校验位之间的循环校验,这种校验方法纠错能力强,比较广泛应用。
在线计算网址
内部结构
51主要是由两个独立的寄存器缓冲区SBUF(一个发,一个接)和发送控制器、接收控制器、输入移位寄存器及其控制门电路。
我们主要就记住是通过SBUF发送和接收数据的,他们虽然名字一样,但是物理地址是不一样的,相当于一个房间一个前面(只能进)一个后门(只能出)不会冲突。
比如我想发送这个 字符 ‘A’ 给对方,就直接 SBUF = ‘A’; 给放到SBUF就好啦。 接收就 直接 value = SBUF。
并行通信
并行通信就是8根线一起传输(如下图)—,每一根线传输1位,一次就可以传输1个字节(8位)数据了。这样传输速度就相对串行通信快,但是但是硬件成本比较高,然后不适宜长距离传输,像如果是300米那岂不是拉好多根线来作为传输。而且还容易受到干扰。
一般我们是用串行通信比较多。
串行通信
串行通信跟并行通信区别就是 串行通信是一位一位的传输。传输速度没有并行通信那么快,但是硬件成本低,适宜长距离传输。我们一般都是用串行通信来的。
串行通信方式
同步通信
同步通信也是属于串行通信,它需要一个同一个时钟信号线来控制。(如下图)
像 IIC总线 和 SPI总线 则属于同步通信,都有一根SCL时钟线来控制的。
异步通信
异步通信是指通信的发送和接收设备使用各自的时钟控制数据发送和接收。为使双方发送和接收协调,要求发送和接收设备的时钟尽可能一致。异步通信是以字符(构成的帧)为单位进行传输。
一帧信息由4个部分组合:起始位、数据位、奇偶校验位、停止位。
有的字符信息也带空闲位,即在字符之间有空闲符。
起始位其实是一个标志准备开始,因为如果不发送和接收是处于空闲状态。都是高电平,那你想发送数据或者接收数据是不是得拉低 表示起始呢,不然我都不知道啥时候开始发送和接收了。停止位也是这个道理。
串行口的控制寄存器
工作模式:
SM2: 多机通信控制位。
主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI
(RB8=0时不激活RI,收到的信息丢弃;
RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。
当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
在方式0时,SM2必须是0。
在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。
REN: 允许串行接收位。
由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。
TB8: 在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。
在方式0和方式1中,该位未用。
RB8: 在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位。
在方式1时,若SM2=0,则RB8是接收到的停止位。
**TI:**发送中断标志位。
当串行发送第8位数据结束时,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。
RI: 接收中断标志位。
当串行接收第8位数据结束时,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。
PCON寄存器
SMOD: 波特率倍增位。
在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。
中断源及优先级
串口通信配置步骤
串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。
1、确定T1的工作方式(TMOD寄存器)
2、确定串行口控制(SCON寄存器);
3、计算T1的初值,装载TH1、TL1。
4、设定是否波特率增倍 (PCON寄存器)
5.、启动T1(TCON寄存器TR1位)
6、设置总中断允许以及设置串行口中断(IE寄存器)
7、优先级(IP寄存器) 看自己需求定
关于TMOD、IE、IP等寄存器配置这里没有写,是学定时器中断的相关内容,可以点击 这里 查看相关内容。
比如想配置一个 波特率为 9600。 我单片机是11.0592晶振。
TMOD = 0x20; //设定定时器工作方式2 8位初值自动重装定时/计数器
SCON = 0x50; //10位异步收发器(8位数据) 打开串口接收允许
TH1 = 0xFD; //9600波特率
TL1 = 0xFD;
PCON = 0x00; //波特率不增倍
TR1 = 1; //打开定时器1
EA = 1; //打开中断总开关
ES = 1; //允许串行口中断
关于初值的计算不会算可以通过一个软件 mcuelf 来快速计算,反正我不会算哈哈。或者 stc-isp串口助手 也可以。
相关程序
简单例程1
我们用电脑通过串口助手发送数据给单片机 单片机将收到内容发给计算机。
代码:
#include /*初始化串口函数*/ void init_uart() { TMOD = 0x20; //设定定时器工作方式2 8位初值自动重装定时/计数器 SCON = 0x50; //10位异步收发器(8位数据) 打开串口接收允许 TH1 = 0xFD; //9600波特率 TL1 = 0xFD; PCON = 0x00; //波特率不增倍 TR1 = 1; //打开定时器1 EA = 1; //打开中断总开关 ES = 1; //允许串行口中断 } /*主函数入口*/ void main() { init_uart(); //启动串口 while(1); } /*串口中断服务函数*/ void uart_dispose() interrupt 4 { unsigned char dat; //存放数据 if(RI == 1) //如果有数据来 { dat = SBUF; //接收数据 RI = 0; SBUF = dat; //发送内容 while(!TI); //判断是否发送完毕 TI = 0; //软件清零 } } 运行结果: 简单例程2 串口发送指令(‘1’)给单片机 单片机发送hello world 回应。 #include char code array[11] = {"hello world"}; //定义要发送的内容 unsigned char flag = 0; //标志位 /*初始化串口函数*/ void init_uart() { TMOD = 0x20; //设定定时器工作方式2 8位初值自动重装定时/计数器 SCON = 0x50; //10位异步收发器(8位数据) 打开串口接收允许 TH1 = 0xFD; //9600波特率 TL1 = 0xFD; PCON = 0x00; //波特率不增倍 TR1 = 1; //打开定时器1 EA = 1; //打开中断总开关 ES = 1; //允许串行口中断 } /*串口发送数据函数*/ void send_data(unsigned char c) { SBUF = c; while(!TI); TI = 0; //这里有TI 置 0了 不需要在串口中断再次写 否则会冲突 } /*主函数入口*/ void main() { unsigned char i; init_uart(); while(1) { if(flag == 1) //收到指令 1 { /*可以去自己设定去点亮某个LED灯丫 喇叭响起等等*/ for(i=0;i<11;i++) //我这里就是发送 hello world { send_data(array[i]); } flag = 0; //标志位复位 } } } /*串口中断服务函数*/ void uart_dispose() interrupt 4 { unsigned char dat; //存放数据 if(RI == 1) //如果有数据来 { dat = SBUF;//接收数据 switch(dat) { case '1': flag = 1; break; default: flag = 0; break; } RI = 0; //软件置0 } /*发送字节函数那里已经有TI置0 这里不加。*/ } 运行结果:
上一篇:基于51单片机---遥控灯
下一篇:51单片机中断篇
推荐阅读最新更新时间:2024-11-11 10:12
设计资源 培训 开发板 精华推荐
- 航顺MCU HK32F030最小系统开发板
- LM1875 功放 DCDC供电 V1.1
- LT3471,一个 1.2MHz、锂离子至 5V 和 12V 转换器
- A8498 宽输入电压 3A 降压稳压器的典型应用
- 基于C8051F413 8051 MCU的录音机电路
- stc15w4k58W播放WAV文件
- AD8604ARZ-REEL 作为 DAC 输出缓冲器驱动重负载的典型应用
- EFM32WG-STK3800、EFM32 Wonder Gecko 入门套件是一个功能丰富的平台,用于评估、原型设计和应用程序开发,适用于具有 ARM Cortex-M4F CPU 内核的 EFM32WG990F256 EFM32 Wonder Gecko MCU 系列
- 具有软启动组件的 LT1308BIS8 5V 至 12V 升压转换器的典型应用电路
- ADR431A 2.5 Vout 超低噪声 XFET 电压基准的典型应用,具有灌电流和拉电流能力