IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于STC98C52RD+的51MCU学习流水账--->串口通讯学习(汇编版) -> 正文阅读

[嵌入式]基于STC98C52RD+的51MCU学习流水账--->串口通讯学习(汇编版)

?开篇语:

1-收集-->整理-->消化-->分享,收集多年,开始迈出分享这步。

2-从点灯-->到数码管-->撸到串口,目前卡在串口。无法实现基本串口通讯。

为了便于后期解决问题后,能回头复盘过程,特此开始记录后期一切解决过程

(自用的同时各位过客如可参考一二,甚是开心。如有不当之处亦可提出指正,不胜感激!)

先上图

问题:PC发送45H,串口助手接收到的确是 BAH(图中2个BA,是因为我按了两次“发送数据”)

首先:对源代码进行注释(汇编)

        ;初始化
        ORG   0000H      ;上电&复位入口地址0000H             
        LJMP  MAIN       ;从0000H跳到标号MAIN处,进行主程序任务    
        ORG   0023H      ;串行口中断入口地址      
        LJMP  UART_INT   ;从0023H跳到标号UART_INT处,进行串行口中断任务
        ORG   0100H      ;下列程序从入口地址0100H开始 
        
        ;主程序
MAIN:   
        MOV  SP,#70H     ;堆栈指针SP指向的栈底地址        
        MOV  IE,#90H     ;#90H=#10010000B,EA=1(开总中断),ES=1(开串口中断),        
        MOV  TMOD,#20H   ;#20H=#00100000B,高四位,GATE=0(软件控制TR1启动定时或计数),
                         ;C/T=0(定时方式), M1M0=10(模式2),           
        MOV  TH1,#0FDH   ;载入TH初值(怎么算)           
	    MOV  TL1,#0FDH   ;载入TL初值(怎么算)         
        MOV  PCON,#00H   ;#00H=#00000000B,SMOD=0(不增倍)          
	    MOV  SCON,#50H   ;#50H=#01010000B,SM0SM1=01(方式1,10位UART,8位数据,波特率可变),
                         ;REN=1(允许接受)         
	    SETB TR1         ;TR1=1,开定时器
	    SETB ES          ;ES=1,开串口中断
	    SETB EA          ;EA=1,开总中断
	    SJMP $           ;动态待机(循环跳转此行)

        ;串口中断程序
UART_INT: 
         JNB   RI,SENT   ;RI=0?是(没接收完一帧数据),跳到标号SENT处,
                         ;RI=0? 不是(即RI=1,接受完一帧数据),往下执行
                         ;通知CPU从SBUF取走接收到的数据

         MOV   A,SBUF    ;SBUF接收到数据,先放入A
		 XRL   A,#0FFH   ;与FFH异或后的值,存A(不明白为啥这么做)
		 MOV   SBUF,A    ;A的值,再送到SBUF等待输出
		 CLR   RI        ;RI清0(简单理解:RI接受中断使能)
    SENT:       
         CLR   TI        ;TI清0 (简单理解:TI发送中断使能)  
         RETI            ;返回主程序

         END             ;程序到此结束

然后,分段分析
? ? ? ? 第一段: 初始化,没啥纰漏。

? ? ? ?ORG ? 0000H ? ? ?????????????????;上电&复位入口地址0000H ? ? ? ? ? ??
? ? ? ? LJMP ?MAIN ? ? ? ????????????????;从0000H跳到标号MAIN处,进行主程序任务 ? ?
? ? ? ? ORG ? 0023H ? ? ?????????????????;串行口中断入口地址 ? ? ?
? ? ? ? LJMP ?UART_INT ? ????????????;从0023H跳到标号UART_INT处,进行串行口中断任务
? ? ? ? ORG ? 0100H? ? ??????????????????;下列程序从入口地址0100H开始?

?第二段:设置各个寄存器,看完也没啥纰漏。

MAIN: ??
? ? ? ? MOV ?SP,#70H? ? ? ?

;设置堆栈指针SP指向的栈底地址;【串口通信也是中断的一种,中断必须保护现场】

因为8051单片机在复位后,堆栈的底部就在07H,使得堆栈实际上是从08H开始的。但我们从RAM的结构分布中可知,08H—1FH隶属1—3工作寄存器区,若编程时需要用到这些数据单元,必须对堆栈指针SP进行初始化,原则上设在任何一个区域均可,但一般设在30H—7FH之间较为适宜。如图

?那现在设在70H ,则实际可用堆栈会再70H-7FH范围,用来暂存数据,保护现场。

(任何程序在运行过程中都需要使用堆栈,堆栈就是维护当前线程中运行状态的一个数据结构,这种状态包括:需要传递的变量,函数的返回地址,局部变量等等)

????????MOV ?IE,#90H ? ?
????????
;#90H =? #10010000B
????????EA=1(总中断允许),ES=1(串口中断允许)?
? ? ??
? ? ? ? ?MOV ?TMOD,#20H ? ?
????????;#20H=#00100000B
????????;使用高四位,即定时器1,GATE=0(软件控制TR1启动定时或计数),
? ? ? ? ;C/T=0(定时方式), M1M0=10(模式2)

????????;如下图,模式2:是 8位自动重置定时器/计数器? ? ? ?

????????MOV ?TH1,#0FDH ? ;载入TH初值?? ? ? ? ??
?? ? ? ?MOV ?TL1,#0FDH ? ;载入TL初值? ??

【 怎么计算?】
?定时时间 =(2的8次-初值)X 12/晶振频率

??
? ? ? ? MOV ?PCON,#00H ?
????????;#00H=#00000000B,SM0D=0,不增倍。
? ? ? ? ;8051的PCON只看SMOD是1,还是0;SMOD=0(不增倍) ;SMOD=1(增倍) ;? ?

? ? ?
?? ? ? ?MOV ?SCON,#50H ?
????????;#50H=#01010000B
? ? ? ? ;SM0SM1=01(方式1,10位UART,8位数据,波特率可变)
????????有些资料写着8位UART,有些资料写着10位UART,8位数据

? ? ?方式一波特率=(2^SMOD/32)*(T1溢出率)
其中
1-当SMOD=0,波特率正常;当SMOD=1,波特率加倍。

2-T1溢出率就是 T1定时器溢出的频率。
(只要算出T1定时器每溢出一次所需的时间T,就可以算出溢出率1/T.单位为Hz)

????????T1定时器使用工作方式2(TMOD=0X20),即8位初值自动重装的定时器。

其工作过程是,在TLX和THX中装好相同的初值,在时钟的作用下TLX加一计数,当TLX加满溢出后,CPU会自动将THX的值装入TLX中......如此循环。

每计一个数的时间为一个机器周期,一个机器周期为12个时钟周期。
如采用11.0592MHz的晶振,机器周期为? 12*( 1/11.0592MHz )(s)
那么定时器溢出一次的时间为(256-X)*12/11.0592MHz(s),其中X为装入的初值。

取倒数即为 T1的溢出率。

如要设为波特率为9600,此处SMOD取0,则9600=( 1/32 )*11059200/ [ ( 256-X )*12 ]
解得X=253,即十六进制的0xFD.

????????;REN=1(允许接受) ?
? ? ? ? ;REN为允许接收位。相当于串行接受的开关,由软件置位或清零;
? ? ? ? ;在串行通信过程中,如果满足REN=1,且RI=1,则启动一次接受过程,一帧数据就装入接收缓冲器SBUF中。? ? ? ??

接下来:开启各个寄存器
?? ? ? ?SETB TR1 ? ? ? ????????? ;TR1=1,开定时器
?? ? ? ?SETB ES? ? ? ? ? ? ? ? ? ?;ES=1,开串口中断
?? ? ? ?SETB EA? ? ? ? ? ? ? ? ? ?;EA=1,开总中断
?? ? ? ?SJMP $? ? ? ? ? ? ? ? ? ? ? ;动态待机(循环跳转此行)??

?第三段:串口中断,数据传输。

?UART_INT:?
? ? ? ? ?JNB ? RI,SENT? ?

? ? ? ? ;JNB,直接寻址,为0转移??
????????;RI=0?是(没接收完一帧数据),跳到标号SENT处,
? ? ? ? ;RI=0? 不是(即RI=1,接受完一帧数据),往下执行
? ? ? ? ;由前面SCON,#50H ?可知,SM0SM1=01,为方式二
? ? ? ??
;当RI接收到停止位时,RI由硬件置1,表示接收结束。【可供软件查询或请求中断】
? ? ? ? ;往下执行是:通知CPU从SBUF取走接收到的数据

? ? ? ? ?MOV ? A,SBUF ? ?
????????;SBUF接收到数据,先放到A


?? ??? ? XRL ? A,#0FFH ?
? ? ? ? ;A里的数据与0FFH,进行异或后再存入A.? ?
? ? ? ? ;XRL:逻辑异或指令,即相对应的二进制位不同该位异或后的结果是1,相同则为0
? ? ? ? ;如:
发送01000101B(45H), XRL 11111111B(FFH)=1011 1010B ( BAH )


?? ??? ? MOV ? SBUF,A ?
?????????;A的值,再送到SBUF等待输出
? ? ? ? ;接上,这个时候,在异或后,A里的值是BAH,送到SBUF


?? ??? ? CLR ? RI ? ? ? ?
????????;RI清0(简单理解:RI接受中断使能)
? ? ? ? ;中断后,RI清0,表示准备下一次接收数据


? ? SENT: ? ? ??
? ? ? ? ?CLR ? TI ? ? ?
?????????;TI清0 (简单理解:TI发送中断使能)
? ? ? ? ?;TI是发送中断标志,TI=1,表示发送完成,TI=0,表示准备下一次发送数据
? ? ? ? ?;根据前面,JNB ? RI,K1 ,RI≠0,即接收没结束,转到这里,使TI=0,继续发送、
?????????RETI ? ? ? ? ? ?;返回主程序

? ? ? ? ?END ? ? ? ? ? ? ;程序到此结束

捋完之后,发现:XRL A,#0FFH; 这句话 使得A里的数据,从45H,变成了BAH
所以,把这句话屏蔽后,在通过串口助手测试,发现,接收正常


?以上,第一段串口程序,测试完毕。

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 23:14:49  更:2022-01-29 23:15:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:50:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码