Posts

Showing posts from September, 2018

Instruction Set and Timing

The 8051 operates based on an external crystal. This is an electrical device which, when energy is applied, emits pulses at a fixed frequency. One can find crystals of virtually any frequency depending on the application requirements. When using an 8051, the most common crystal frequencies are 12 megahertz and 11.059 megahertz with 11.059 being much more common.  Why would anyone pick such an odd-ball frequency?  There is a real reason for it :-   It has to do with generating baud rates and well talk more about it in the Serial Communication chapter. For the remainder of this discussion well assume that were using an 11.059Mhz crystal.  Microcontrollers (and many other electrical systems) use crystals to synchronize operations. The 8051 uses the crystal for precisely that: to synchronize its operation. Effectively, the 8051 operates using what are called "machine cycles." A single machine cycle is the minimum amount of time in which a single 8051 instru...

Common Problems with Interrupts

Interrupts are a very powerful tool available to the 8051 developer, but when used incorrectly they can be a source of a huge number of debugging hours. Errors in interrupt routines are often very difficult to diagnose and correct. If  interrupts are being used and the program is crashing or does not seem to be performing as expected, always review the following interrupt-related issues :- 1. Register Protection : Make sure you are protecting all your registers, as explained above. If forget to protect a register that the main program is using, very strange results may occur. In our example above we saw how failure to protect registers caused the main program to apparently calculate that 25h + 10h = 51h. If it witness problems with registers changing values unexpectedly or operations producing "incorrect" values, it is very likely that  forgotten to protect registers.  ALWAYS PROTECT YOUR REGISTERS. 2. Forgetting to restore protected values: Anot...

Serial Interrupts

Serial Interrupts are slightly different than the rest of the interrupts. This is due to the fact that there are two interrupt flags: RI and TI. If either flag is set, a serial interrupt is triggered. As it will recall from the section on the serial port, the RI bit is set when a byte is received by the serial port and the TI bit is set when a byte has been sent. This means that when the serial interrupt is executed, it may have been triggered because the RI flag was set or because the TI flag was set--or because both flags were set. Thus, the routine must check the status of these flags to determine what action is appropriate. Also, since the 8051 does not automatically clear the RI and TI flags this must clear these bits in the interrupt handler.                                JNB INT_SERIAL: RI,CHECK_TI    ; If the RI flag is not set, then jump to check TI MOV A, SBUF  ...

What happens when an interrupt ends?

An interrupt ends when your program executes the RETI (Return from Interrupt) instruction.  When the RETI instruction is executed the following actions are taken by the microcontroller :- 1. Two bytes are popped off the stack into the Program Counter to restore normal program execution. 2. Interrupt status is restored to its pre-interrupt status.

What happens when an interrupt occurs?

When an interrupt is triggered, the following actions are taken automatically by the microcontroller :- 1.  The current Program Counter is saved on the stack, low-byte first. 2.  Interrupts of the same and lower priority are blocked. 3.  In the case of Timer and External interrupts, the corresponding interrupt flag is cleared. 4.  Program execution transfers to the corresponding interrupt handler vector address. 5.  The Interrupt Handler Routine executes. Take special note of the third step: If the interrupt being handled is a Timer or External interrupt, the microcontroller automatically clears the interrupt flag before passing control to interrupt handler routine. This means it is not necessary that bit is cleared in the code.

Interrupt Priorities

Image
The 8051 offers two levels of interrupt priority: high and low. By using interrupt priorities it may assign higher priority to certain interrupt conditions. For example, you may have enabled Timer 1 Interrupt which is automatically called every time Timer 1 overflows. Additionally, you may have enabled the Serial Interrupt which is called every time a character is received via the serial port. However, you may consider that receiving a character is much more important than the timer interrupt. In this case, if Timer 1 Interrupt is already executing then it may wish that the serial interrupt itself interrupts the Timer 1 Interrupt. When the serial interrupt is complete, control passes back to Timer 1 Interrupt and finally back to the main program. This may accomplish this by assigning a high priority to the Serial Interrupt and a low priority to the Timer 1 Interrupt. When considering interrupt priorities, the following rules apply : - 1. Nothing can interrupt a high-prior...

Polling Sequence

The 8051 automatically evaluates whether an interrupt should occur after every instruction. When checking for interrupt conditions, it checks them in the following order : - 1.  External 0 Interrupt 2.  Timer 0 Interrupt 3.  External 1 Interrupt 4.  Timer 1 Interrupt 5.  Serial Interrupt This means that if a Serial Interrupt occurs at the exact same instant that an External 0 Interrupt occurs, the External 0 Interrupt will be executed first and the Serial Interrupt will be executed once the External 0 Interrupt has completed.

Setting Up Interrupts

Image
By default at powerup, all interrupts are disabled. This means that even if, for example, the TF0 bit is set, the 8051 will not execute the interrupt. This program must specifically tell the 8051 that it wishes to enable interrupts and specifically which interrupts it wishes to enable. Each of the 8051s interrupts has its own bit in the IE SFR. This will enable a given interrupt by setting the corresponding bit. For example, if it wish to enable Timer 1 Interrupt, this would execute either: MOV IE, #08h or SETB ET1 Both of the above instructions set bit 3 of IE, thus enabling Timer 1 Interrupt. Once Timer 1 Interrupt is enabled, whenever the TF1 bit is set, the 8051 will automatically put "on hold" the main program and execute the Timer 1 Interrupt Handler at address 001Bh. However, before Timer 1 Interrupt (or any other interrupt) is truly enabled, it must also set bit 7 of IE. Bit 7, the Global Interupt Enable/Disable, enables or disables all interrupts ...

Events that can trigger interrupts and where do they go?

8051 can be configure so that any of the following events will cause an interrupt : - 1.  Timer 0 Overflow 2.  Timer 1 Overflow 3.  Reception/Transmission of Serial Character 4.  External Event 0 5.  External Event 1 In other words, we can configure the 8051 so that when Timer 0 Overflows or when a character is sent/received, the appropriate interrupt handler routines are called.  Obviously,  there need to be able to distinguish between various interrupts and executing different code depending on what interrupt was triggered. This is accomplished by jumping to a fixed address when a given interrupt occurs.

Interrupts

Image
An  interrupt  is some event which interrupts normal program execution.  As stated earlier, program flow is always sequential, being altered only by those instructions which expressly cause program flow to deviate in some way. However, interrupts give us a mechanism to "put on hold" the normal program flow, execute a subroutine, and then resume normal program flow as if it was never left. This subroutine, called an interrupt handler, is only executed when a certain event (interrupt) occurs. The event may be one of the timers "overflowing," receiving a character via the serial port, transmitting a character via the serial port, or one of two "external events." The 8051 may be configured so that when any of these events occur the main program is temporarily suspended and control passed to a special section of code which presumably would execute some function related to the event that occured . Once complete, control would be returned to the original progr...

The Stack Pointer (SP)

Image
The Stack Pointer , like all registers except DPTR and PC, may hold an 8-bit (1-byte) value. The Stack Pointer is used to indicate where the next value to be removed from the stack should be taken from. When there is to push a value onto the stack, the 8051 first increments the value of SP and then stores the value at the resulting memory location. When there is to pop a value off the stack, the 8051 returns the value from the memory location indicated by SP, and then decrements the value of SP. This order of operation is important. When the 8051 is initialized SP will be initialized to 07h. If there is to  immediately push a value onto the stack, the value will be stored in Internal RAM address 08h. This makes sense taking into account what was mentioned two paragraphs above: First the 8051 will increment the value of SP (from 07h to 08h) and then will store the pushed value at that memory address (08h). SP is modified directly by the 8051 by six instructions: PUSH, POP, ACA...

The Program Counter (PC)

Image
The Program Counter (PC) is a 2-byte address which tells the 8051 where the next instruction to execute is found in memory. When the 8051 is initialized PC always starts at 0000h and is incremented each time an instruction is executed. It is important to note that PC isn't always incremented by one. Since some instructions require 2 or 3 bytes the PC will be incremented by 2 or 3 in these cases.  The Program Counter is special in that there is no way to directly modify its value. That is to say, it is not possible to do something like PC=2430h. On the other hand, if there is to execute LJMP 2430h there is need to effectively accomplished the same thing.                                                                    Another important register in the 8051 is the PC (program counter). The program counter ...

The data Pointer (DPTR)

Image
The Data Pointer (DPTR) is the 8051s only user-accessable 16-bit (2-byte) register. The Accumulator, "R" registers, and "B" register are all 1-byte values. DPTR, as the name suggests, is used to point to data. It is used by a number of commands which allow the 8051 to access external memory. When the 8051 accesses external memory it will access external memory at the address indicated by DPTR. While DPTR is most often used to point to data in external memory, many programmers often take advantge of the fact that its the only true 16-bit register available. It is often used to store 2-byte values which have nothing to do with memory locations. It consists of one 8-bit register for DPL and other 8-bit register for DPH.

The "B' registers

Image
The "B" register is very similar to the Accumulator in the sense that it may hold an 8-bit (1-byte) value. The "B" register is only used by two 8051 instructions: MUL AB and DIV AB. Thus, if there is need for quickly and easily multiply or divide A by another number, this may store the other number in "B" and make use of these two instructions. Aside from the MUL and DIV instructions, the "B" register is often used as yet another temporary storage register much like a ninth "R" register.

The "R" registers

Image
The "R" registers are a set of eight registers that are named R0, R1, etc. up to and including R7. These registers are used as auxillary registers in many operations. To continue with the above example, perhaps there is need to add 10 and 20. The original number 10 may be stored in the Accumulator whereas the value 20 may be stored in, say, register R4. To process the addition there is necessity to execute the command:    ADD A, R4 After executing this instruction the Accumulator will contain the value 30. There is need to think of the "R" registers as very important auxillary, or "helper", registers. The Accumulator alone would not be very useful if it were not for these "R" registers. The "R" registers are also used to temporarily store values. For example, lets say there is need  to add the values in R1 and R2 together and then subtract the values of R3 and R4. One way to do this would be: MOV A, R3  ;  Move the value of ...

Accumulator

Image
The Accumulator , as its name suggests, is used as a general register to accumulate the results of a large number of instructions. It can hold an 8-bit (1-byte) value and is the most versatile register the 8051 has due to the shear number of instructions that make use of the accumulator. More than half of the 8051s 255 instructions manipulate or use the accumulator in some way.  For example, if the numbers 10 and 20 are added, the resulting 30 will be stored in the a ccumulator . Once the value is there in accumulator this may used  to continue processing the value or can store it in another register or in memory.

Code indirect

External memory can also be accessed using a form of indirect addressing which is called as  code indirect addressing. This form of addressing is usually only used in relatively small projects that have a very small amount of external RAM. An example of this addressing mode is: - MOVX @R0, A Once again, the value of R0 is first read and the value of the Accumulator is written to that address in External RAM. Since the value of @R0 can only be 00h through FFh the project would effectively be limited to 256 bytes of External RAM. There are relatively simple hardware/software tricks that can be implemented to access more than 256 bytes of memory using External Indirect addressing; however, it is usually easier to use External Direct addressing if your project has more than 256 bytes of External RAM.

External Direct

External Memory is accessed using a suite of instructions which use what I call " External Direct " addressing. Ii is called called this because it appears to be direct addressing, but it is used to access external memory rather than internal memory. There are only two commands that use External Direct addressing mode: MOVX A, @DPTR MOVX @DPTR, A As you can see, both commands utilize DPTR. In these instructions, DPTR must first be loaded with the address of external memory that you wish to read or write. Once DPTR holds the correct external memory address, the first command will move the contents of that external memory address into the Accumulator. The second command will do the opposite: it will allow you to write the value of the Accumulator to the external memory address pointed to by DPTR.

Indirect addressing

Indirect addressing is a very powerful addressing mode which in many cases provides an exceptional level of flexibility. Indirect addressing is also the only way to access the extra 128 bytes of Internal RAM found on an 8052. Indirect addressing appears as follows:        MOV A, @R0 This instruction causes the 8051 to analyze the value of the R0 register. The 8051 will then load the accumulator with the value from Internal RAM which is found at the address indicated by R0. For example, lets say R0 holds the value 40h and Internal RAM address 40h holds the value 67h. When the above instruction is executed the 8051 will check the value of R0. Since R0 holds 40h the 8051 will get the value out of Internal RAM address 40h (which holds 67h) and store it in the Accumulator. Thus, the Accumulator ends up holding 67h. Indirect addressing always refers to Internal RAM; it never refers to an SFR. Thus, in a prior example we mentioned that SFR 99h can be used to w...

Direct Addressing

Direct addressing is so-named because the value to be stored in memory is obtained by directly retrieving it from another memory location.  For example :-        MOV A, #30h This instruction will read the data out of Internal RAM address 30 (hexidecimal) and store it in the Accumulator.  Direct addressing is generally fast since, although the value to be loaded isn't included in the instruction, it is quickly accessable since it is stored in the 8051s Internal RAM. It is also much more flexible than Immediate Addressing since the value to be loaded is whatever is found at the given address--which may be variable. Also, it is important to note that when using direct addressing any instruction which refers to an address between 00h and 7Fh is referring to Internal Memory. Any instruction which refers to an address between 80h and FFh is referring to the SFR control registers that control the 8051 microcontroller itself. The obvious question t...

Immediate addressing

Immediate addressing is so-named because the value to be stored in memory immediately follows the operation code in memory. That is to say, the instruction itself dictates what value will be stored in memory. For example, the instruction:    MOV A, #10h This instruction uses Immediate Addressing because the Accumulator will be loaded with the value that immediately follows; in this case 20 (hexidecimal). Immediate addressing is very fast since the value to be loaded is included in the instruction. However, since the value to be loaded is fixed at compile-time it is not very flexible.

Addressing Modes

An "addressing mode" refers to how you are addressing a given memory location. The addressing modes are as follows, with an example of each: Immediate Addressing                    MOV A, #10h Direct Addressing                    MOV A, #40h Indirect Addressing                    MOV A, @R0 External Direct                                            MOVX A, @DPTR Code Indirect                     MOVC A, @A+DPTR Each of these addressing modes provides important flexibility.

Instruction Sets of 8051 microcontroller

 ACALL                                               Absolute Call  ADD, ADDC                                       Add Accumulator (With Carry)   AJMP                                                  Absolute Jump  ANL                                                     Bitwise AND  CJNE                                                   Compare and Jum...

Features of 8051 microcontroller

1.  8- bit CPU 2.   16-bit Program counter 3.   8-bit Processor Status Word (PSW) 4.   8-bit Stack Pointer 5.   Internal RAM of 128 bytes 6.  Special Function Registers (SFRs) of 128 bytes 7.   32 I/O pins arranged as four 8-bit ports (P0-P3) 8.  Two 16 bit timer/counters : T0 and T1 9.  Two external and three internal vectored interrupts 10. One full duplex serial I/O

Description of AT89S52

Image
The AT89S52 is a low-power, high performance CMOS 8-bit microcontroller with 8K bytes of in-system programmable Flash memory. The device is manufactured using Atmel's high-density nonvolatile memory technology and is compatible with the industry-standard AT80C51 instruction set and pinout. The on-chip Flash allows the program memory to be reprogrammed in-system  programmable Flash on a monolithic chip, the Atmel AT89S52 is a powerful microcontroller which provides a  highly-flexible and cost-effective solution to many embedded control applications. The AT89S52 provides the following standard features: 8K bytes of Flash, 256 bytes of RAM, 32 I/O lines, Watchdog timer, two data pointers, three 16-bit timer/counters, a six-vector two-level interrupt architecture, a full duplex serial port, on-chip oscillator and clock circuitary. In addition, the AT89S52 is designed with static logic for operation down to zero frequency and supports two software selectable power saving m...