8051单片机

8051单片机原理

简答

1、MCS-51单片机有哪些功能部件组成?并说明它们各自的功能。

1.cpu:控制单片机的操作,执行指令,进行数据处理等。

2.存储器单元:提供程序存储和数据存储的空间。

ROM:存储固定的程序代码

RAM:存储运行时数据和变量。

3.I/O端口

用于连接外部设备,例如传感器、执行器和其他外围设备。

4.定时器/计数器:

用于生成精确的时间延迟、计时和产生脉冲等,可以用于控制系统的定时操作。

5.串行通信控制器(UART)

提供串行通信的能力,可用于与其他设备进行数据传输。

7.中断系统:

允许外部设备通过中断请求中断处理器的正常执行,以执行特殊的任务。

2、简述MCS-51单片机内部RAM功能分区,说明各部分的使用特点。

51单片机RAM分为四个区域

1.工作寄存器区(00H~1FH)

里面就是通用寄存器组R0-R7,每八个分一组。这个区域是最常用的数据区,数据的操作大部分在这里进行。

2.位寻址区(20H~2FH)

这里和通用寄存器组一样可以进行位寻址,也就是说可以比较方便的进行位操作,个人认为它和通用寄存器组的区别是,没有逐个的命名和分组。使用频率较高的数据,或需要位操作的数据会放在这里。

3.用户RAM区(30H~7FH)

很普通的数据缓存区,用来建立堆栈,还有放一些不太常用的数据。

4.特殊功能寄存器(80H~FFH)

特殊功能寄存器组区,支持直接寻址,各种各样的特殊功能寄存器都在这里。

3、什么叫寻址方式?请给出89C51单片机中所有的寻址方式,并为每种寻址方式提供相应的汇编指令例子。

寻址方式(Addressing Mode)是指用于确定操作数或指令地址的方法。

1,立即寻址

MOV A, #5    ; 将立即数5移动到累加器A

2.寄存器寻址

MOV A, R0    ; 将R0寄存器的内容移动到累加器A

3.直接寻址

MOV A, 30H   ; 将RAM地址30H处的数据移动到累加器A

4.寄存器间接寻址

MOV A, @R0   ; 将R0寄存器中存储的地址处的数据移动到累加器A

5.变址寻址

MOV R0, #30 ; 将立即数30赋值给R0寄存器
MOV A, @R0 ; 将R0寄存器中的地址加上A寄存器中的值作为地址,将该地址处的数据移动到A寄存器

4.举出几个串口通信应用的实例,讨论使用串口的基本流程

1,从8051单片机发送温度传感器数据到PC端,实时监控温度。

2.两个8051单片机之间进行数据传输,例如通过串口实现简单的通信协议。

3,使用串口连接8051单片机和GPS模块,获取位置信息并进行处理。

流程

1.串口初始化

在8051中,使用相关寄存器(如SCONTMOD)进行配置

2.发送数据

将要发送的数据加载到发送缓冲区,启动串口发送操作等待发送完成标志,确保数据已经发送完毕。

3.接收数据

收端等待串口接收寄存器中的数据。
4.处理数据:

接收端从接收缓冲区读取数据,并进行相应的处理。

实例:两个单片机相互通信

5.简述你对单片机系统中断的理解,以及中断编程时应该注意的问题。

8051单片机中断,其实就是一种“插队”机制。可以把这个想象成,你正在写代码、做事情,突然有个紧急的事情发生,像是一个按钮按下、定时器到时了,单片机就会暂时搁下手头的事情,跳去处理这个“插队”的事件,等处理完再回来接着做原来的事情。

当然,有几个要点需要记住:

  1. 中断服务程序要快速:中断服务程序得迅速搞定手头的事情,因为主程序也在等着。长时间的中断响应会耽误主程序的执行。

  2. 小心资源冲突:如果中断服务程序和主程序都要使用一些共享的资源,比如全局变量,得小心操作,不然容易出问题。得确保在中断服务程序和主程序之间的交互是安全的。

  3. 中断的优先级:中断有优先级,得了解清楚各个中断的重要性,按照实际需求设置优先级。

计算

1.计算延迟时间

8051机器周期 T = 12 X T A L T={\frac{12}{XTAL}} T=XTAL12

如果 XTAL=11.0592MHz \text{XTAL=11.0592MHz} XTAL=11.0592MHz,8051的机器周期 12 11.0592 M H z = 1.085 u s \frac{12}{11.0592MHz}=1.085us 11.0592MHz12=1.085us

指令所用机器周期
MOV1
DEC1
DJNZ2
LJMP2
SJMP2
NOP1
MUL4
		MOV	R2,#200		;1
AGAIN:	MOV R3,#250		;1
HRER:	NOP			 	 ;1
		NOP				 ;1
		DJNZ R3,HERE	;2
		DJNZ R2,AGAIN	;2

内循环(HERE DELAY): ( 1 + 1 + 2 ) ∗ 250 ∗ 1.085 u s = 1085 u s (1+1+2)*250*1.085us=1085us (1+1+2)2501.085us=1085us

外循环(AGAIN DELAY): 1085*200=217000us=217ms \text{1085*200=217000us=217ms} 1085*200=217000us=217ms

指令延时Y: ( 2 + 1 ) ∗ 200 ∗ 1.085 = 651 u s (2+1)*200*1.085=651us (2+1)2001.085=651us

MOV R3,#250
DJNZ R2,AGAIN

子程序的第一条和最后一条指令被忽略

总共延时: 217000 + 651 = 217651 u s = 217.651 m s 217000+651=217651us=217.651ms 217000+651=217651us=217.651ms

 

2.在定时器中设置延时和频率

8051的机器周期 T = 12 X T A L T={\frac{12}{XTAL}} T=XTAL12

TMODmode(模式)timer(所用定时器)
01H10
02H20
10H11
20H21

延迟时间

初值:TH0|TL0 or TH1|TL0

mode1: ( 65536 − i n i t i a l   v a l u e (初值) ) × 1.085 u s = d e l a y   t i m e (65536-initial \ value(初值))×1.085us=delay \ time (65536initial value(初值))×1.085us=delay time

初值:TH0=TL0 or TH1 = TL0

mode2: ( 256 − i n i t i a l   v a l u e (初值) ) × 1.085 u s = d e l a y   t i m e (256-initial \ value(初值))×1.085us=delay \ time (256initial value(初值))×1.085us=delay time

频率: f = 1 T f=\frac{1}{T} f=T1

 

3.计算波特率

8051机器周期 T = 12 X T A L T={\frac{12}{XTAL}} T=XTAL12

SMOD=0

mode 2:

baud rateTH1(D:10进制)TH1(H:16进制)
9600-3(making (256-TH1 = 3))FD
4800-6FA
2400-12F4
1200-24E8

如果SMOD = 1,baud rate×2(for rate in SMOD = 0)
X T A L 12 × 2 1 − S M O D × 16 × ( 256 − T H 1 ) = b a u d   r a t e \frac{XTAL}{12\times2^{1-SMOD}\times16\times(256-TH1)}=baud \ rate 12×21SMOD×16×(256TH1)XTAL=baud rate

编程

汇编编程

片上片内数据转换

片外RAM2000h单元开始存有1个8字节数。编写汇编程序将这个数转移到片内RAM的30h开始的单元中。

    MOV DPTR, #2000h    ; 设置DPTR到片外RAM的起始地址
    MOV R0, #30h        ; 设置片内RAM的起始地址

    ; 循环8次来复制8个字节
    MOV R7, #08         ; 设置计数器为8
  CO_LOOP:
    MOVX A, @DPTR       ; 从片外RAM读取数据到累加器A
    MOV @R0, A          ; 将累加器A的数据存储到片内RAM
    INC DPTR            ; 增加片外RAM地址
    INC R0              ; 增加片内RAM地址
    DJNZ R7, CO_LOOP  ; 减少计数器并检查是否完成8次循环

ps:汇编延时创建等同样重要,需要对汇编语言的基础语法熟练记忆和运用

c语言编程

定时器相关编程

配置工作模式2,timer0,对一个端口500ms后取反

晶振每次产生十二个周期,会给TH以及TL中进位,当TH,TL为FFFF时,TF溢出由0变1.

通过此过程不断进行反转,即可获得一个占空比为50%的脉冲。

#include <REGX52.H>
void Timer0Init(void);

sbit mybit = P1^5;

void main(void)
{
	while(1)
	{
		mybit = ~mybit;
		Timer0Init();
	}
}

void Timer0Init(void)    // 500毫秒@12.000MHz
{
    TMOD = 0x02;          // 设置定时器模式为工作模式2(8位自动重载定时器)
    TL0 = 0x83;           // 设置定时初始值(低字节),使得定时器每溢出一次大约500毫秒(在12.000MHz的频率下)
    TH0 = 0xFD;           // 设置定时初始值(高字节)
    TR0 = 1;              // 启动定时器0

    while (TF0 == 0);     // 当溢出时将其加入TF可以使TF=1时跳出死循环

    TF0 = 0;              // 清除TF0标志
    TR0 = 0;              // 停止定时器0计时
}

中断相关编程

每秒点亮P1.0口的发光二极管一次,然后熄灭,使发光二极管形成闪烁效果

#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
sbit LED = P1 ^ 0;
uchar count = 0;
void Interrupt() interrupt 1
{
    TH0 = (65536 - 46080) / 256; //触发中断时重新装填计时
    TL0 = (65536 - 46080) % 256;
    if (count == 20)
    {
        LED = ~LED;
        count = 0;
    }
    else ++count;
}
void main(void)
{
    LED = 0xff; //初始化LED
    TMOD = 0x01; //初始化TMOD,定时器0,方式1
    TH0 = (65536 - 46080) / 256; //装填计数
    TL0 = (65536 - 46080) % 256;
    EA = 1; //开放所有中断
    ET0 = 1; //开放定时器0中断控制位
    TR0 = 1; //定时器0开始计时
    while(1)
    {
        _nop_();
    }
}

ps:上面只是简单举例两个8051中应用定时器和中断的例子,在这门课程中,例如:矩阵键盘的扫描,数码管显示,AB的串口通信,按键中断等等同样重要

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y江江江江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值