AT89S52之串行异步通信笔记

SRF

中断入口地址

- 中断源
- 外中断
- 外部中断0 INT0(P3.2)
- 外部中断1 INT1(P3.3)
- 电平方式触发
- 低电平
- 脉冲方式触发
- 脉冲后延的负跳
- 内中断
- 定时中断
- 串行中断
- 外中断
中断允许控制寄存器
- EA中断允许总控制位
- ES串行中断允许控制位
- ET2、ET1、ET0、EX1、EX0

- AT89S52有两个定时/计数器T1,T2
- T1,T2各有四种工作方式
定时器/计数器工作方式寄存器TMOD
- 工作方式



顾 12M的晶振对于一个正道周期为1/12us ,一个机器周期为1us
方式1位16位寄存器,顾最大65536个数 从0-65535-0变化
所以,你要想定时1us,因为它溢出中断,所以FF FF 执行完+1 后溢出 置位TF0 并 触发中断 定时器恢复为0
定时器/计数器控制寄存器TCON
溢出TF:查询方式,软件清零;中断方式,硬件自动清零。
允许TR:启动停止

串行控制口寄存器SCON
- 串行口工作方式
- REN控制是否允许接受。当REN=1时,允许接收,当REN=0
- 方式0,8位移位寄存器方式,典型应用串口驱动数码管
- 方式1,10位异步通信方式,通信的帧格式为1个起始位0,8个数据位,最后是停止位1
- 方式2,11位方式,通信的帧格式为1个起始位0,9个数据位,第九位作为奇偶校验位或者多机通讯是的地址数据标识位,最后是停止位1,共11个二进制位。

串行口工作方式选择:

电源控制寄存器PCON
- 波特率加倍

定时器T1的溢出率:

定时器T1的波特率的计算公式:
- 串行口传输方式为方式0和方式2的波特率不灵活:
- 串行口传输方式为方式1或者方式3时的波特率灵活,其计算公式:



常用波特率:

汇编使用定时器1工作在方式1【10位数据帧格式】(无奇偶校验位)发送接受(双向,允许接受,REN=1),配置波特率为9600bit/s,
①设置定时器1工作方式2:
MOV TMOD, #20H ;M1,M2为10,T1为定时方式2
②设置定时器1的初始值:
MOV TL1, #0FDH ;TL1为8位定时/计数
MOV TH1, #0FDH ;TH1为自动装载的初值,波特率为9600bit/s
②启动定时器1工作(TCON):
SETB TR1 ;启动定时器
④设置串行口工作方式:
MOV SCON, #50H ;串行口工作在方式1
⑥设置波特串加倍位为不加倍
SMOD:MOV PCON,#00H
⑥开中断开关IE:
SETB ES;
SETB EA;

实验现象
未发送完SBUF里的数据时,SCON 寄存器里TI位为0

当发送完SBUF里的数据时,SCON 寄存器里TI位由硬件自动置1,并进入中断


注意事项:
当确认程序配置的波特率无误,但是利用串口调试助手接受到数据和实际单片机发送的数据不吻合时可按下面检查
- 查看芯片的晶振,检查配置的波特率是否误差较大(>1%),利用单片机小精灵查看

- 查看自己使用的串口调试助手的跳线帽,STC89C52单片机输出的串口信号是0-3.3V电平,跳线帽应短接3.3端而不是5V端。
- 当下载完程序后应先进行复位操作再进行串口调试,查看数据。
AT89S52之汇编实现串行通信-只发送数据
;中断方式,硬件自动清除定时器1中断,即清除TF1标志位
;数据从TXD端输出,当数据写入发送缓冲器SBUF后,启动发送器发送。当发送完一帧数据后,置中断标志TI为1。T1为串行控制寄存器里的
/**
**AT89S52之汇编实现串行通信-只发送数据
**备注:波特率为4800bit/s,波特率误差为0.16%,采用定时器1工作在方式2(自动装载初值),采用串口传输方式1(10位数据帧格式)
*/
ORG 0000H
LJMP MAIN
ORG 001BH;定时器1中断
LJMP IT1P
ORG 0023H;串行传输中断
LJMP SEND
ORG 0100H
MAIN:
MOV TMOD, #20H ;M1,M2为10,T1为定时方式2
MOV TL1, #0F3H ;TL1为8位定时/计数
MOV TH1, #0F3H ;TH1为自动装载的初值,波特率为4800bit/s
MOV SCON,#50H ;串口工作方式1 10位数据格式
;SETB ET1 ;允许定时器1中断,有病吧,你开TM定时器1中断干哈????
SETB EA ;允许总中断
SETB ES ;允许串行传输中断ES,传输完成触发中断
MOV PCON,#80H;波特率加倍,减小波特率误差 0.16%
SETB TR1 ;启动定时器
LOOP:MOV A,#99H
MOV SBUF,A
CONT:
INC DPTR
LJMP $
//WAIT:JBC TI,CONT ;判断发送结束否,必须要有个等待发送完毕的过程,发送完毕才能进行下一次的发送
//SJMP WAIT
IT1P:
INC DPTR
RETI ;中断服务程序的返回必须用RETI,用RET则CPU不会清除中断,造成下次无法进入中断
SEND:
CLR TI;TI的位地址是99H,存在于字节地址为98H的SCON第二位里
MOV A,#66H
MOV SBUF,A
RETI
END
2018-12-2日更新 汇编实现数据收发
;中断方式,硬件自动清除定时器1中断,即清除TF1标志位
;数据从TXD端输出,当数据写入发送缓冲器SBUF后,启动发送器发送。当发送完一帧数据后,置中断标志TI为1。T1为串行控制寄存器里的
/**
**AT89S52之汇编实现串行通信-只发送数据
**备注:波特率为4800bit/s,波特率误差为0.16%,采用定时器1工作在方式2(自动装载初值),采用串口传输方式1(10位数据帧格式)
*/
//定时延迟之类的必须大于一个机器周期
;=================================================================================================================
ORG 0000H
LJMP MAIN
ORG 000BH ;定时器0中断
LJMP Timer0Interrupt
ORG 001BH ;定时器1中断
LJMP Timer1Interrupt
ORG 0023H ;串行传输中断
LJMP UARTInterrupt
ORG 0100H
MOV SP,#60H
;=================================================================================================================
;=================================================================================================================
MAIN:
LCALL InitTimer0 ;定时器0初始化
LCALL InitUART ;串口初始化
MOV A,#99H
MOV SBUF,A
CONT:
INC DPTR
LJMP $
;=================================================================================================================
;定时器0中断服务函数
Timer0Interrupt:;定时器中断里赋定时初值,其定时是时间不能小于本中断里所以程序语句执行时间,否则定时器会一直中断????;或者最后清除中断,但是一定要清除,否则会一直进入中断,无法执行其他程序和进入其他中断
PUSH DPH
PUSH DPL
PUSH ACC
MOV TH0,#00H ;
MOV TL0,#01H
;========================
CPL P2.7
//延迟1s
MOV R2,#01H
LCALL DELAY1S
;========================
POP ACC
POP DPL
POP DPH
CLR TF0
RETI
;=================================================================================================================
;定时器1中断服务函数
Timer1Interrupt:
PUSH DPH
PUSH DPL
PUSH ACC
MOV TH0,#0FFH
MOV TL0,#0FFH
;========================
;add your code here!
;========================
POP ACC
POP DPL
POP DPH
CLR TF1
RETI
UARTInterrupt:
JB RI,IsUART_Receive ;RI为1则转移
CLR TI ;TI的位地址是99H,存在于字节地址为98H的SCON第二位里
CPL P2.6
MOV R2,#01H
LCALL DELAY1S
MOV A,#99H
MOV SBUF,A
RETI ;中断服务程序的返回必须用RETI,用RET则CPU不会清除中断,造成下次无法进入中断
;=================================================================================================================
InitTimer0:
MOV TMOD,#01H ;工作方式1,16位计数器
MOV TH0,#00H
MOV TL0,#01H
SETB ET0 ;开定时器T0中断
SETB EA ;开总中断
SETB TR0 ;启动定时器
RET
;=================================================================================================================
/*
InitTimer1:
MOV TMOD,#20H ;M1,M2为10,T1为定时方式2
MOV TL1, #0F3H ;TL1为8位定时/计数
MOV TH1, #0F3H ;TH1为自动装载的初值,波特率为4800bit/s
MOV SCON,#50H ;串口工作方式1 10位数据格式
MOV TMOD,#01H
MOV TH0,#0FFH
MOV TL0,#0FFH
SETB EA ;开总中断
SETB ET0 ;开定时器T0中断
SETB TR0 ;启动定时器
RET
*/
;=================================================================================================================
InitUART:
MOV TMOD,#20H ;M1,M2为10,T1为定时方式2
MOV TL1, #0F3H ;TL1为8位定时/计数
MOV TH1, #0F3H ;TH1为自动装载的初值,波特率为4800bit/s
MOV SCON,#50H ;串口工作方式1 10位数据格式
;SETB ET1 ;关定时器1中断,定时器1会自动装载初值,无需中断
SETB EA ;开总中断
SETB ES ;开串行传输中断ES,传输完成触发中断
MOV PCON,#80H ;波特率加倍,波特率误差为 0.16%
SETB TR1 ;启动定时器
RET
;=================================================================================================================
IsUART_Receive: ;发送中断里先查询是否接受
CLR RI
PUSH ACC
MOV A,SBUF
;========================
CPL P2.0
MOV R2,#01H
LCALL DELAY1S
;========================
POP ACC
RETI
DELAY1S: ;误差 0us
START:
MOV R7,#38H
DL1:
MOV R6,#0E2H
DL0:
MOV R5,#26H
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
NOP
DJNZ R2,START
RET
END
C51编程


AT89S52之串行异步通信笔记的更多相关文章
- Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)
利用状态机实现比较复杂的接口设计: 这是一个将并行数据转换为串行输出的变换器,利用双向总线输出.这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍: I2C总线(inter integra ...
- STM32学习笔记(五) USART异步串行口输入输出(轮询模式)
学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在 ...
- STM32学习笔记——SPI串行通讯(向原子哥学习)
一.SPI 简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在 EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...
- JVM_垃圾回收串行、并行、并发算法(总结)
一.串行 JDK1.5前的默认算法 缺点是只有一个线程,执行垃圾回收时程序停止的时间比较长 语法 -XX:+UseSerialGC 新生代.老年代使用串行回收 新生代复制算法 老年代标记-压缩 示例图 ...
- 【Arduino】使用C#实现Arduino与电脑进行串行通讯
在给Arduino编程的时候,因为没有调试工具,经常要通过使用串口通讯的方式调用Serial.print和Serial.println输出Arduino运行过程中的相关信息,然后在电脑上用Arduin ...
- 十天学会单片机Day4串行口通信
并行与串行基本通信方式 1.并行通信方式 通常是将数据字节的各位用多条数据线同时进行传送. 并行通信控制简单.传输速度快:由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难. 2.串行通 ...
- IOS多线程知识总结/队列概念/GCD/主队列/并行队列/全局队列/主队列/串行队列/同步任务/异步任务区别(附代码)
进程:正在进行中的程序被称为进程,负责程序运行的内存分配;每一个进程都有自己独立的虚拟内存空间 线程:线程是进程中一个独立的执行路径(控制单元);一个进程中至少包含一条线程,即主线程 队列 dispa ...
- 单片微机原理P4:80C51串口与串行总线拓展
0. 串口通讯 0. 串口通讯的数据传输方式:单工(单向传输数据),半双工(非同时双向传输),全双工(同时,双向传输) 1. 根据通信方式的不同又分为同步通讯和异步通讯. 同步通讯:所有设备都使用同一 ...
- PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化)/约束类型/魔术方法小结
前 言 OOP 学习了好久的PHP,今天来总结一下PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化). 1 PHP中的抽象 ...
随机推荐
- json-lib使用——JSONObject与JSONArray
ps:看这篇博客之前首先要引入工具包json-lib-2.2.2-jdk15.jar 资源链接:百度云:链接:https://pan.baidu.com/s/1o9k7PSu 密码:00lj 一.从O ...
- 怎样写SQL语句可以提高数据库的性能
1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录 ...
- FOR XML PATH做为数据表中单列或者多列的字符串拼接的方法,放到一列中去,很好用。
先看看自己弄得例子,SELECT sName+',',hoppy+',' FROM student2 where hoppy='游泳' FOR XML PATH('')--PATH后面跟的是行标题, ...
- template-web.js 真分页绑定表格
<div class="layui-table-box"> <div class="layui-tabl ...
- SpringMVC中文件上传
在SpringMVC中上传文件是比较方便的.主要分为以下几个步骤: 1)在applicationContext.xml中增加相应类的引用 <bean id="multipartReso ...
- 阿里云Maven仓库
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexu ...
- eclipse配置tomcat Mac平台
1.到 apache官方主页 http://tomcat.apache.org 下载 Mac 版本的完整 tar.gz文件包.解压拷贝到 /Library 目录下,并命名为Tomcat,其他目录也可以 ...
- 封装framework注意点
1.新建一个framework过程: . 2.在工程内新建一些类,注意,使用xib时初始化必须要加上loadnib:,否则会造成xib无效(可能是因为没有加载) 如下: JFViewControlle ...
- SpringBoot(六) Web Applications: Embedded Containers(嵌入式容器)
参考 文档: 28.4 Embedded Servlet Container Support
- 遍历FTP目录及下载
操作ftp,直接在main方法中即可操作. 例1:遍历ftp目录中的文件 public static void main(String[] args) throws IOException { FTP ...