串口

发布时间 : 星期六 文章串口更新完毕开始阅读

D)TB8——工作方式2和3要发送的第9位数据

在许多通信协议中,该位是奇偶位,它可以按需要由软件置位或清除。在多处理机通信中,该位用于表示是地址帧还是数据帧。

E)RB8——工作方式2和3要接收的第9位数据 它可以是奇偶位或地址/数据标志位等等,在工作方式1中若SM2=0,则RB8是已接收的停止位。在工作方式0中RB8不使用。

F)TI——发送中断标志位

它由硬件置位,软件清除。工作方式0中,在发送第8位末尾由硬件置位;处于其他工作方式时,在发送停止位开始时由硬件置位。TI=1时,申请中断。CPU响应中断后,发送下一帧数据。在任何工作方式中都必须由软件清除TI。

G)RI——接收中断标志位

它由硬件置位,软件清除。工作方式0中,在接收第8位末尾由硬件置位;处于其他工作方式时,在接收到停止位时由硬件置位。RI=1时,申请中断,要求CPU取走数据。但在工作方式1中,SM2=1且未接收到有效的停止位时,不会对RI置位。在任何工作方式中都必须由软件清除RI。

系统复位时,SCON的所有位都被清零。 2)电源控制寄存器PCON

PCON也是一个逐位定义的8位寄存器,字地址位87H,只能按字节寻址,目前仅仅有几位有定义,见下表:

D7 SMOD D6 —— D5 —— D4 —— D3 GF1 D2 GF0 D1 PD D0 IDL PCON中仅最高位SMOD与串行口的控制有关。SMOD是串行通信波特率系数控制位,当串行口工作在工作方式1或工作方式2时,若使用T1作为波特率发生器,SMOD=1则波特率加倍,因此SMOD也称为串行口的波特率倍增位。

系统复位时,SMOD被清零。 4、串行口的工作方式

按照串行通信的数据格式和波特率的不同,8051系列单片机的串行口有四种工作方式,可以通过SM0SM1选择。

(1)方式0

方式0是同步移位寄存器方式。波特率固定为fosc/12。发送和接收串行数据通过RXD(P3.0)进行,TXD(P3.1)输出移位脉冲,控制外部的移位寄存器移位。一帧信息为8位,没有起始位、停止位,传输时低位在前。

A)方式0发送

串行数据从RXD引脚输入,TXD引脚输出移位脉冲。CPU将数据写入发送寄存器SBUF同时,立即启动发送,将8位数据以fosc/12的固定波特率从RXD输出,低位之在前,高位在后。发送完一帧数据后,发送中断标志TI由硬件置位。方式0下,单片机可外接移位寄存器以扩展I/O接口,也可以外部接同步输入/输出设备。

B)方式0接收

当串行口以方式0接收时,先置位允许接收控制位REN。此时,RXD为串行数据输入端,TXD仍为同步脉冲移位输出端。当RI=0且REN=1时,开始接收数据。当接收到第8位数据后,将数据一如接收寄存器SBUF,并由硬件置位RI。

(2)方式1

方式1是波特率可以改变的10位异步通信接口方式。发送或接收一帧信息,包括一个起始位0,8个数据位和一个停止位1.波特率可变,根据定时器1的溢出率计算。

A)方式1发送

当CPU执行一条指令将数据写入发送缓冲SBUF时,就启动发送。串行数据从TXD引脚输出,发送完一帧数据后,就由硬件置位TI,向CPU申请中断。

B)方式1接收

在REN=1时,串行口采样RXD引脚,当采样到下降沿时,确认是开始位0,就开始接收一帧数据。只有当RI=0且停止位为1或者SM2=0时,停止位才进入RB8,8位数据才能进入接收寄存器,并由硬件置位中断标志RI;否则信息丢失。所以在方式1接收时,应先用软件清零RI和SM2标志。

(3)方式2

固定波特率的11位UART方式,包括一位起始位“0”,8位数据位(先低位后高位),一位控制位(第9位)和一个停止位“1”。它比方式1增加了第9位数据TB8或RB8。波特率可变,为振荡频率的1/64或1/32 。在方式2下还是8个数据位,只不过增加了第9位,其功能由用户确定,是一个可编程位。

A)方式2发送

当CPU执行一条指令将数据写入发送缓冲SBUF时,就自动发送。附加的第9位来自SCON寄存器的TB8位,用软件置位或复位。它可作为多机通信中地址/数据信息的标志位,也可以作为数据的奇偶校验位。发送一帧信息后,置位中断标志TI。

B)方式2接收

在REN=1时,串行口采样RXD引脚,当采样到下降沿时,确认是开始位0,就开始接收一帧数据。在接收到附加的第9位数据后,只有当RI=0且停止位为1或者SM2=0时,第9位数据才进入RB8,8位数据才能进入接收寄存器SBUF,并由硬件置位中断标志RI,否则信息丢失。

(4)方式3

方式3为波特率可变的11位UART方式。波特率可变,根据定时器1的溢出率计算。除波特率不同外,其工作方式与工作方式2相同。 5、波特率的程序设定

串行工作模式0的波特率:模式0波特率=fosc/12

串行工作模式1的波特率:模式1波特率=T1溢出率·2SMOD/32 串行工作模式2的波特率:模式2波特率= fosc·2SMOD/64

串行工作模式3的波特率:模式3波特率=T1溢出率·2SMOD/32

6.2 串行口异步通信实验

今天我们的实验是两个单片机之间的串行通信:

通信的思路是:甲单片机首先将P1口拨动开关,数据载入串口寄存器SBUF,然后经由TXD将数据传给乙单片机,乙单片机将接收数据存入串口寄存器SBUF,再由SBUF载入累加器,并输出至P1,点亮相应端口的LED.

我们认为单片机1为发送数据,单片机2为接收数据。

编程的思路:对于单片机1,设置串行寄存器和设置波特率,然后启动定时器T1开始计数,读入P1口拨动的键值,若读入的键值与前次相同,则继续读入,若不相同,则将读入的数据载入串口寄存器SBUF,然后由TXD将数据发送出去。然后等待是否将数据发送完毕,若发送完毕,则结束,若没有结束,则继续等待。对于单片机2,设置串行寄存器和设置波特率,然后启动定时器T1开始计数,判断是否接收到数据,若接收到数据,则将接收到的数据存入串口寄存器SBUF,若没有接收到数据,则继续等待。我们再把串口寄存器SBUF的数据暂存到累加器A,并输出至P1,点亮P1端口的LED.最后清除串口中断标记,,继续接受数据。

6.2.1 实验的步骤:

1.Keil 软件开启动作(参照前面的软件介绍即可)

2.新建project(工程)文件保存在自定义或者系统默认文件夹中(编者建议每次新建工程(protect)时都保存在单独新建的文件夹中)。

3.通常情况下,我们选择Atmel公司生产的AT89C51芯片。

4.新建工程文件结束后,再新建text文件(创建文件快捷键:Ctrl+N;在未保存时,系统默认名为“text”)

5.新建完成后千万别忘记保存,否则软件崩溃,你的辛苦就白费了,保存新建的文件时注意文件的扩展名!如果你是用c语言编写的程序文件,则扩展名为“.c”;如果你是用汇编语言编写的程序文件,则扩展名为“.asm”。(注:程序文件的保存也可在编写程序完成后进行,保存命名最好不要用汉字) 6.2.2 参考实验程序和keil程序运行 单片机发送程序:

#include #include

#define uint unsigned int #define uchar unsigned char

void DelayMs();

void Init_deivces(); void Send_One_Byte(); void Port_Init(void) {

P4SW = 0xFF; //将P4.4 P4.5 P4.6设置成I/0口 P3 = 0xFF;//端口输出高电平 P2 = 0xFF; P1 = 0xFF;

P0 = 0xFF;//STC12 无须硬件上拉 }

void Timer_Init(void) {

BRT = 0xFD;//波特率自动加载,由于AUXR寄存器的BRTX12=0,波特率发生器每12个时钟计数一次 }

void Uart_Init(void) {

TMOD = 0x20; //定时器1工作方式2,自动重载的8位 SCON = 0x40; //串行工作方式1,允许发送 PCON = 0x80; //设置波特率不加倍 TH1 = 0xFD; //设置波特率为9600bps TL1 = 0xFD;

TR1 = 1; //启动t1 }

/************************************************************************* Function: 设备初始化

Argument: 端口,定时器,串口初始化 Return: 无返回值

*************************************************************************/ void Init_Devices(void) {

Port_Init(); Timer_Init(); Uart_Init(); }

void DelayMs(unsigned int n) //STC1T延时 500大约为1秒 {

unsigned int x; while (n--) {

for(x=0;x<500;x++); } }

/************************************************************************* Function: 向从机发送一个字节,无奇偶校验,9600bps Argument: 要发送的数据 Return: 无

*************************************************************************/ void Send_One_Byte(unsigned char ucData) {

DelayMs(1); ucData = P1; SBUF = ucData; while(!TI); TI=0;

DelayMs(1); }

void main(void) {

Init_Devices(); while(1) {

Send_One_Byte(0); DelayMs(1); } }

联系合同范文客服:xxxxx#qq.com(#替换为@)