Microcontroller Knowledge (III)

Publisher:Howard_SunLatest update time:2016-03-18 Source: eefocusKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Through the previous study, we have understood the internal structure of the microcontroller, and we also know that to control the microcontroller and let it do things for us, we need to use instructions. We have learned a few instructions, but they are very scattered. From now on, we will systematically study the instruction part of 8051.

I. Overview

1. Instruction format

We know that to make a computer do something, we have to give it instructions, and we also know that computers are very "stupid" and can only understand numbers, such as 75H, 90H, 00H, etc. that we wrote into the machine before, so the first format of instructions is the machine code format, also known as the digital format. But this format is really difficult for us humans, it is too difficult to remember, so there is another format, the mnemonic format, such as MOV P1, #0FFH, which is easier to remember. The relationship between these two formats is not difficult for us to understand. In essence, they are completely equivalent, just in different forms.

2. Assembly

We write instructions in assembly format, but computers only understand machine code format, so we need to convert the instructions in assembly format into machine code format. There are two ways to do this conversion: manual assembly and machine assembly. Manual assembly is actually a table lookup, because the two formats are purely different, so there is a one-to-one correspondence, and you only need to look up a table. However, manual table lookup is always troublesome, so there is computer software, which replaces manual table lookup with computer software, and this is machine assembly.

2. Addressing

Let's review some of the instructions we have learned: MOV P1, #0FFH, MOV R7, #0FFH. These instructions are to send some data to the corresponding location. Why do we need to send data? The first reason is that the number sent in can make all the lights go out, and the second reason is to achieve delay. From here we can see that when programming with the programming language of the microcontroller, data transfer is often used. In fact, data transfer is an important task when programming a microcontroller. There are 28 instructions in total (the microcontroller has a total of 111 instructions). Let's start with the data transfer instructions.

Analyzing the instruction MOV P1, #0FFH, we can easily come to the conclusion that the first word MOV is a command verb, which is to decide what to do. MOV is MOVE with one less E, so it means "transfer", which is the instruction that specifies what to do. There are some parameters behind it. Analyzing it, data transfer must have a "source", which is the number you want to send, and a "destination", which is where you want to send the number. Obviously, in the above instruction, the number to be sent (source) is 0FFH, and the place to be sent (destination) is the P1 register. In data transfer instructions, the destination is written after the instruction, and the source is written at the end.

In this instruction, the number itself is sent to P1. In other words, after completing this instruction, we can clearly know that the value in P1 is 0FFH, but the number itself cannot be given directly at any time. For example, the delay program example given above is written like this:

MAIN: SETB P1.0; (1)

LCALL DELAY; (2)

CLR P1.0; (3)

LCALL DELAY; (4)

AJMP MAIN; (5)

; The following subroutine

DELAY: MOV R7, #250; (6)

D1: MOV R6, #250; (7)

D2: DJNZ R6, D2; (8)

DJNZ R7, D1; (9)

RET; (10)

END; (11)

 

 

Table 1

MAIN: SETB P1.0; (1)

MOV 30H, #255

LCALL DELAY;

CLR P1.0; (3)

MOV 30H,#200

LCALL DELAY; (4)

AJMP MAIN; (5)

; The following subroutine

DELAY: MOV R7, 30H; (6)

D1: MOV R6, #250; (7)

D2: DJNZ R6, D2; (8)

DJNZ R7, D1; (9)

RET; (10)

END; (11)

In this way, the delay time is the same every time I call the delay program (roughly 0.13S). If I put forward such a requirement: the delay time is 0.13S after the light turns on, and the light turns off after the light turns off, and the delay time is 0.1s. Can such a program still meet the requirements? No, what should we do? We can change the delay program to this (see Table 2): The call is shown in the main program in Table 2, that is, first send a number to 30H. The value in R7 in the subroutine is not fixed, but is determined according to the number passed from the 30H unit. This can meet the requirements.
From this we can conclude that in data transmission, in order to find the number being passed, in many cases, this number cannot be given directly and needs to be changed. This leads to a concept: how to find the operand. We call the address of the unit where the operand is located as addressing. Here we directly use the address of the unit where the number is located to find the operand, so this method is called direct addressing. In addition to this method, there is another method. If we put the number in the working register and find the data from the working register, it is called register addressing. For example, MOV A, R0 sends the data in the working register R0 to the accumulator A. Here is a question: As we know, the working register is part of the memory unit. If we choose the working register group 0, then R0 is the 00H unit of the RAM. In this case, there is no difference between MOV A, 00H and MOV A, R0? Why do we need to distinguish them? Indeed, the results of the execution of these two instructions are exactly the same, both of which send the content in the 00H unit to A, but the execution process is different. The execution of the first instruction requires 2 cycles, while the second only requires 1 cycle. The first instruction needs two bytes (E5H 00H) to become the final target code, while the second only requires one byte (E8h).

Why are you so fussy? Isn't it just one cycle? If it is a 12M crystal oscillator, it is only 1 microsecond. How much can a byte have?

No, if this instruction is executed only once, it may not matter, but if an instruction is executed 1,000 times, it is 1 millisecond. If it is executed 1000000 times, it is 1S error, which is considerable. The microcontroller is responsible for real-time control, so it must be so "meticulous". The same is true for the number of bytes.

Let me ask another question. Now we know that we can find operands by directly giving them (immediate addressing) and by directly giving the address of the unit where the number is located (direct addressing). Is this enough?

Looking at this problem, it requires starting from unit 30H, taking 20 numbers and sending them into the A accumulator respectively.

As far as the method we have mastered at present is concerned, to fetch a number from the 30H unit, we use MOV A, 30H. Then what about the next number? If it is from the 31H unit, how to fetch it? Or can we only use MOV A, 31H? Then, wouldn't it take 20 instructions to write 20 numbers? There are only 20 numbers here. If we want to send 200 or 2000 numbers, wouldn't we have to write 200 or 2000 commands? This is too stupid. Why does this happen? Because we only know how to write the address in the instruction, so there is no way. If we don't write the address directly in the instruction, but put the address in another register unit, and decide which unit to fetch data according to the value in this register unit, for example, if the current value in this register is 30H, then fetch it from the 30H unit, and if it is 31H, fetch it from the 31H unit, then this problem can be solved. How to solve it? Since we are looking at the value in the register, we can use certain methods to change the value here, such as adding 1 to the value in the register unit after taking a number. It is still the same instruction, but the object of the number is different, right? Let's explain it through an example.

MOV R7, #20

MOV R0, #30H

LOOP: MOV A, @R0

INC R0

DJNZ R7,LOOP

We can understand most of the instructions in this example. The first sentence is to send the immediate value 20 to R7. After execution, the value in R7 should be 20. The second sentence is to send the immediate value 30H to the R0 working register. So after execution, the value in R0 is 30H. The third sentence is to see what the value in R0 is, use this value as the address, take the content of this address unit and send it to A. At this time, the result of executing this instruction is equivalent to MOV A, 30H. The fourth sentence, which we have not learned, adds 1 to the value in R0. Therefore, after execution, the value in R0 is 31H. The fifth sentence, which we have learned, subtracts 1 from the value in R7 to see if it is equal to 0. If it is not equal to 0, it will jump to the label LOOP to continue execution. Therefore, after executing this sentence, it will jump to execute MOV A, @R0, which is equivalent to executing MOV A, 31H (because the value in R0 is already 31H at this time). This continues until the value in R7 is subtracted successively and equals 0, that is, the loop is repeated 20 times, and our requirement is achieved: 20 data are sent to A starting from unit 30H.

This is also a method of finding data. Since the data is found indirectly, it is called indirect addressing. Note that in indirect addressing, only R0 or R1 can be used to store the data being sought.

 


2. Instructions


Data transfer instructions 1) Instructions with the accumulator as the destination operand

MOV A, Rn

MOV A, direct

MOV A, @Ri

MOV A, #data

In the first instruction, Rn represents R0-R7. In the second instruction, direct refers to the direct address, and in the third instruction, it is what we just talked about. The fourth instruction is to send the immediate data to A.

Let's illustrate this with some examples:

MOV A, R1; send the value in the working register R1 to A, and the value in R1 remains unchanged.

MOV A,30H; send the value in memory unit 30H to A, and the value in unit 30H remains unchanged.

MOV A,@R1; first check the value in R1, use this value as the address, and send the value in this address unit to A. If the value in R1 is 20H before executing the command, the value in the 20H unit is sent to A.

MOV A,#34H; send the immediate number 34H into A. After executing this instruction, the value in A is 34H.


2) Instructions that operate on register Rn

MOV Rn,A

MOV Rn,direct

MOV Rn,#data

The function of this set of instructions is to send the contents of the source address unit into the working register, and the source operand remains unchanged.

Keywords:MCU Reference address:Microcontroller Knowledge (III)

Previous article:Microcontroller Knowledge (IV)
Next article:Microcontroller Knowledge (II)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号