本系列文章是为教你8051单片机编程而开发的。我将本编程教程分成如下所示的一系列章节。你可以从第一章开始,然后读第二章,第三章等等。所以让我们现在就开始这段旅程吧!

注意:下一章1、2、3……都在开发阶段。请再次访问此页面以获取更新。

注意:要测试这些程序或自己写一个测试,你现在不需要买一个微控制器板。您可以使用8051模拟器测试您的程序。这里有一个大的列表8051模拟器可用。首先尝试列表中给出的第一个函数Edsim51。它是一个易于使用的工具。

要给世界上任何可用的微控制器编程,首先你需要学习和理解它的指令集。指令集包含一组可供程序员创建任何他喜欢的程序的指令。或者用另一种方式,程序员可以使用指令集为他正在编写的特定应用程序创建所需的程序。因此,首先,一个人需要掌握所有可用的指令,指令如何工作,指令的执行如何影响微控制器(影响寄存器,psw,堆栈等),以及它在程序中的使用方式。一旦掌握了指令集,就可以开始使用程序了。在开始编程之前,有一些先决条件。如果你真的是微控制器的新手,如果8051是你玩的第一个,请先阅读以下文章。

1.微处理器和微控制器的区别

2.8051微控制器基础-引脚图-体系结构-存储器组织

3.8051的寻址模式- - - - - -在为8051编写任何程序之前,您必须阅读本文,因为它记录了指令处理的根源。

4.8051特殊功能寄存器和I/O端口

现在让我们来看看8051微控制器的指令集。8051指令集可以分类如下所示。

  • 数据传输/数据移动指令
  • 算术运算说明
  • 对程序进行分支的说明
  • 创建子程序的指令
  • 逻辑操作说明
  • 布尔运算说明
  • 特殊目的的说明

按照所给的链接,在那里你可以访问8051微控制器的完整指令列表8051指令集(见首表字母顺序下的标题)。

注意:-8051微控制器属于MCS-51微控制器家族。这基本上意味着,任何其他制造商生产的8051变体微控制器(属于MCS-51家族)都必须使用为MCS-51制作的同一套指令。因此,“指令译码器“MCS-51系列所有微控制器的部分是相同的。例子:Atmels AT89c2051就是属于MCS-51家族的一种微控制器。因此,为Intel 8051编写的程序也可以用来运行AT89C2051(您可能需要做一些轻微的修改以匹配硬件差异)。

1.数据传输指令包括- mov, movc, movx, push, pop, xch, XCHD

2.在structions for arithmetic operations are- add, addc, subb, mul, div, inc, dec, da a

3.分支和子程序的说明- ljmp、ajmp、sjmp、lcall、acall、jz、jnz、cjne、djnz、jmp、nop、ret、reti

4.逻辑操作说明- anl, orl, xrl, clr, cpl, rl, rlc, rr, rrc, swap

5.布尔变量操作的说明- setb、mov、clr、jb、jnb、jbc、anl、orl、cpl、jc、JNC

6.特殊用途说明包括- movc, movx, swap, xch, xchd, jbc, reti, da a

你可以通过上面给出的链接了解所有的详细说明。在8051或MCS-51指令集中有44条指令。

我假设您现在已经完成了数据传输/算术/分支和子程序指令。现在让我们写一个非常简单的程序。

求N个自然数和并存储其和的程序

项目描述:-数字“N”存储在位置35H中。从0到N生成的自然数必须从位置55H存储。自然数的和必须存储在36H位置。

分析程序描述,我们需要3个寄存器。R0用于存储“N”的值(在位置35H中给定),并作为生成N以内的自然数的计数器。R5用于保存第一个自然数存储位置的值,然后R5分别加1以存储每个新生成的自然数。R7初始值为0,然后加1以生成自然数。

程序:

MOV PSW, #00H //通过执行此指令选择寄存器bank '0'。

MOV R0, 35H //存储在位置35H中的'N'值被转移到R0。

MOV R5, #55H//存储自然数'#55H'的起始位置转移到R5

累加器初始值为0,用于累加自然数。

MOV R7, #00H// R7初始化为'0'以生成自然数。注意:'0'不是一个自然数。

循环:INC R7// R7加1以生成下一个自然数。

MOV @R5, 07H//这里使用的是间接寻址模式。不可能将数据从一个寄存器直接传输到另一个寄存器。所以像MOV R5, R7这样的指令是无效的。在stead we use the direct address (07) of register R7 of register bank #00 to transfer the generated natural number to it's storage location in register R5.Indirect addressing is used as we need to save the generated natural number directly to memory address. R5 holds the starting location address (of the storage area) as its value i.e #55H.通过间接寻址,我们可以将R7中的任何值直接保存到位置#55H。

INC R5//存储位置从#55H到#56H加1以存储下一个生成的自然数

ADD A, R7//将生成的自然数加到累加器内容中。

DJNZ R0, LOOP//寄存器Ro的值('N'的值)减1。根据停止条件零进行检查。如果它的R0不等于零,程序控制将再次移动到标记LOOP,从INC R7开始的步骤将再次执行,直到R0等于零。当R0等于0时,程序控制将退出循环并移动到下面给出的下一条指令。

MOV 36H,A//累加器中的自然数和移动到存储位置36H。

STOP: SJMP STOP//在程序结束时写入的一个无限循环。当到达此指令时,程序控制将卡在此指令上,因为它是一个无限循环。为了摆脱这个无限循环,必须应用系统重置。

一个将数据块从一个位置复制到另一个位置的简单程序

项目描述:-从30H开始存储的10字节数据将从50H开始复制到另一个位置。

分析这个程序,我们看到,我们需要两个寄存器来存储源和目标的起始位置。我们设R0为源寄存器,R2为目标寄存器。现在我们需要一个计数器来计算从源到目的地传输的10个字节的数据。取R3为例。不可能通过使用任何类型的寻址模式直接将数据从一个寄存器传输到另一个寄存器。所以我们需要一个累加器作为中间的临时寄存器。这就是它:

程序:

MOV R0,#30H //源数据起始位置地址移动到R0。

MOV R1,#50H //目标起始位置地址移动到R1

MOV R3,#OAH//将计数器R3设置为10。您也可以使用小数MOV R3,#10d。

LOOP: MOV A, @R0//使用间接寻址模式。Ro (30H)位置的内容被复制到累加器。

MOV @R1, A//累加器中的内容被复制到Ra指定的位置(即50H)。

INC R0 // Ro加1指向下一个位置。

INC R1// R1加1指向下一个位置。

DJNZ R3, LOOP //计数器寄存器R3减1并检查为零。参见第一个程序“自然数的和”中的DJNZ说明

STOP: SJMP STOP //无限循环终止程序

生成斐波那契数列

注意:-请点击此链接,如果您有兴趣了解斐波那契数列的起源和背后的故事

项目描述:-我们都知道,斐波那契数列是数学上的无限数列它的表达式是0 1 1 2 3 5 8 13 21....

这里我们要写一个程序生成N项的斐波那契数列。N的值在位置30H中可用,我们将从位置40H保存序列。

注意:如果你是第一次听说斐波那契数列这个术语,这里有一个很好的阅读-斐波纳契数列的一代

程序:

开始:MOV R1,30H //得到“N”的值

MOV R7,#40H //系列的第一个数字'0'存储在这里。

MOV @R7,#00H //加载值'o'到地址40H使用间接寻址

INC R7 //将R7的值从40H增加到41H以存储下一个数字'1'

MOV @R7, #01H //存储值“1”到位置41H。注意,'o'和'1'是斐波那契数列的种子值,必须手动生成。

MOV R5,#42H //新寄存器R5加载位置地址42H以存储系列的下一个值,该值是通过将前面生成的两个数字相加而生成的。

12月R1

DEC R1 //计数值“N”减2,因为我们已经生成并存储了前两个数字。

DEC R7 // R7现在从41H降低到40H。我们需要添加40H和41h的内容,得到要存储在42H的数字。

循环:MOV A, @R7 //将R7中的内容移动到累加器。

INC R7 // R7递增以获得下一个值。

ADD A,@R7 //添加两个值并存储在Acc中。

MOV @R5,A //该系列新生成的值存储在R5持有的地址中。

INC R5 // R5递增以存储下一个值。

DJNZ R1,LOOP //将计数“N”检查为零(以知道是否生成了所有到N的数字)。

STOP: SJMP STOP //在此无限运行或程序执行结束。

这3个程序将足够a“启动”8051年编程。更多的程序和概念将在接下来的文章中解释。我建议你下载Edsim51模拟器(或其他你喜欢的程序)并尝试这些程序。对这些代码进行修改,并根据自己的想法编写简单的代码——比如两个数字相乘,生成一个特定的序列,算术计算器等。只有亲自动手,你才能掌握编程的艺术!

学习快乐!

作者

18评论

  1. 加里

    我注意到在你的Fibonacci循环中你增加了R7;这将增加一个未知的值,因为R7已经在较高的地址(41H),它被编程从那里获取值。

    循环:MOV A, @R7 //将R7中的内容移动到累加器。(当返回到这个标签时,它在地址41H)

    INC R7 // R7递增以获得下一个值。

    ADD A,@R7 //添加两个值并存储在Acc中。(现在它在42H,这个地址的未知值,会给我们一个错误的和,加上在每次迭代中我们只添加一个数字到伏隔器,并存储该数字,然后再迭代)

    MOV @R5,A //该系列新生成的值存储在R5持有的地址中。

  2. Swetha

    谁能用简单的语言给我解释一下微处理器程序。我什么都不懂,所以请用最基本的语言给我解释一下,这样我就容易理解了。

  3. GOVADA LAKSHMAN钱德拉

    请我想为收费广场系统使用低频射频识别或基于射频识别的相关程序,如果发现

  4. vaibhav bagal

    为什么程序不被NOP指令终止,为什么被8051的循环终止

  5. vaibhav

    惠……
    乔乔,你能回答我之前的问题吗?

    请求……尽快给我答复。

    请求……回复一些我等不及的东西。

  6. vaibhav

    你好先生,
    在8051的指令集中也有NOP指令
    那么为什么不使用NOP指令来终止程序呢?
    为什么只使用无限循环来终止程序?
    PLZZZZ详细回答我。

    • 穆罕默德Asgar

      在你的程序中,当控制器发现NOP指令时,它不执行任何操作,只是增加堆栈指针,并前往下一个位置。

      但当它在程序中发现结束指令时,它停止控制器以增加sp地址。
      这就是为什么我们使用end指令来终止程序。

  7. vaibhav

    你好,先生,这篇文章真的很棒。但是我在整篇文章中没有得到一件事,那就是为什么程序被无限循环终止,为什么不被HLT指令终止????plzzzzz回复

    • 乔乔

      你好Vaibhav,

      8051单片机中没有HLT指令。HLT仅适用于8085微处理器及其变体的指令集。

      • vaibhav

        哦……好的谢谢…

  8. Dainius Stankevicius

    你好,
    首先,感谢您提供这些关于8051的优秀文章和教程。这对我帮助很大!
    然而,我注意到在第一个程序“寻找N个自然数的和”中有一个简单的错误(至少我是这样认为的)。
    这里是:
    MOV @R5, 07年h
    EdSim说:
    未知标签- @R5
    在另一篇文章“8051微控制器的寻址模式”中,你说“只允许R0和R1组成寄存器间接寻址指令”。
    那么,为什么要使用R5来存储自然数的位置呢?
    我用的是R1,一切都很完美。

    • Dainius Stankevicius

      我还注意到你在第三个程序“生成斐波那契数列”中使用了间接寄存器寻址:
      MOV @R7 # 00 h
      MOV @R5,
      所以问题还是一样的。这是一个简单的错误,还是有什么我显然不明白的地方?
      你为什么要用这些精确的寄存器?
      提前谢谢!

      • 乔乔

        你好Dainius,

        这是我的错误。谢谢你的通知。在间接寻址模式下,只能使用R0和R1。要使用更多的寄存器,可以切换银行。在写这篇文章的时候,我没有检查过那些程序。我将纠正他们之后,给它在模拟器测试。

        谢谢,
        乔乔

  9. habeeb

    你好,先生,我有一个thinnkware 8051 usbasp和thinnkware 8051编程工具包..问题是我没有。我不知道如何连接它和套件..套件上没有特殊的别针,除了端口别针..请帮助我.......

    网站:thinnkware.com

    • 乔乔

      你好,Habeeb,尝试从thinnkware.com获得编程工具包的数据表。

  10. Anurag马利克

    这是我找到的8051最好的教程。你已经很好地解释了基础知识。谢谢

Baidu