一、串口介绍。
串口是一个 通讯接口。成本低,容易使用,通信线路简单,可实现两个设备的相互通信
单片机的串口可以实现单片机于单片机,单片机与电脑,单片机与其他模块相互通信。
51单片机内部自带UART,通用异步手法器,实现单片机的串口通信。
二、硬件电路
1、简单双向串口通信有两根通信线(发送端TXD和接收端RXD)
TXD和RXD要交叉连接,
当电平标准不一致时,需要加电平转换芯片。
通信必须需要txd和rxd和gnd三根线
三、电平标准
电平标准时数据1和数据0的表达式,时传输线缆中人为规定的电平与数据的对应关系,串口常用的标准三种:
TTL电平:-+5表述1,0V表示0
RS232电平:-3~-15V表示1,+3~+15V表示0
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)
TTL和RS232z最多可以输出十多米
RS485可以达到1000米
四、通信接口
(1)c51的单片机串口
名称:UART 引脚定义:TXD RXD 通信方式:全双工、异步 特点:点对点通信
(2)串行通信模式
全双工:通信双方可以在同一时刻互相传输数据。
半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
单工:通信只能一方发送给另一方。
(3)传输数据方式
异步:通信双方各各自约定通信速率
同步:通信双方靠一根时钟线来约定通信速率
(4)其他
总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,让住户相互交流)
波特率:串口通信的速率,单位时间内发送的比特率(bits\s)
检验位:用于数据验证(奇校验与偶校验)
停止位:用于数据帧间隔
时序图
五、51单片机的UART
c51中只有1个UART
其有4种工作模式:
(1)模式0:同步移位寄存器
(2)模式1:8位UART,波特率可变(常用)
(3)模式2:9位UART, 波特率固定
(4)模式3:9位UART,波特率可变
六、串口模式图
SBUF:串口数据缓存寄存器。物理上时两个独立的寄存器,但占用的是相同的地址。写操作时,写入的是发送寄存器,读操作时,独处的时接收寄存器。
在总线上接受数据和发送数据,靠定时器计数,T1的溢出率经过二分频或16分频控制收放的速率,通过SBUF写入发送数据。将数据放在SBUF,单片机自动读写数据,发送之后会申请TI这个发送中断,接收数据会生成RI接受中断。
七。寄存器
还有定时器,中断的寄存器看前面的文章。
七、课堂练习
发送数字,数码管输出相应的数字。
uart.c
#include "reg51.h"
#include "utils.h"
#include "ledNum.h"
void uartInit(void)
{
SCON |= 0x01<<6; //选择uart 工作方式1 8位的uart
SCON |= 0x01<<4; //开启接收
PCON |= 0x01<<7; //波特率设置翻倍
TH1 = 243;
TL1 = 243;
TMOD |= 0x01<<5;
TCON |= 0x01<<6; //开启定时器
//串口中断相关
IE |= 0x01<<7 | 0x01 << 4; // 开启总中断 和 串口中断
}
void sendOneByte(unsigned char ch)
{
SBUF=ch;
while (SCON&(0x01<<1) == 0)
;
SCON &= ~(0x01<<1); //软件清零
}
void sendStr(const char *s)
{
int i = 0;
while (s[i])
{
sendOneByte(s[i]);
++i;
delay(30000);
}
}
void uartHandler(void) interrupt 4
{
if (SCON&0x01)//接收中断
{
P2 = ~P2;
displayNum(1,SBUF);
SCON &= ~0x01<<0;
}
}
uart.h
#ifndef _UART_H_
#define _UART_H_
void uartInit(void);
void sendOneByte(unsigned char ch);
#endif
延迟 utils.c
void delay(unsigned int n )
{
while(n)
--n;
}
延迟 utils.h
#ifndef _UTILS_H_
#define _UTILS_H_
void delay(int n);
#endif
ledNum.c
#include <reg51.h>
void displayNum(unsigned int dig,int n)
{
unsigned char num[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,
0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71, 0x00};
//位的选择
P1 = 0x01 << (dig-1); //1 2 3 4
//显示数据 --段的选择
P0 = num[n];
}
void display(int num)
{
//1234
unsigned int k = 0;
unsigned int i = 1;
while(num)
{
k = num % 10; //
displayNum(i,k);
num = num/10; //123
i++;
// delay(500);
}
}
main.c
#include "reg51.h"
#include "uart.h"
#include "utils.h"
#include <stdio.h>
void main(void)
{
uartInit();
while (1)
{
sendOneByte(SBUF);
delay(10000);
}
}