单片机的程序存储器和数据存储器共处同一地址空间为啥不会发生总线冲突?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机的程序存储器和数据存储器共处同一地址空间为啥不会发生总线冲突?相关的知识,希望对你有一定的参考价值。
表面上看:他们的地址可能是相同的,含义不同。体现在两个空间数据的访问,和程序运行读指令两方面。
【1】两者数据的寻址方式是不同的,这也体现在了对应的指令形式的不同。一个是MOVC,一个是MOVX。这是在把存储区都当数据对待时的情况。当外扩rom时,PSEN给出读有效。
【2】程序运行时,程序通过PC访问。而数据一定通过DPTR访问。 参考技术A 由于PC指针只选择一个区域执行。要么执行ROM要么执行RAM。所以,同一地址对于两者来说,并不会冲突。
单片机期末复习
一、硬件结构
1.1部分引脚说明
RST:复位引脚,两个机器周期的高电平后复位
ALE:锁存低八位地址
EA:高电平时,访问内部程序存储器(ROM)
P0:双向IO口、分时复用-低八位地址,数据总线
P1:双向IO口
P2:双向IO口,访问外部存储器时,提供高八位地址总线
P3:双向IO口,有第二功能
1.2存储器
物理上分为:4 个空间
- 即片内ROM、 、 片外ROM(程序存储器)
- 片内RAM、 、 片外RAM(数据存储器)
逻辑上分为: : 3 个空间 ,
- 程序内存(ROM) ( 片内 、 外 ) 统一编址 MOVC
- 数据存储器 ( 片内) ) MOV
- 数据存储器(片外) MOVX
1.2.1程序存储器(ROM
- 作用:存储用户程序和表格常数
- 特殊单元:
0000H:复位后从这里开始执行程序
中断单元:
- 外中断0 (INT0 ) 0003H
- 定时器0 (T0 ) 000BH
- 外中断1 (INT1 ) 0013H
- 定时器1 (T1 ) 001BH
- 串行口(UART ) 0023H
1.2.2内部数据存储器(RAM
通用工作寄存器组
00~1FH共32个,四组通用寄存器,即(四组R0~R7)
可以使用RS1(PSW.4)RS0(PSW.3)来切换寄存器区
RS1 RS0 寄存器区 内存地址 00 0区 00-07H 01 1区 08-0FH 10 2区 10-17H 11 3区 18-1FH 位地址空间
20-2FH 共128位
外部数据存储器空间
MCS-51 可以外扩64KB RAM 或I/O 口。外部RAM和 和I/O口统一编址
特殊功能寄存器(SFR)
80-FFH 共21个离散分布,11个可以位寻址
介绍
A(ACC),存放操作数、运算结果
B,乘除法使用,也可以用作通用RAM单元
PSW
CY AC F0 RS1 RS0 OV - P D7 D6 D5 D4 D3 D2 D1 D0 - CY,进位标志,可被硬件,软件清零或置位。
- AC,辅助进位标志,低四位有进位或借位时置位。
- F0,用户定义的状态标志,软件清零或置位
- RS1、RS0,寄存器区控制位
- OV,溢出标志,加减指令溢出时置位
- p,奇偶标志,ACC中1的个数为奇数时置位
特殊功能寄存器介绍
- 堆栈指针SP:指示堆栈在内部RAM中的位置,系统复位后SP为07H,堆栈实际从08H开始
- 数据指针-DPTR:存放16位数据地址,访问外部(RAM或P)可分为DPH,DPL单独操作
- 端口P0-P3:IO端口锁存器
- 其他SFR:SBUF、SCON、TH0、TL0、TH1、TL1、IP、IE、TMOD、TCON、PCON
注 : PC 不属于 SFR
1.2.3并行口结构与操作
? 访问外部存储器时,地址由P0 和P2 口送出, 数据 通过P0 口传送,此时P0 口是 分时复用 的双向总线。
不使用外部存储器时,可作为准双向口使用。P2口:
- 不外接数据存储器时,P2 口作为通用I/O 口。
- 外接256B 数据存储器时,使用MOVX @Ri 类指令,由P0 送出低8 位地址,P2 口不受影响。
- 使用MOVX @DPTR 类指令时,需输出16 位地址,存储器访问周期内P2 口保持高8 位地址信息,而锁
存器的内容保持不变,故访问周期结束后锁存器的内容又回到引脚上。可在一定限度内作I/O 使用,如
作为输入口。P3口:
- 作通用I / O 时, “ 选择输出功能 ” 应保持高电平
- 工作于第二功能时,该位锁存器应置1
- 作输入口时,输出锁存器和选择输出功能端都 应置1 。
- 第二功能专用输入,取自输入通道第一 缓冲器G1 )输出端,通用输入信号取自 “ 读引脚 ”
I/O 口 第二功能 说 明 P 3.0 RXD 串行口数据接收端 P 3.1 TXD 串行口数据发送端 P 3.2 INT0 外部中断请求0 P 3.3 INT1 外部中断请求1 P 3.4 T0 定时器/ 计数器0 P 3.5 T1 定时器/ 计数器1 P 3.6 WR 外部RAM 写信号 P 3.7 RD 外部RAM
1.2.4时钟电路与复位电路
? 1个机器周期:12个晶荡(时钟)周期(或6个状态周期)
指令的执行时间称作指令周期
1.2.5复位
复位可使单片机或系统部件处于确定的初始状态。
- PC:0000H
- RAM:随机值(运行中复位不改变RAM内容)
- SFR:
- P0~P3=FFH
- SP=07H
- 其余各位为0
? 复位电路的作用非常重要,能否成功复位关系到单片机系统能否正常运行的问题。如果振荡电路正常而单片机系统不能正常运行,其主要原因是单片机没有完成正常复位,程序计数器的值没有回0 0 ,特殊功能寄存器没有回到初始状态。这时可以适当地 调整上电复位电路的阻容值 ,增加其充电时间常数来 解决问题
二、指令系统
2.1指令格式及常用符号
机器指令 :计算机能直接识别和执行的指令
单字节指令:一般那种没有数字的是单字节指令
如:
? INC A
MOV A,R0
双字节指令:一般带有一个数字的为双字节指令,带有rel的也增加一个字节
如:
? MOV A,#50H
? JC rel
三字节指令:一般带有两个数字的为三字节指令
如:
? MOV 20H,#30H
Rn (n=0~7 )- 当前工作寄存器组中的寄存器R0~R7 之一
Ri (i=0,1 )- 当前工作寄存器组中的寄存器R0 或R1
@ ---------- 间址寄存器前缀
- #data ------8 位立即数/
- #data16-----16 位立即数
- direct------ 片内低128 个RAM 单元地址及SFR 地址
- addr11------11 位目的地址
- addr16------16 位目的地址
- rel---------8 位地址偏移量 , 范围:-128 ~+127
- bit--------- 片内RAM 位地址、 、SFR 的位地址
- ( ×)------ 表示 × 地址单元或寄存器中的内容
/ ----------位操作数的取反操作前缀
2.2寻址方式
? 7种寻址方式
2.2.1寄存器寻址
? MOV A,R0
2.2.2直接寻址
? MOV A,50H
2.2.3寄存器间接寻址
? MOV A,@R0
2.2.4立即寻址
? MOV A,#50H
2.2.5变指寻址
? MOVC A,@A+DPTR
2.2.6相对寻址
? 用于跳转指令,实现程序分支,注意加上指令字节数
如:
? rel=75H,psw.7=1,JC rel存在1000H开始的单元,
执行JC rel后,程序将跳转到1077H单元,(因为要加上JC rel的两个字节)
2.2.7位寻址
? 位寻址方式实质属于 位的直接寻址。
2.3指令
? 注意,使用MOVX A,@Ri读取片外RAM时,高八位地址由P2提供
PUSH,POP
? PUSH 先SP+1 在送值
? POP 先出值,在SP-1
XCH 字节交换
若(R0 )=80H, (A )=20H 。
执行指令 XCH A ,R0 后,
(A )=80H ,(R0 )=20H。XCHD 间址操作数的低半字节与A 的低半字节互换
若(R0 )=30H ,(30H )=67H , (A )=20H 。执行指令
XCHD A ,@R0 指令后,(A )=27H ,(30H )=60H。MUL AB ;A为低八位,B为高八位
DIV AB ;A为整数,B 为余数
ANL
ORL
XRL ;异或
CLR
CPL ;取反
AJMP ;2K PC+2
LJMP ;64K
SJMP;256(-128~+127) PC+2
JMP ;PC+1
JB、JBC、JNB ;PC + 3
JC、JNC ; PC + 2
2.4调用与返回
调用
ACALL addr11:
? PC += 2
? SP += 1
? SP = PC(低八位)
? SP+=1
? SP = PC(高八位)
? PC(低11位)=addr11
LCALL addr16:
? PC += 3
? SP += 1
? SP = PC(低八位)
? SP+=1
? SP = PC(高八位)
? PC = addr16
SP中存的是程序返回地址,PC存的是当前执行指令的值
返回
RET
? PC (高八位)= SP
? SP -= 1
? PC(低八位) = SP
? SP -= 1
RETI
? PC (高八位)= SP
? SP -= 1
? PC(低八位) = SP
? SP -= 1
RET 与 RETI 对堆栈的操作是完全相同的,但是RETI专用于中断的返回,它具有清除内部相应的中断状态触发器的功能。
三、程序设计
? 单片机应用系统由 硬件系统 和 应用程序
? 注意:查表时,如果表是DW存的,那么查询之前,需要左移一下A,若是DB存的,则不需要
JMP @A+DPTR
AJMP XXXX ; 最多128种分支, (256/2
LJMP XXXX; 最多85种分支 (256/3
其余略过,具体看书
四、中断系统
? 外部中断0和1(INT0、INT1)? 采集到低电平或者脉冲下降沿时,产生中断请求。 INT0来自P3.2引脚 INT1来自P3.3引脚
定时/计数器0和1(T0、T1)? 定时功能时,计数脉冲来自片内? 计数功能时,计数脉冲来自片外。T0来自P3.4引脚 T1来自P3.5引脚? 计数值由8个1变成8个0时,产生中断请求。
串行中断? 发送或接收完一个字节数据时,产生中断请求发送来自P3.0引脚接收来自P3.1引脚
中断相关特殊寄存器
中断允许寄存器IE
中断优先级寄存器IP
定时/ 计数器及外部中断控制寄存器TCON
串口控制寄存器SCONTCON
SCON
IE
IP
五、定时器、计数器
TMOD
TCON
5.1工作方式
T0:0、1、2、3
T1:0、1、2
方式0:
13位,初值计算:
- 计数模式(C/T=1):
8192-N
定时模式:
8192-N,
? N=t/Tcy,(即,要求的时间/单片机的机器周期)
? eg: 定时1ms,单片机晶振频率12M,则机器周期为1μs,那么N=1ms/1μs=1000
? 初值就是 7192,然后转换为十六进制送入TH0(高八位),TL0(低五位)即可
但是由于,13位,送的时候,不太方便,所以一般不用方式0
方式1:
16位,初值计算
65536-N
送初值的时候,需要将初值高八位送入TH0,低八位送入TL0
eg:N=500,则可以这样送
MOV TH0,#(65536-500) / 256 MOV TL0,#(65536-500) MOD 256
?
方式2:
8位,自动重装载
256-N
送初值的时候,只要将初值送给TH0,和TL0即可
方式3:
8位,(仅T0有此方式,T1 方式3将停止计数)
TL0进行8位定时/计数
TH0进行8位定时(T1方式2时,可出借TR1 、TF1)
? 模式3 对T T0 和T1是不同的。
对于T1,设置为模式3将使它保持原有的计数值 其作用
如同使 如同使 TR1 = 0,即停止计数。
对于T0,将使 TL0 和 TH0 成为两个独立的 8位计数器 。 TH0
只能作定时器 , 对机器周期计数 ,借用T1 的 TR1 和 TF1 , 并占用
T1的中断源 ,此时T1 仍可工作在模式0 、1 或 2, 用于不需要中
断控制的场合 , 如用于作波特率发生器 (工作于模式2)。
5.2注意的问题
5.2.1对输入信号的要求
定时器方式:
输入来自内部时钟脉冲(fosc/12),定时精度取决于振荡器频率
计数器方式
外部输入脉冲的最高频率为震荡器频率的1/24。即 晶振频率/24
5.2.2赋初值
除了模式二的自动重装载外,其余的模式,在中断程序内需要重新赋初值
5.2.3运行中读定时器/计数器
由于 不可能在同一时刻读取THx 和TLx 的内容,读取的计数值有可能出错。例如:先读TLx ,后读THx ,由于定时器在不断运行,读THx 前若恰好产生 生TLx 溢出向THx 进位的情况,则读得的TLx 是错误的。同样,若先读
THx ,后读TLx也会出错。
解决方式:
? 先读THx, , 后读TLx, , 再读THx, 若两次读得的THx 相同 , 则可确定读得的内容是正确的 。 若前后读得的THx 有变化 , 则重复上述过程 , 这次重复读得的内容应是正确的。
RDTIME : MOV A ,TH0 MOV R0 ,TL0 CJNE A ,TH0 ,RDTIME MOV R1 ,A RET
5.3初始化
- 对TMOD赋值,确定T0、T1工作方式
- 求初值,并写入TH0、TL0或者TH1、TL1
- 中断方式时,对IE进行赋值,开开中断
- 查询方式时,检测TF0或TF1,为1代表计时时间到,将其清0,使TR0或TR1置位,启动定时、计数工作。
eg:
? 用T0 扩展一个外部中断源。将T0 设置为计数器方式,按方式2工 工
作,TH0 、TL0 的初值均为0FFH ,T0 允许中断,CPU 开放中断。其初
始化程序如下:MOV TMOD,#06H ; 置T0 为计数器方式2 MOV TL0,#0FFH ; 置计数初值 MOV TH0,#0FFH SETB TR0 ; 启动T0 工作 SETB EA ;CPU 开中断 SETB ET0 ; 允许T0 中断
5.4例
定时时间较大时(大于65ms)
实现方法:一是采用1 个定时器定时一定的间隔(如20ms ),然后用软件进行计数;二是采用2 个定时器级联,其中一个定时器用来产生周期信号(如20ms 为周期),然后将该信号送入另一个计数器的外部脉冲输入端进行脉冲计数。
编写程序,实现用定时/ 计数器T0 定时,使P1.7 引脚输出周期为2s 的方波。设系统的晶振频率为12MHz 。
$color{red}{采用 定时50ms ,然后再 计数20}$
ORG 0000H LJMP MAIN ORG 000BH LJMP DVT0 ORG 0030H MAIN: MOV TMOD,#01H; 置T0 方式1 MOV TH0,#3CH ; 装入计数初值 MOV TL0,#0B0H ; 首次计数值 MOV R7,#20 ; 计数50 次 SETB ET0 ;T0 开中断 SETB EA ;CPU 开中断 SETB TR0 ; 启动T0 SJMP $ ; DVT0: DJNZ R7,NT0 MOV R7,#20 CPL P1.7 NT0: MOV TH0,#3CH MOV TL0,#0B0H RETI END
六、串行口
SCON
PCON
6.1工作方式
SM0、SM1选择四种工作方式
方式0,同步移位寄存器方式
用于扩展并行I/O
- 一帧8 位,无起始位和停止位。
- RXD :数据输入/ 输出端。
TXD :同步脉冲输出端,每个脉冲对应一个数据位。 - 波特率B = fosc/12
如: fosc=12MHz , B=1MHz ,每位数据占1μs 。 - 发送过程: 写入SBUF ,启动发送,一帧发送结束,TI=1 。
接收过程:REN=1 且RI=0 ,启动接收,一帧接收完毕, RI=1 。
eg:
数据从RXD(P3.0)引脚串行输出,低位在先,高位
在后;TXD(P3.1)引脚输出移位脉冲,其频率为foc/12;
发送完毕后,中断标志位TI为1。MOV SCON,#00H ;串行口方式0 MOV SBUF,A ;将数据送出 JNB TI,$ ;等待数据发送完毕
方式1:八位数据异步通讯方式
一帧10 位:8 位数据位,1 个起始位(0) ,1 个停止位(1)
RXD :接收数据端。 TXD :发送数据端。
波特率:用T1 作为波特率发生器,B=(2 SMOD /32) ×T1 溢出率。
发送:写入SBUF ,同时启动发送,一帧发送结束,TI=1 。
接收:REN=1 ,允许接收。接收完一帧,若RI=0 且停止位为1( 或SM2=0) ,将接收数据装入SBUF ,停止位装入RB8 ,并使
RI=1 ;否则丢弃接收数据,不置位RI 。当REN=1 ,CPU 开始采样RXD 引脚负跳变信号,若出
现负跳变,才进入数据接收状态,先检测起始位,若第一
位为0 ,继续接收其余位;否则,停止接收,重新采样负跳
变。数据采样速率为波特率16 倍频,在数据位中间,用第7 、
8 、9 个脉冲采样3 次数据位,并3 中取2 保留采样值。
方式2、方式3:9位数据异步通讯方式
- 一帧为11 位:9 位数据位,1 个起始位(0) ,1 个停止位(1)。 。
第 第9 位数据位在TB8/RB8 中,常用作校验位和多机通讯标识
位。 - RXD :接收数据端,TXD :发送数据端
- 波特率: 方式2 :B=(2 SMOD /64) ×fosc 。
方式3 :B=(2 SMOD /32) ×T1 溢出率 - ) 发送: 先装入TB8 ,写入SBUF 并启动发送,发送结
束,TI=1 。
接收:REN=1 ,允许接收。接收完一帧,若RI=0 且第
9 位为1 ( 或SM2=0) ,将接收数据装入接收SBUF ,第9 位装
入RB8 ,使RI=1 ;否则丢弃接收数据,不置位RI
- 一帧为11 位:9 位数据位,1 个起始位(0) ,1 个停止位(1)。 。
6.2波特率确定与初始化步骤
波特率确定
固定波特率:
方式0波特率= fosc/12
方式2波特率 = ($2^{SMOD}$/64)*fosc
可变波特率:
方式1波特率 = ($2^{smod}$/32)*T1溢出率
方式3波特率 = ($2^{smod}$/32)*T1溢出率
? (定时器1)T1溢出率
- fosc/(12*($2^n$-定时器初值))
- n为定时器的模式位数,模式0-->13, 模式1----->16, 模式2----->8
经推导定时器初值可近似为
$2^n-(2^{smod}1.085x)/(波特率/2400)$
其中,smod与pcon最高位相同,x为晶振频率/M,计算结果,四舍五入即可。
初始化步骤
- 确定T1工作方式(找到n)(MOV TMOD,#20H)
- 设置PCON
- 计算初值(上面的公式)
- 启动T1(SETB TR1)
- (开开单片机中断(SETB EA))
- (开开串行口中断(SETB ES))
发送程序
查询方式
SEND: MOV A,@R0 ; 取数据 MOV SBUF,A ;发数据 JNB TI,$ ; 等待发送结束 CLR TI ;清除标志位 INC R0 ;准备下一次发送 SJMP SEND
中断方式
ORG 0 LJMP MAIN ORG 0023H LJMP DVSEND ORG 0100H MAIN: ...... MOV A,@R0 ; 取数据 MOV SBUF,A ;发数据 DVSEND: CLR TI INC R0 MOV A,@R0 MOV SBUF,A RETI
接收程序
REN=1、RI=0等待接收,当RI=1,从SBUF读取数据
查询方式
WAIT: JBC RI,NEXT SJMP WAIT NEXT: MOV A,SBUF MOV @R0,A INC R0 SJMP WAIT
中断方式
ORG 0023H LJMP DVGET MAIN: ...... SJMP $ DVGET: CLR RI MOV A,SBUF MOV @R0,A INC R0 RETI
?
以上是关于单片机的程序存储器和数据存储器共处同一地址空间为啥不会发生总线冲突?的主要内容,如果未能解决你的问题,请参考以下文章
为啥MCS-51单片机的程序存储器和数据存储器共处同一地址空间而不会发生总线冲突