串口通信
来源:互联网 发布:演唱会设备清单知乎 编辑:程序博客网 时间:2024/05/23 11:56
串口通信
通信按照基本类型可以分为并行通信和串行通信。并行通信的各个数据位同时传送,但占用资源多,成本高;而串行通信的数据位是由低位到高位一位一位发送的。
常用的通信从传输方向上可以分为单工通信、半双工通信、全双工通信三类。
1.单工通信就是指只允许一方向另外一方传送信息,而另一方不能回传信息。比如电视遥控器、收音机广播等,都是单工通信技术。
2.半双工通信是指数据可以在双方之间相互传播,但是同一时刻只能其中一方发给另外一方,比如我们的对讲机就是典型的半双工。
3.全双工通信就发送数据的同时也能够接收数据,两者同步进行,就如同我们的电话一样,我们说话的同时也可以听到对方的声音。
二.串口通信的基本知识:
通常一个单片机有两个引脚是来做UART通信的,P3.0(RXD)、P3.1(TXD),两个单片机通信的示意图:
TXD 是串行发送引脚,RXD是串行接收引脚。两个单片机之间要通信,首先电源基准得一样,所以我们要把两个单片机的 GND 相互连接起来。
串行通信的数据发送过程:
在 UART 通信的时候,一个字节是8位,规定当没有通信信号发生时,通信线路保持高电平,当要发送数据之前,先发一位 0 表示起始位,然后发送 8 位数据位,数据位是先低后高的顺序,数据位发完后再发一位 1 表示停止
位。这样本来要发送一个字节的 8 位数据,而实际上我们一共发送了 10 位,多出来的两位其中一位起始位,一位停止位。而接收方呢,原本一直保持的高电平,一旦检测到了一位低电平,那就知道了要开始准备接收数据了,接收到 8 位数据位后,然后检测到停止位,再准备下一个数据的接收。
三、串口通信速率的约定:
串口通信的时候涉及到引脚的高低电平的持续时间,比如发送一个0和1,发送引脚先持续一段低电平,在持续一段高电平,那么这个数据就发送过去了,这个时间是如何约定的,这就需要了解通信当中的另外一个概念——波特率(baud)。
发送一位二进制的时间=1/baud,通信之前,单片机 1 和单片机 2 首先都要明确的约定好它们之间的通信波特率,必须保持一致,收发双方才能正常实现通信。
四.USB转串口通信
现在大多数的笔记本电脑上已经没有串口了,所以一般我们的电路板上会有一个USB转串口的芯片,以实现实现USB通信协议和标准UART串行通信协议的转换,一般常用的芯片有ch340和pl2303这两个转串口的芯片
五、UART模块介绍:
51单片机的 UART串口的结构由串行口控制寄存器SCON、发送和接收电路三部分构成。
SCON-串行控制寄存器的位分配(地址0x98,可位寻址)
SCON - 串行寄存器位描述
可以位寻址的含义:支持对寄存器的单个位进行操作,不可位寻址的只能一次性对寄存器进行整体操作。
串口通信的波特率,只能由定时器T1或T2产生,不能由T0产生。使用定时器2,则需要配置额外的寄存器,默认使用的是定时器1。使用定时器1产生波特率需要使用定时器1的模式2,即自动重载模式:
TH1 = TL1 = 256 - 晶振值/12/2/16/波特率
波特率有关的还有一个寄存器,是一个电源管理寄存器PCON,他的最高位可以把波特率提高一倍,也就是如果写 PCON |= 0x80 以后,计算公式就成了:
TH1 = TL1 = 256 - 晶振值/12 /16 /波特率
关于SBUF寄存器:
串口通信的发送和接收电路在物理上有2个名字相同的SBUF寄存器,它们的地址也都是0x99,但是一个用来做发送缓冲,一个用来做接收缓冲。意思就是说,有2个房间,两个房间的门牌号是一样的,其中一个只出人不进人,另外一个只进人不出人,这样的话,我们就可以实现UART的全双工通信,相互之间不会产生干扰。我们每次只操作SBUF,单片机会自动根据对它执行的是“读”还是“写”操作来选择是接收 SBUF 还是发送 SBUF。
//例:发送 SBUF = 1;//接受P0 = SBUF;
六、串口通信的基本配置步骤:
1、配置串口为模式 1。
2、配置定时器 T1 为模式 2,即自动重装模式。
3、根据波特率计算 TH1 和 TL1 的初值,如果有需要可以使用 PCON 进行波特率加倍。
4、打开定时器控制寄存器 TR1,让定时器跑起来。
T1 做波特率发生器的时候,千万不要再使能 T1 的中断了。否则会使产生的波特率发生错误。
void UART_Init(unsigned int baud){SCON = 0x50; //配置串口为模式 1TMOD &= 0x0F; //清零 T1 的控制位TMOD |= 0x20; //配置 T1 为模式 2TH1 = 256 - (11059200/12/32)/baud; //计算 T1 重载值TL1 = TH1; //初值等于重载值ET1 = 0; //禁止 T1 中断//ES = 1 ; //使能串口中断TR1 = 1; //启动 T1}
当我们使用串口中断的时候:
//首先main函数中打开总中断main(){ EA = 1; //使能总中断UART_Init(9600); //将里面的串口使能中断打开...}//串口中断服务函数void InterruptUART() interrupt 4{if (RI) //接收到字节{RI = 0; //手动清零接收中断标志位SBUF = SBUF + 1; //接收的数据+1 后发回,左边是发送 SBUF,右边是接收 SBUF}if (TI) //字节发送完毕{TI = 0; //手动清零发送中断标志位}}
串口接收和发送数据的时候,都是一个字节一个字节的进行的,假如我们想要发送一个字符串的话,我们可以先写好一个字节的发送函数,然后再写一个发送字符串的函数,通过循环的方式一个字节一个字节的发送过去,这样我们就可以放字符串了。
七、关于ASCII码:
我们常用的字符就包含了0~9的数字、A~Z/a~z的字母、还有各种标点符号等。那么在单片机系统里面我们怎么来表示它们呢?ASCII码(AmericanStandardCodeforInformationInterchange,即美国信息互换标准代码)可以完成这个使命:我们知道,在单片机中一个字节的数据可以有 0~255 共 256个值,我们取其中的0~127共128个值赋予了它另外一层涵义,即让它们分别来代表一个常用字符,当我们用字符格式发送一个小a,其实发送的是十六进制的0x61,这样就体现了ASCII码表的用处,其具体的对应关系如表:
ASCII码字符表
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- “串口通信”
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 串口通信
- 张孝祥[致敬]-多线程学习第04课-线程的通信机制
- gcc选项-g与-rdynamic的异同
- js关闭当前页面(窗口)的几种方式总结
- AndFix Bug热修复框架的使用
- Hibernate中Criteria的完整用法
- 串口通信
- 2016/11/09
- vim中使用cscope
- C++ int转string
- mysql分区
- Android Ndk C/C++ 程序中的Logcat调试输出
- 进军欧洲市场,除了亚马逊和eBay,还有这10大电商平台
- 校园电信翼讯账号写入路由器上网
- hadoop远程访问权限不足