Es Unit-Ii
Es Unit-Ii
In this lecture, we will discuss about the Logical operators in Embedded C. Data
conversion programs in embedded C will also be written and discussed. At the end Data
Serialization in 8051 using embedded C will be discussed.
Bitwise Operations in C
Q. Illustrate any two logical operators used in C with their examples (2M)
One of the most important and powerful features of the C language is its ability to perform
bit wise manipulation. This section describes the action of bitwise logic operators. Figure1.1
shows the bitwise logical operators.
Using these bit wise operators Embedded c will perform the logical operations bit wise on
binary numbers. Following are some examples which show how they are used.
Following program will show the demo of the logical operations. Run the following program
on your simulator and examine the results.
#include <reg51.h>
void main(void)
P0=~0x55; //inverting
Next program will show the operation on port pins to access data bit-wise and manipulate
through logical operator.
1.2.1 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)
//it to P2.7
We have seen BCD numbers in previous modules. As stated there, many newer
microcontrollers have a real-time clock (RTC) where the time and date are kept, even when
the power is off. Very often the RTC provides the time and date in packed BCD. However, to
display them they must be converted to ASCII. Like this example, we need to convert the
data from one form to another form. In this section we show some example programs to
demo how Embedded C helps for data conversions. Some data conversions needed are listed
below.
Figure.2 shows the ASCII, binary and BCD codes for the digits 0 to 9.
Following program shows Packed BCD to ASCII conversion.
1.3.1 Example.1
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)
x=mybyte&0x0F;
P1=x|0x30;
y=mybyte&0xF0;
y=y>>4;
P2=y|0x30;
1.3.2 Example.2
Write an 8051 C program to convert ASCII digits of ‘4’ and ‘7’ to packed BCD and
display them on P1.
Solution:
#include <reg51.h>
void main(void)
w=w&0x0F;
w=w<<4;
z=z&0x0F;
bcdbyte=w|z;
P1=bcdbyte;
1.3.3 Example.3
Write an 8051 C program to calculate the checksum byte for the data 25H, 62H, 3FH, and
52H.
2. Take the 2’s complement (invert and then add 1) of the total sum. This is the
Solution:
#include <reg51.h>
void main(void)
{
unsigned char x;
for (x=0;x<4;x++)
P2=mydata[x];
sum=sum+mydata[x];
P1=sum;
P1=chksumbyte;
Following program will demo Binary to Decimal and ASCII Conversion in 8051 C
1.3.4 Example.4
Write an 8051 C program to convert 11111101 (FD hex) to decimal and display the digits
on P0, P1 and P2.
Solution:
#include <reg51.h>
void main(void)
binbyte=0xFD;
x=binbyte/10;
d1=binbyte%10;
d2=x%10;
d3=x/10;
P0=d1;
P1=d2;
P2=d3;
Using the code (program) space for predefined data is a widely used option in 8051. We
saw how to use the Assembly language instruction MOVC to access the data stored in the
8051 code space. Here, we see the same concept with 8051 C.
✓ If you declare variables (eg.: char) to store data, C compiler will allocate a RAM
space for these variable.
1. Bank 0 – addresses 0 – 7
2.1.1 Write, compile and single-step the following program on your 8051 simulator.
Examine the contents of the code space to locate the values.
#include <reg51.h>
void main(void)
for (x=0;x<100;x++)
z–;
mydata[x]=z;
P1=z;
While running this program you can see how the data will be stored in an array and
displayed in a port.
One of the new features of the 8052 was an extra 128 bytes of RAM space.
✓ The extra 128 bytes of RAM helps the 8051/52 C compiler to manage its registers and
resources much more effectively.
✓ Based on 8052 architecture, you should use the reg52.h header file. Choose the 8052
option when compiling the program.
2.2.2 Examples 5
Let us compare and contrast the following programs and discuss the advantages and
disadvantages of each one.
Example 5(a):
#include <reg51.h>
void main(void)
P1=“H”;
P1=“E”;
P1=“L”;
P1=“L”;
P1=“O”;
Example 5(b):
#include <reg51.h>
void main(void)
P1 = mydata[z];
Example 5(c):
#include <reg51.h>
void main(void)
unsigned char z;
P1 = mydata[z];
Q. Develop a ‘C’ program to transfer the data from port P0 to port Pl. (2M)
Program:
#include <reg51.h> // contains all the port registers and
internal
void main (void)
{
unsigned char z; // z is allotted a space of 1 byte
for (z=0; z<=170;z++)
Q. Write a C language program to operate port 0 and port 2 as output port and port
1 and port 3 as input port. (4M)
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
unsigned char mybyte;
P1=0xFF; //make P1 input port
P3=0xFF; //make P3 input port
while (1)
{
mybyte=P1; //get a byte from P1
P0= mybyte;
mybyte=P3;
P2= mybyte;
}
}
Q. Write a ‘C’ language program to mask the upper four bits of the data given in port 0
and write the answer in port 1.(4M)
Prog-
#include <reg51.h>
void main( )
unsigned char mybyte;
P0=0xFF;
{
P0=P0&0x0F;
while(1);
mybyte=P1;
}
Q. Write ‘C’ program to generate delay of 50msec for microcontroller
89C51 with crystal frequency of 11.0592 MHz. (4M)
#include<reg51.h>
void Delay()
{
TMOD = 0x01; // Timer0 mode1
TH0 = 0xDC; //initial value for 10ms
TL0 = 0x00;
TR0 = 1; // timer0 start
#include<reg51.h>
void delay(unsigned int);
void main(void)
{
unsigned int x;
for(;;) //repeat forever
{
for(x=0;x<250;x++)
{
P1=x;
delay(100);
}
for(x=250;x>0;x–)
{
P1=x;
delay(100);
}
}
}
✓ Transfer data one bit a time and control the sequence of data and spaces in between
them.
In many new generations of devices such as LCD, ADC, and ROM, the serial versions are
becoming popular since they take less space on a PCB.
The following are examples that demonstrate data serialization using embedded
C. Example. 6
Write a C program to send out the value 44H serially one bit at a time via P1.0. The LSB
should go out first.
Solution :
#include <reg51.h>
sbit P1b0=P1^0;
sbit regALSB=ACC^0;
void main(void)
unsigned char x;
ACC=conbyte;
for (x=0;x<8;x++)
P1b0=regALSB;
ACC=ACC>>1;
2.3.1 Write a C program to bring in a byte of data serially one bit at a time via P1.0. The
MSB should come in first.
Example.7
#include <reg51.h>
sbit P1b0=P1^0;
sbit regALSB=ACC^0;
bit membit;
void main(void)
unsigned char x;
for (x=0;x<8;x++)
membit=P1b0;
ACC=ACC<<1;
regALSB=membit;
P2=ACC;
Solution:
#include <reg51.h>
sbit MYBIT=P1^0;
void main(void)
{
unsigned int z;
for (z=0;z<=50000;z++)
MYBIT=0;
MYBIT=1;
Fig .3
Among 8 bits, four bits are for timer 1 and the remaining four bits are for
timer 0. The bits of timer 0 and timer 1 are identical to each other.
Gate: Gate means enable hardware control. The timer should run or
stop. If the gate is equal to one then counting is controlled by
external Interrupt (0 or 1) using a hardware pin. If the gate is zero
then it is independent of external Interrupt. By default, the gate is
one.
C/T: If this bit is equal to one then it acts as a counter or else timer.
M1, M0: Decides the mode of the timer.
00: Mode 0
01: Mode 1
10: Mode 2
11: Mode 3
Timer Modes
5. Time Delay
There are two ways to create a time delay in 8051 C : (i) using
the 8051 timer and (ii) using a simple for-loop. When using a loop
to create the time delay, there are three factors that can affect
the accuracy of the time delay. They are: (i) Crystal frequency of
the 8051 system, (ii) 8051 machine cycle timing and (iii) Compiler
used for 8051 C.
Solution:
#include <reg51.h>
void main(void)
unsigned int x;
p1=0x55;
p1=0xAA;
for (x=0;x<40000;x++);
}
}
Solution:
#include <reg51.h>
void main(void)
p1=0x55;
MSDelay(250);
p1=0xAA;
MSDelay(250);
for (i=0;i<itime;i++)
for (j=0;j<1275;j++);
}
The operating modes of the 8051 can be changed by
manipulating the values of the 8051’s Special Function Registers
(SFRs). SFRs are accessed as if they were normal Internal RAM.
The only difference is that Internal RAM is from address 00h
through 7Fh whereas SFR registers exist in the address range of
80h through FFh.Each SFR has an address (80h through FFh) and
a name.
Write an 8051 C program to toggle all the bits of P0, P1, and P2
continuously with a 250 ms delay. Use the sfr keyword to declare
the port addresses.
Solution:
sfr P0=0x80;
sfr P1=0x90;
sfr P2=0xA0;
void main(void)
while (1)
P0=0x55;
P1=0x55;
P2=0x55;
MSDelay(250);
P0=0xAA;
P1=0xAA;
P2=0xAA;
MSDelay(250);
Example 1:
Write an 8051 C program to toggle only bit P1.5 continuously every 50ms. Use
Timer 0, mode1 (16-bit) to create the delay.
Solution:
#include <reg51.h>
Void T0MDelay (void):
Sbit mybit = P1^5;
Void main (void)
{
While (1)
{
mybit= ̴mybit; // toggle P1.5
T0M1Delay (); // Timer 0, mode 1 (16-bit)
}
}
Tested for AT89C51, XTAL=11.0592 MHz, using the Proview 32 compiler.
Void T0M1Delay (void)
{
TMOD=0x01; // Timer 0, mode 1 (16-bit)
TMOD=0xFD; // load TL0
TMOD=0x4B; // load TH0
TR0=1; // turn on T0
While (TF0==0); // wait for TF0 to roll over
TR0=0; // turn off T0
TF0=0; // clear TF0
}
Example 2:
Write an 8051 C program to toggle all bits of P2 continuously every 500ms. Use
Timer 1, mode1 to create the delay.
Solution:
// tested for DS89C420, XTAL=11.0592 MHz, using the Proview 32 compiler.
#include <reg51.h>
Void T1MDelay (void):
Void main (void)
{
Unsigned char x;
P2=0x55;
While (1)
{
P2= ̴P2;
For (x=0; x<=20; x++)
T1M1Delay ();
}
}
Void T1M1Delay (void)
{
TMOD=0x10; // Timer 1, mode 1 (16-bit)
TL1=0xFE; // load TL1
TH1=0xA5; // load TH1
TR1=1; // turn on T1
While (TF1==0); // wait for TF1 to roll over
TR1=0; // turn off T1
TF1=0; // clear TF1
}
A5FEH=42494 in decimal
65536-42494=23042
23042x 1.085µs=25ms and 20x 25 ms=500ms
Timers 0 & 1 delay using mode 1 (8-bit auto-reload):
Example 1:
Write an 8051 C program to toggle only bit P1.5 continuously every 250ms. Use
Timer 0, mode2 (8-bit auto-reload) to create the delay.
Solution:
// tested for DS89C420, XTAL=11.0592 MHz, using the Proview 32 compiler.
#include <reg51.h>
Void T0M2Delay (void):
Sbit mybit = P1^5;
Void main (void)
{
Unsigned char x, y;
While (1)
{
mybit= ̴mybit; // toggle P1.5
for (x=0; x=250; x++) // due to for loop overhead
for (y=0; y=36; y++) // we put 36 and not 40
T0M2Delay ();
}
}
Void T0M2Delay (void)
{
TMOD=0x02; // Timer 0, mode 2 (8-bit auto-related)
TH0=-23; // load TH0 (auto-reload value)
TR0=1; // turn on T0
While (TF0==0); // wait for TF0 to roll over
TR0=0; // turn off T0
TF0=0; // clear TF0
}
256-23=233
23x1.085 µs=25 µs
25 µs x 250 x 40=250 ms by calculation.
However, the scope output does not give us this result. This is due to
overhead of the ‘for loop’ in C. to correct this problem, put 36 instead of 40.
Example 2:
Write an 8051 C program to toggle only bit P1.5 continuously every 250ms. Use
Timer 0, mode2 (8-bit auto-reload) to create the delay.
Solution:
// tested for DS89C420, XTAL=11.0592 MHz, using the Proview 32 compiler.
#include <reg51.h>
Void T1M2Delay (void):
Sbit mybit = P2^7;
Void main (void)
{
Unsigned char x;
While (1)
{
mybit= ̴mybit; // toggle P2.7
T1M2Delay ();
}
}
Void T1M2Delay (void)
{
TMOD=0x20; // Timer 1, mode 2 (8-bit auto-related)
TH1=-184; // load TH1 (auto-reload value)
TR1=1; // turn on T1
While (TF1==0); // wait for TF1 to roll over
TR1=0; // turn off T1
TF1=0; // clear TF1
}
}
1. Write a Program to read the number 1 from port 1, number 2 from port 2 , then add
them ,store the result ,send it to Port 3.
#include<reg.51.h>
void main()
{
unsigned char a,b,c ;
P1 = 0XFF ; //make port 1 as input port
P2 = 0XFF ; //make port 2 as input port
a=P1;
b=P2;
c= a+b ;
P3= c;
}
2. Write a program to Turn on and off the LED with some delay.
#include<reg51.h>
sbit LED=P1.1;
void delay(void);
void main(void)
{
while(1)
{
LED=1;
delay();
LED=0;
delay();
}
}
void delay(void)
{
unsigned char i,k;
for(i=0;i<70;i++)
for(k=0;k<255;k++);
}
3. Write a program to transfer the data from port P0 to port P1.
#include<reg51.h>
void main (void )
{
unsigned char X;
P0=0XFF; // P0 as input port
P1=0X00; // P1 as output port
while(1)
{
X = P0; // read port0
P1 = X; // output data to port1
}
Example 1
Example 2
Solution:
#include <reg51.h>
Example 3
Program the 8051 in C to receive bytes of data serially and put
them in P1. Set the baud rate at 4800; use 8-bit data, and 1 stop
bit.
#include <reg51.h>
void main(void){
unsigned char mybyte;
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFA; //4800 baud rate
SCON=0x50;
TR1=1; //start timer
while (1) { //repeat forever
while (RI==0); //wait to receive
mybyte=SBUF; //save value
P1=mybyte; //write value to port
RI=0;
}
}
Example 4
Solution:
#include <reg51.h>
Example 5
Write a C program for the DS89C4x0 to transfer the letter “A”
serially at 4800 baud continuously. Use the second serial port
with 8-bit data and 1 stop bit. (note: We can only use Timer 1 to
set the baud rate).
Solution:
#include <reg51.h>
sfr SBUF1=0xC1;
sfr SCON1=0xC0;
sbit TI1=0xC1;
void main(void){
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFA; //4800 baud rate
SCON1=0x50; //use 2nd serial port SCON1
TR1=1; //start timer
while (1) {
SBUF1=‘A’; //use 2nd serial port SBUF1
while (TI1==0); //wait for transmit
TI1=0;
}}
Example 6
Solution:
#include <reg51.h>
sfr SBUF1=0xC1;
sfr SCON1=0xC0;
sbit RI1=0xC0;
void main(void){
unsigned char mybyte;
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFD; //9600 baud rate
SCON1=0x50; //use 2nd serial port SCON1
TR1=1; //start timer
while (1) {
while (RI1==0); //monitor RI1
Solution:
void main()
{
Switch=1;
IE=0x81;
While(1)
{
P2=“y”;
}
}
The TCON register holds four of the interrupt flags in the 8051.
The interrupt flag bits for 8051 are shown in Table 4. The SCON
register has the RI and TI flags.
Example 4 shown below gives the C program to receive data
serially and send it to P0.
Example 4
Solution:
void main()
{
unsigned char x;
P1=0xFF; //make P1 an input
TMOD=0x22;
TH1=0xF6; //4800 baud rate
SCON=0x50;
TH0=0xA4; //5 kHz has T=200us
Example 5
#include <reg51.h>
sbit WAVE =P2^1;
Unsigned char cnt;
void timer0() interrupt 1
{
WAVE=~WAVE; //toggle pin
}
void timer1() interrupt 3
{
cnt++; //increment counter
P0=cnt; //display value on pins
}
void main()
{
cnt=0; //set counter to 0
TMOD=0x42;
TH0=0x-46; //10 KHz
IE=0x86; //enable interrupts
TR0=1; //start timer 0
while (1); //wait until interrupted
Write C language program to toggle all bits of P0, P1, P2 and P3 ports continuously
with certain delay.
#include <reg51.h>
void main(void)
{
unsigned char text[ ] = “MSBTE”; //initialize array
TMOD = 0x20; //Initialize timer 1 in mode 2
TH1 = 0xFD; //baud rate 9600
SCON = 0x50; //start serial communication ( 8bit , 1 stop bit , REN )
TR1 = 1; //start timer 1
#include< regx51.h>
void delay();
void main()
{
int x;
for (x=0;x,13;x++)
{
P0=0x33;
delay(10);
P0=0x66;
delay(10);
P0=0xcc
delay(10);
P0=0x99;
delay(10);
}
}
void delay(unsigned int t)
{
unsigned int x,y;
for(x=0;x<=t;x++)
for(y=0;y<=1275;y++);
}
Write a 89C51 C program to display ‘WELCOME’ on 16 × 2
LCD display
#include reg51.h
//LCD
sbit rs = P3^0; //register select pin
sbit rw = P3^1; //read write pin
sbit e = P3^2; //enable pin
int i,j ;
for(i=0;i<time;i++)
for(j=0;j<1275;j++);
{
P2 = item;
rs= 0;
rw=0;
e=1;
delay(1);
e=0;
return;
}
P2 = item;
rs= 1;
rw=0;
e=1;
delay(1);
e=0;
return;
}
void main()
{
lcdcmd(0x0E); //turn display ON for cursor blinking
lcdcmd(0x01); //clear screen
lcdcmd(0x06); //display ON
lcddata('H');
lcddata('E');
lcddata('L');
lcddata('L');
lcddata('O');
lcddata('!');