我是靠谱客的博主 传统白云,这篇文章主要介绍51单片机常用通信方式之串口(UART)(一),现在分享给大家,希望可以做个参考。

        在我这里没有太多的理论废话,主要给大家把串口的寄存器、重要参数、怎么用代码实现的操作发出来,供大家参考一些,当然,自己能力有限,如有纰漏,敬请指正。

还有就不知道单片机是啥、串口理论、定时器理论、中断理论的不建议看我这篇文章,要不然得骂我,这篇文章主要给那些用串口设计小东西,可以过来瞅瞅。

        还有就是自己在实践过程中遇到许多的问题,这里我直接写出来解决方法,应该可以解决大部分串口问题。

串口接线

        主要两根线:Rx,Tx,外设和单片机进行串口通信时,单片机Rx要和外设Tx相连,单片机Tx和外设Rx相连,这个相对于的一种规定,必须这样连。

寄存器

        讲寄存器之前串口有个主要参数就是波特率,波特率就是串口传输数据的速度,波特率越大,传输数据速度也越快,但是因为51单片机自身硬件原因,波特率不能太大,一般情况下都是9600,这个波特率由定时器1产生。

        串口寄存器有好几个,但是有一部分都用不到,这里就贴出来两个最常用的,也是必须的。

中断允许控制寄存器(IE)

ET0和ET1:这两个是控制定时器中断的开关,因为我们用到定时器来产生波特率,所以让ET1=1,打开定时器中断,则定时器0没有用到,就关闭它,ET0=0;

 ES:串行口中断允许位;就是串口发送过来一个数据,产生中断,这个置1(让ES=1),也就是打开它,就会允许中断,直接接收数据;

EA :总中断,也必须置1,这是中断系统的总开关,它必须打开,也就是置1;

        其余的用不到全部关闭(置0);

        这个寄存器控制串口中断的,当外设发送给单片机数据的时候,就会产生一个中断信号,这个时候单片机就知道了有数据过来,中断允许之后,然后就会放下正在执行的数据,来接收来自外界发送的数据,当然,这个速度是非常快的,快到肉眼看不出来。

串口控制寄存器(SCON)

REN:允许/禁止串行接收控制位。即REN=1为允许串行接收状态,可启动串行接收器Rx,开始接收信息。即REN=0,则禁止接收。

RI: 接收中请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1, 
向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1,必须由软件复位,即RI=0。(软件的也是在代码里面写出来)

TI: 发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件自动置位, 
即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位。

SM1,SM0:是控制串口的工作方式,一般情况下都是工作方式1;

 其余都用不到了置0就可以了;

上面寄存器困难有点难理解可以在代码里面理解,代码里面有各种注解

直接上代码

第一个是串口文件,我利用的是函数封装

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "uart.h" /*串口通信工作方式1,由定时器1产生波特率,定时器0不能产生波特率,晶振11.0592*/ void T1_init() //串口初始化 { TMOD|=0x20; //定时器1工作方式2 PCON=0; //波特率加倍 SCON=0x50; //工作方式1 TH1=0xfd; //八位自动重装载,波特率9600 TL1=0xfd; ES=1; //打开串口中断 EA=1; //打开总中断 TR1=1; //打开定时器(这是另外一个定时器,因为这是定时器有关定时器,就没有粘出来) } //发送一个字节(八位) void Send_byte(u8 cha) { SBUF=cha; while(TI==0); TI=0; } //发送字符串函数(多个八位) void Send_string(u8 *table) { while(*table!='') { Send_byte(*table); table++; } }

串口头文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
#ifndef __uart_H__ #define __uart_H__ #include "main.h" void T1_init(); void Send_byte(u8 cha); void Send_string(u8 *table); #endif

主程序,向外设发送520.1314

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "main.h" #include "uart.h" u8 dat[10]; u16 i=0; void main() { T1_init(); Send_string("520.1314"); while(1); } void T1_timer() interrupt 4//串口中断 { if(RI) //如果接收到数据,RI=1,还会产生中断, { RI=0;//手动清除标志位,RI dat[i++]=SBUF;//把接收到的数据储存在dat数组中,中断一次提取一次 } }

主程序头文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef __main_H__ #define __main_H__ #include <REGX52.H> #include <intrins.H> #define u16 unsigned int #define u8 unsigned char #endif

此代码是单片机向外设发送520.1314;利用串口调试助手,可以轻松看到;

演示效果

接收缓冲区是显示的是单片机向外设发送的数据

发送缓冲区是指外设发送数据的地方

外设向单片机发送数据,单片机把接收到的数据在发送出来

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "main.h" #include "uart.h" u8 dat[10]; u16 i=0; void main() { T1_init(); while(1) { Send_byte(dat[0]); } } void T1_timer() interrupt 4//串口中断 { if(RI) //如果接收到数据,RI=1,还会产生中断, { RI=0;//手动清除标志位,RI dat[i++]=SBUF;//把接收到的数据储存在dat数组中,中断一次提取一次 } }

 

最后

以上就是传统白云最近收集整理的关于51单片机常用通信方式之串口(UART)(一)的全部内容,更多相关51单片机常用通信方式之串口(UART)(一)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部