MC Unit 3 Notes-2
MC Unit 3 Notes-2
Advantages of C programming:
a. Easier and less time consuming to write in C than assembly programming.
b. C is easier to modify and update
c. You can use code available in function libraries
d. C code is portable to other microcontroller with little or no modification
i. Unsigned char
ii. Signed char
iii. Unsigned int
iv. Signed int
v. Sbit (single bit)
vi. Bit and sfr
i. Unsigned char:
Since 8051 is an 8-bit microcontroller, the character data type is the most natural choice for many applications
and most widely used data types for 8051. It is an 8-bit data type that takes a value in the range of 0 – 255(00H
– FFH). It occupies one byte location in internal RAM. In setting a counter value, to store string of ASCII
characters, where there is no need for signed data, unsigned char should be used instead of signed char. Default
is signed char. „unsigned‟ keyword is used to declare unsigned char.
#include <reg51.h>
void main(void)
{
unsigned char z;
for (z=0;z<=255;z++)
P1=z;
}
Write an 8051 C program to send hex values for ASCII characters of 0, 1, 2, 3, 4, 5, A, B, C, and D to port
P1.
Solution:
#include <reg51.h>
#include <reg51.h>
void main(void)
{
char mynum[]={+1,-1,+2,-2,+3,-3,+4,-4};
unsigned char z;
for (z=0;z<=8;z++)
P1=mynum[z];
}
Write an 8051 C program to toggle bit D0 of the port P1 (P1.0) 50,000 times.
Solution:
#include <reg51.h>
sbit MYBIT=P1^0;
void main(void)
{
unsigned int z;
for (z=0;z<=50000;z++)
{
MYBIT=0;
MYBIT=1;
}
}
Write an 8051 C program to toggle only bit P2.4 continuously without disturbing the rest of the bits of
P2.
Solution:
#include <reg51.h>
sbit mybit=P2^4;
void main(void)
{
while (1)
{
mybit=1; //turn on P2.4
mybit=0; //turn off P2.4
}
}
Write an 8051 C program to get the status of bit P1.0, save it, and send it to P2.7 continuously.
Solution:
#include <reg51.h>
sbit inbit=P1^0;
sbit outbit=P2^7;
bit membit; //use bit to declare bit- addressable memory
void main(void)
{
while (1)
{
membit=inbit; //get a bit from P1.0
outbit=membit; //send it to P2.7
}
}
2. The crystal frequency connected to XTAL1 and XTAL2 input pins. The duration of clock period for
machine cycle is a function of crystal frequency.
3. C compiler converts C program to assembly language instructions. Different compilers produce different
code and hence produce different hex code.
Write an 8051 C program to toggle bits of P1 continuously forever with some delay.
Solution:
#include <reg51.h>
void main(void)
{
unsigned int x;
for (;;) //repeat forever
{
p1=0x55;
for (x=0;x<40000;x++); //delay size
//unknown
p1=0xAA;
for (x=0;x<40000;x++);
}
}
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
while (1) //repeat forever
{
P1=0x55;
MSDelay(250);
p1=0xAA;
MSDelay(250);
}
}
void MSDelay(unsigned int itime)
{
unsigned int i,j;
for (i=0;i<itime;i++)
for (j=0;j<1275;j++);
}
Byte-wise operators in C:
a. AND (&&),
b. OR (||),
c. NOT (!)
Bit-wise operators in C:
a. AND (&),
b. OR (|),
c. EX-OR (^),
d. Inverter (~),
e. Shift Right (>>),
f. Shift Left (<<)
These operators are widely used in software engineering for embedded systems and control.
#include <reg51.h>
void main(void)
{
P0=0x35 & 0x0F; //ANDing
P1=0x04 | 0x68; //ORing
P2=0x54 ^ 0x78; //XORing
P0=~0x55; //inversing
P1=0x9A >> 3; //shifting right 3
P2=0x77 >> 4; //shifting right 4
P0=0x6 << 4; //shifting left 4
}
Write an 8051 C program to toggle all the bits of P0 and P2 continuously with a 250 ms delay. Using the
inverting and Ex-OR operators, respectively.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
P0=0x55;
P2=0x55;
while (1)
{
P0=~P0;
P2=P2^0xFF;
MSDelay(250);
}
}
Write an 8051 C program to convert packed BCD 0x29 to ASCII and display the bytes on P1 and P2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char x,y,z;
unsigned char mybyte=0x29;
x=mybyte&0x0F;
P1=x|0x30;
y=mybyte&0xF0;
y=y>>4;
P2=y|0x30;
}
#include <reg51.h>
void main(void)
{
unsigned char bcdbyte;
unsigned char w=„4‟;
unsigned char z=„7‟;
w=w&0x0F;
w=w<<4;
z=z&0x0F;
bcdbyte=w|z;
P1=bcdbyte;
}
1. The 128 bytes of RAM space with address range 00H to 7FH.
2. The 64 kbytes of on-chip code or program memory with address range 0000H to FFFFH. Here both program
as well data can be stored and accessed using program counter (PC). To read data from this memory “movc a,
@a+dptr” instruction is used in assembly language program. To store data into this memory DB (define byte)
assembler directive is used. If more data is stored in this memory, less space is left for program. This space is
used to store predefined data and tables. But data cannot be written to it during execution of program.
3. The 64 kbytes of external memory can be used as both RAM and ROM. MOVX instruction is used to access
external memory.
Write, compile and single-step the following program on your 8051simulator. Examine the contents of the
code space to locate the values.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mydata[100]; //RAM space
unsigned char x,z=0;
for (x=0;x<100;x++)
{
z--;
Compile and single-step the following program on your 8051 simulator. Examine the contents of the 128-
byte RAM space to locate the ASCII values.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mynum[]=“ABCDEF”; //RAM space
unsigned char z;
for (z=0;z<=6;z++)
P1=mynum[z];
}
To store data in code space or memory instead of RAM memory, keyword code is used in front of the variable
declaration
Ex: code unsigned char num[] = “1234”;
code unsigned char weekdays=7, month=0x12;
Compile and single-step the following program on your 8051 simulator. Examine the contents of the code
space to locate the ASCII values.
Solution:
#include <reg51.h>
void main(void)
{
code unsigned char mynum[]=“ABCDEF”;
unsigned char z;
for (z=0;z<=6;z++)
P1=mynum[z];
}
Compare and contrast the following programs and discuss the advantages and disadvantages of each one.
(a)
#include <reg51.h>
void main(void)
{
P1=„H‟;
P1=„E‟;
P1=„L‟;
P1=„L‟;
P1=„O‟;
}
(b)
#include <reg51.h>
void main(void)
{
unsigned char mydata[]=“HELLO”;
unsigned char z;
for (z=0;z<=5;z++)
P1=mydata[z];
}
Use the RAM data space to store array elements, therefore the size of the array is limited.
(c)
#include <reg51.h>
void main(void)
{
code unsigned char mydata[]=“HELLO”;
unsigned char z;
for (z=0;z<=5;z++)
P1=mydata[z];
}
Use a separate area of the code space for data. This allows the size of the array to be as long as you want if you
have the on-chip ROM. However, the more code space you use for data, the less space is left for your program
code.
Sample C Programs:
#include <reg51.h>
void main(void)
{
for (;;)
{
P1=0x55;
P1=0xAA;
}
LEDs are connected to bits P1 and P2. Write an 8051 C program that shows the count from 0 to FFH
(0000 0000 to 1111 1111 in binary) on the LEDs.
Solution:
#include <reg51.h>
#defind LED P2;
void main(void)
{
Write an 8051 C program to get a byte of data form P0. If it is less than 100, send it to P1; otherwise,
send it to P2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mybyte;
P0=0xFF; //make P0 input port
while (1)
{
mybyte=P0; //get a byte from P0
if (mybyte<100)
P1=mybyte; //send it to P1
else
P2=mybyte; //send it to P2
}
}
Write an 8051 C program to monitor bit P1.5. If it is high, send 55H to P0; otherwise, send AAH to P2.
Solution:
#include <reg51.h>
sbit mybit=P1^5;
void main(void)
{
mybit=1; //make mybit an input
while (1)
{
if (mybit==1)
P0=0x55;
else
P2=0xAA;
}
}
Write an 8051 C program to turn bit P1.5 on and off 50,000 times.
Solution:
sbit MYBIT=0x95;
Write an 8051 C program to get bit P1.0 and send it to P2.7 after inverting it.
Solution:
#include <reg51.h>
sbit inbit=P1^0;
sbit outbit=P2^7;
bit membit;
void main(void)
{
while (1)
{
membit=inbit; //get a bit from P1.0
outbit=~membit; //invert it and send
//it to P2.7
}}
The 8051 has two timers/counters, Timer 0 and Timer 1. They can be used as either timers to generate a time
delay or as counters to count events happening outside the microcontroller. Both Timer 0 and Timer 1 are 16
bits wide. They are accessed as two separate registers of low byte and high byte.
C/T (clock/timer):
This bit is used to select timer hardware as a timer or counter. If this bit is set to 0, timer hardware act as a
timer to generate time delay by counting internal clock pulse generated by the crystal oscillator. If the bit is set
to 1, the hardware acts as a counter to count external clock pulse which represents an event.
Timer in 8051 is used as timer, counter and baud rate generator. Timer always counts up irrespective of whether
it is used as timer, counter, or baud rate generator: Timer is always incremented by the microcontroller. The
time taken to count one digit up is based on master clock frequency.
If Master CLK=11.0592 MHz,
Timer Clock frequency = Master CLK/12 = 921.6 kHz
Timer Clock Period = 1.085 micro second
This indicates that one increment in count will take 1.085 micro second.
Indicate which mode and which timer is selected for each of the following.
(a) MOV TMOD, #01H (b) MOV TMOD, #20H (c) MOV TMOD, #12H
Solution:
We convert the value from hex to binary.
(a) TMOD = 00000001, mode 1 of timer 0 is selected.
(b) TMOD = 00100000, mode 2 of timer 1 is selected.
(c) TMOD = 00010010, mode 2 of timer 0, and mode 1 of timer 1 are selected.
Find the timer’s clock frequency and its period for various 8051 based systems, with the following crystal
frequencies:
a. 12 MHz,
b. 16 MHz,
c. 11.0592 MHz.
Solution:
GATE Bit:
Every timer has a means of starting and stopping. Some timers do this by software, some by hardware and
some have both software and hardware controls. The timers in 8051 have both. The start and stop of the timer
are controlled by way of software by the TR (timer start) bits TR0 and TR1. This is achieved by the
instructions “SETB TR1” and “CLR TR1” for Timer 1 and „SETB TR0” and “CLR TR0” for Timer 0. The
SETB instruction starts and CLR instruction stops the timer. This method works when gate bit of TMOD is 0.
When gate bit is 1, external hardware is used to start and stop the timer. The signal from external hardware is
applied to external interrupt pins INT0‟ (P3.2) and INT1‟ (P3.3).
a. Hexadecimal method:
Divide the desired time delay by 1.085 μs which gives number of clock pulses to be counted to generate
the required delay.
Convert the number of clock pulses to hexadecimal value (YYXX).
Perform (FFFF – YYXX + 1) gives value to be loaded to TH and TL.
b. Decimal method:
Divide the desired time delay by 1.085 μs which gives number of clock pulses to be counted to generate
the required delay (n).
Perform 65536 – n.
Convert the decimal value got in previous step to hexadecimal which is the value to be loaded to TH and
TL.
a. Hexadecimal method:
Perform (FFFF – YYXX +1) * 1.085 μs which gives the value of time delay.
b. Decimal method:
Convert YYXX to decimal value NNNN.
Perform (65536 – NNNN) * 1.085 μs which gives the value of time delay.
TCON is an 8-bit, bit accessible special function register. The upper four bits consists of timer run bit and timer
overflow flag bit for both T0 and T1. The lower four bits are used for interrupt operation. TR0 and TR1 bits
stands for timer run bit and are used to start and stop the TR0 and TR1 respectively. TF0 and TF1 bits stands
for timer overflow flag for T0 and T1 respectively. These two flags are set to 1 when the timer resets to initial
value from FFFFH.
Mode 1 Programming:
Following are the characteristics and operations of mode 1:
1. It is a 16-bit timer, hence allows values from 0000H to FFFFH to be loaded into the timers registers TL and
TH.
2. Initial value is loaded to timer and timer started. Timer starts to count up until it reaches FFFFH.
3. When timer rolls over from FFFFH to 0000H, overflow flag bit corresponding to the timer is set to 1. This
flag is monitored continuously using JNB instruction. Once the flag is set to 1, the timer can be stopped using
CLR instruction.
4. To repeat the operation, overflag is reset to 0, load the initial value to TL and TH and start the timer.
In the following program, a square wave of 50% duty cycle (with equal portions high and low) is created
on the P1.5 bit. Timer 0 is used to generate the time delay. Analyze the program.
Find the delay generated by timer 0 in the following code, using both decimal and hexadecimal method.
Do not include the overhead due to instruction.
Assume that XTAL = 11.0592 MHz, write a program to generate a square wave of 2 kHz frequency on
pin P1.5.
Solution:
The following program generates a square wave on P1.5 continuously using timer 1 for a time delay. Find
the frequency of the square wave if XTAL = 11.0592 MHz. In your calculation do not include the
overhead due to Instructions in the loop.
Examine the following program and find the time delay in seconds. Exclude the overhead due to the
instructions in the loop.
Examine the following program and find the time delay in seconds. Exclude the overhead due to the
instructions in the loop.
In the following program calculate the frequency of the square wave generated on pin P1.5. Consider the
overhead due to instruction.
Solution:
To get a more accurate timing, we need to add clock cycles due to these instructions in the loop. To do that, we
use the machine cycle of each instruction in the program.
Program Machine Cycle
HERE: MOV TL0, #0F2H 2
MOV TH0, #0FFH 2
CPL P1.5 1
ACALL DELAY 2
SJMP HERE 2
DELAY: SETB TR0 1
AGAIN: JNB TF0, AGAIN 14
CLR TR0 1
CLR TF0 1
RET 2
Total 28
T = 2 × 28 × 1.085 us = 60.76 us and F = 16458.2 Hz
To get the largest delay we make TL and TH both 0. This will count up from 0000 to FFFFH and then roll over
to zero.
Making TH and TL both zero means that the timer will count from 0000 to FFFF, and then roll over to raise the
TF flag. As a result, it goes through a total Of 65536 states. Therefore, we have delay = (65536 - 0) × 1.085 us =
71.1065ms.
Mode 0:
In this mode timer is used as a 13 bit timer. The lower 5 bits of TLX and 8 bits of THX are used for the 13 bit
count. Upper 3 bits of TLX are ignored. It can hold values between 0000H to 1FFFH. Once it reaches final
count of 1FFFH, on the application of clock pulse, the timer will roll back to 0000h. The maximum delay that
can be generated in this mode is 8.88 ms. Because of lesser delay, mode 1 is preferred instead of mode 0.
Mode 2:
The following are the characteristics and operations of mode 2.
1. It is an 8-bit timer; therefore, it allows only values of 00 to FFH to be loaded into the timer‟s register TH.
2. After TH is loaded with the 8-bit value, the 8051 gives a copy of it to TL. Then the timer must be started.
This is done by the instruction SETB TR0 for timer 0 and SETB TR1 for timer 1.
3. After the timer is started, it starts to count up by incrementing the TL register. It counts up until it reaches its
limit of FFH. When it rolls over from FFH to 00, it sets high the TF (timer flag).
4. When the TL register rolls from FFH to 00H and TF is set to 1, TL is reloaded automatically with the original
value kept by the TH register. To repeat the process, we must simply clear TF and let it go without any need by
the programmer to reload the original value. This makes mode 2 an auto-reload, in contrast with mode 1 in
which the programmer has to reload TH and TL.
Mode 2 is used in generating baud rate for serial communication.
Assume XTAL = 11.0592 MHz, find the frequency of the square wave generated on pin P1.0 in the
following program.
Assuming that we are programming the timers for mode 2, find the value (in hex) loaded into TH for
each of the following cases.
(a) MOV TH1, #-200 (b) MOV TH0, #-60
(c) MOV TH1, #-3 (d) MOV TH1, #-12
(e) MOV TH0, #-48
Solution:
You can use the Windows scientific calculator to verify the result provided by the assembler. In Windows
calculator, select decimal and enter 200. Then select hex, then +/- to get the TH value. Remember that we only
use the right two digits and ignore the rest since our data is an 8-bit data.
Counter Programming:
If the timer is used to external event happening outside 8051, timer is known as a counter also known as event
counter. External event in the form of clock pulse is applied to either pin number 14 (P3.4, T0 input) or
15(P3.5, T1 input) which increments the content of the TH and TL registers.
Assuming that clock pulses are fed into pin T1, write a program for counter 1 in mode 2 to count the
pulses and display the state of the TL1 count on P2, which connects to 8 LEDs.
Solution:
Notice in the above program the role of the instruction SETB P3.5. Since ports are set up for output when the
8051 is powered up, we make P3.5 an input port by making it high. In other words, we must configure (set
high) the T1 pin (pin P3.5) to allow pulses to be fed into it.
Design a counter for counting the pulses of an input signal. The pulses to be counted are fed to pin P3.4.
Assume XTAL = 11.0592 MHz.
Solution:
Here timer 1 is used as time base for timing 1 second. During this 1 second, timer 0 is run as a counter with
input pulses fed into P3.4. At the end of 1 second, the values in TL0 and TH0 give the number of pulses
received at P3.4. This gives the frequency of unknown signal.
ORG 0000H
RPT: MOV TMOD, #15H
SETB P3.4
MOV TL0, #00
MOV TH0, #00
SETB TR0
MOV R0, #14
AGAIN: MOV TL1, #00H
MOV TH1, #00H
SETB TR1
BACK: JNB TF1, BACK
CLR TF1
CLR TR1
DJNZ R0, AGAIN
MOV A, TL0
MOV P2, A
MOV A, TH0
MOV P1, A
SJMP RPT
END
As the frequency varies, the values obtained at P1 and P2 vary. The values obtained for 10 Hz, 25 Hz, 100 Hz,
are respectively 0AH, 19H, 64H., etc.,.
In the above program, timer 1 is used as an event counter where it counts up as clock pulses are fed into P3.5.
These clock pulses could represent the number of people passing through an entrance or the number of wheel
rotations or any other event that can be converted to pulses.