Tuesday, December 27, 2011

Data conversion in 8051 C


Packed BCD to ASCII

What to do??
Say number be 28
First separate 2 to get 02.
Second separate 8 to get 08.
Now add 30 to both to get 32 and 38 respectively.
Hence these are our ascii values.
#include<reg51.h>
void main()
{
                unsigned char x,y,z;
                unsigned char bytemy = 0x28;
                x = mybyte & 0x0F;     //mask lower 4 bits
                P1 = x | 0x30;         //make it ascii
                y = mybyte & 0xF0;     //mask upper 4 bits
                y = y >> 4;            //shift it to lower 4 bits
                P2 = y | 0x30;         //make it ascii
}// end of main
end of program

ASCII to Packed BCD.

What to do??
Say we have 2 ascii numbers 02 and 08.
We need to get say 28.
So shift 02 to 20.
Add 08 to it.
Hence this is our packed BCD.
#include<reg51.h>
void main()
{
                unsigned char myBCD;
                unsigned char x = '2',y='8';
                x = x & 0x0F;       //mask lower 4 bits just in case.
                x = x << 4;            //shift 4 left to make it upper digit
                y = y & 0x0F;       //just in case
                myBCD = x | y;  //combine to make BCD
                P1 = myBCD;
}// end of main
// end of program

Logic operations in 8051 C

Everyone must be familiar with AND(&&), OR(||) and NOT(!) operators in C. well there are also bitwise logical operators also known as AND(&), OR(|), EX-OR(^), Inverter(~), shift right(>>) and shift left(<<).
These bit wise operators are widely used in embedded systems and control.

Bit wise logic operators for C
A
B
A & B
A | B
A ^ B
Y = ~B
0
0
0
0
0
1
0
1
0
1
1
0
1
0
0
1
1

1
1
1
1
0


Used as:
ANDing
0x35 & 0x45 = 0x05
ORing
0x35 | 0x45 = 0x75
XORing
0x35 ^ 0x45 = 0x70
INVERTing
~0x35 = 0xCA

Usage of bit wise shift operation:
Data>>number of bits to be shifted right
Data<<number of bits to be shifted left
0x50>>4 = 0x05
0x45<<2 = 0xB4

An example of logic operation can be seen below.

#include<reg51.h>
/*
 * issue ascii char to P2 as follows
 * P3.1                   P3.0
 * 0                         0              send 0
 * 0                         1              send 1
 * 1                         0              send 2
 * 1                         1              send 3
 *
 */
void main()
{
                unsigned char z;
                z = P1;   //read P1
                z = z & 0x03;
                // mask the unused bits
                switch(z)
                {
                                case(0): P2 = '0';
                                                 break;
                                case(1): P2 = '1';
                                                 break;
                                case(2): P2 = '2';
                                                 break;
                                case(3): P2 = '3';
                                                 break;

                }// end of switch
}// end of main
// end of program

INPUT/OUTPUT programming in 8051 C

Ports 0-3 are both byte accessible and bit accessible. So below are few examples to see how to use byte accessible property of ports.
#include<reg51.h>
/*
 * program to get byte from P1
 * and send it to P2
 * after 1/2 second delay
 */
void msdelay(unsigned int x)
{
                unsigned int i,j; //loop variables
                for(i = 0; i<x; i++)
                                for(j = 0;j<1275; j++);
}//end of msdelay()
void main()
{
                unsigned char mybyte;
                P1 = 0xFF; //make P1 input
                while(true)
                {
                                mybyte = P1; //get byte from P1
                                msdelay(500);
                                P2 = mybyte;
                }// end of while
}// end of main
// end of program

#include<reg51.h>
/*
 * increment LED's connected on
 * Port 2
 *
 */
#define LED P2;
// we can also define P2 as shown above
void main()
{
                LED = 0; //clear P2
                while(true)
                {
                                LED++;
                }// end of while
}// end of main
// end of program

Bit addressable I/O programming
As Port 0-3 are bit addressable too so here are few example to see how we can use it.
There are few things to see. In reg51.h we can use ports bit in format Px^y, where x is port number and y is bit number.
Also we need to use sbit data type to use bits of ports.

#include<reg51.h>
/*
 * toggling bit P2.4 without
 * disturbing other P2 bits
 *
 */
void msdelay(unsigned int x)
{
                unsigned int i,j; //loop variables
                for(i = 0; i<x; i++)
                                for(j = 0;j<1275; j++);
}//end of msdelay()
sbit mybit = P2^4;
//this is how we do it
void main()
{
                while(true)
                {
                                mybit = 1;//turn on
                                msdelay(somedelay);
                                mybit = 0;//turn off
                }// end of while
}// end of main
// end of program

#include<reg51.h>
/*
 * door sensor connected to P1.1
 * buzzer connected to P1.7
 * when door sensor open sound buzzer
 * by sending pulse of few hundered hz
 *
 */
void msdelay(unsigned int x)
{
                unsigned int i,j; //loop variables
                for(i = 0; i<x; i++)
                                for(j = 0;j<1275; j++);
}//end of msdelay()
sbit dsensor = P1^1;
sbit buzzer = P1^7;
// this is how we do it
void main()
{
                dsensor = 1; // make it input
                while(dsensor == 1)// check
                {
                                buzzer = 0;
                                msdelay(300);
                                buzzer = 1;
                                msdelay(300);
                }// end of while
}// end of main
// end of program

Accessing SFR address 80 – FFh
Another way to access ports through bits or bytes is through their RAM address. These RAM address can be accessed by using sfr datat type of reg51.h. See table below for addresses.

Port  0
Address
P0.0
80h
P0.1
81h
P0.2
82h
P0.3
83h
P0.4
84h
P0.5
85h
P0.6
86h
P0.7
87h

Port 1
Address
P1.0
90h
P1.1
91h
P1.2
92h
P1.3
93h
P1.4
94h
P1.5
95h
P1.6
96h
P1.7
97h
P1.8
Okay there is no P1.8.

Port 2
Address
P2.0
A0h
P2.1
A1h
P2.2
A2h
P2.3
A3h
P2.4
A4h
P2.5
A5h
P2.6
A6h
P2.7
A7h

Port 3
Address
P3.0
B0h
P3.1
B1h
P3.2
B2h
P3.3
B3h
P3.4
B4h
P3.5
B5h
P3.6
B6h
P3.7
B7h

Few program demonstrating usage.
#include<reg51.h>
/*
 * toggle ports P0,P1,P2
 * continuously with 250ms delay
 *
 */
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
// see how address are initailized using sfr keyword
void msdelay(unsigned int x)
{
                unsigned int i,j; //loop variables
                for(i = 0; i<x; i++)
                                for(j = 0;j<1275; j++);
}//end of msdelay()
void main()
{
                while(true)
                {
                                P0 = 0x55;
                                P1 = 0x55;
                                P2 = 0x55;
                                msdelay(250);
                                P0 = 0xAA;
                                P1 = 0xAA;
                                P2 = 0xAA;
                                msdelay(250);
                }// end of while
}// end of main
// end of program

#include<reg51.h>
/*
 * program to toggle P2.1 on and off
 * for some time
 *
 */
sbit mybit = 0xA1;
one more way to decalare P2^1
void main()
{
                unsigned int z;
                for(z = 0;z< sometime; z++)
                {
                                mybit = 0;
                                mybit = 1;
                }// end of for loop
}// end of main
// end of program

This is all I could think off. Rest I will explain as it comes.