১৯. 8051 এর সাথে বিভিন্ন ধরনের ডিভাইসের ইন্টারফেস
এই পোস্টে আমরা শুধু 8051 মাইক্রোকন্ট্রোলারের সাথে বিভিন্ন ধরনের ডিভাইসের ইন্টারফেস দেখব। যেমন - ম্যাট্রিক্স কিপ্যাড, সার্ভো মোটর, ডিসি মোটরের স্পিড কন্ট্রোল, রিলে ইন্টারফেস ইত্যাদি। এই পোস্টটি পরবর্তীতে আরও আপডেট করা হবে এবং আরও ডিভাইসের ইন্টারফেস এপিক 8051 মাইক্রোকন্ট্রোলার দিয়ে আমরা করব। প্রত্যেকটি কোডেই কমেন্ট করে বলে দেয়া হয়েছে কোন লাইনের লজিক কি?? তারপরও আমরা বেসিক থিওরি বুঝে না থাকলে পরবর্তী কোন পোস্টে সেগুলো সম্পর্কে দেখে নিব। শুধু কোড এবং সার্কিট দিয়েই এই পোস্টটি শেষ করব আমরা।
8051 মাইক্রোকন্ট্রোলারের সাথে রিলে ইন্টারফেসঃ
মাইক্রোকন্ট্রোলারের সাথে রিলে ইন্টারফেসের মাধ্যমে আমরা এসি লাইন কন্ট্রোল করতে পারি মাইক্রোকন্ট্রোলার দিয়েই। নিচে 8051 মাইক্রোকন্ট্রোলারের সাথে রিলে ইন্টারফেসের কোড এবং সার্কিট টি দেখে নেয়া যাক
#include<reg52.h>
sbit relay_pin = P2^0; //declare P2.0 as relay control pin
sbit input_pin = P1^0; //declare P1.0 as input pin
void main()
{
input_pin = 1; //make the input pin as high
relay_pin = 1; //make the relay pin as high, as we control it by pnp transistor
while(1)
{
if(input_pin == 1) //check the input pin whether it low or high
{
relay_pin = ~input_pin; //if high then low the relay pin
}
else
relay_pin = ~input_pin; //if low then high the relay pin
}
}
সার্কিটঃ
8051 মাইক্রোকন্ট্রোলারের সাথে ম্যাট্রিক্স কি-প্যাড ইন্টারফেসঃ
ম্যাট্রিক্স-কিপ্যাড হল অনেকগুলো পুশ-বাটনের সমষ্টি। সারি এবং কলাম করে সংযুক্ত থাকে। মাইক্রোকন্ট্রোলারের ইনপুট/আউটপুট পিনের মাধ্যমে এই সারি এবং কলামের ভোল্টেজ লেভেল রিড করার মাধ্যমে কোন বাটন টিপা হয়েছে তা বুঝা যায়। নিচের কোডটি এরকম একটি ম্যাট্রিক্স কিপ্যাড রিড করে LCD স্ক্রিনে সেটার মান দেখানোর কোড। এরকম ভাবে কেউ ইচ্ছা করলে এটা দিয়ে ক্যালকুলেটরও বানাতে পারবে। তাহলে কোড এবং সার্কিটটি দেখে নেয়া যাক।
#include<reg52.h> //header file for at89s52 mcu
#include<intrins.h> //header file for _nop_() function
#define LCD_register P2 //make port2 data byte of LCD
sbit EN = P0^1; //enable pin of LCD,this pin act as output pin of 8051
sbit RS = P0^0; //register select pin of LCD,this pin act as output pin of 8051
sbit C1 = P1^0; //coloum1 pin of keypad
sbit C2 = P1^1; //coloum2 pin of keypad
sbit C3 = P1^2; //coloum3 pin of keypad
sbit C4 = P1^3; //coloum4 pin of keypad
sbit R1 = P1^4; //row1 pin of keypad
sbit R2 = P1^5; //row2 pin of keypad
sbit R3 = P1^6; //row3 pin of keypad
sbit R4 = P1^7; //row4 pin of keypad
unsigned char button; //declare a global variable to hold the keypad button data
void delay_uS(unsigned int t) //pass value to get desired microsecond delay
{
while((t--) > 0)
{
_nop_(); //doing nothing one machine cycle
}
}
void send_cmd(unsigned char cmd)
{
LCD_register = cmd; //put command code in LCD_register pin which act as data pin
RS = 0; //keep RS high for selecting data register
EN = 1; //keep high EN pin of lcd for minimum 490 nano second
delay_uS(10); //we keep this action for 10 micrpseconds
EN = 0; //clear this EN pin
}
void send_data(unsigned char dt)
{
LCD_register = dt; //put data code in LCD_register pin which act as data pin
RS = 1; //keep RS high for selecting data register
EN = 1; //keep high EN pin of lcd for minimum 490 nano second
delay_uS(10); //we keep this action for 10 microseconds
EN = 0; //clear this EN pin
}
void init_LCD()
{
send_cmd(0x38); //use 8bit,two lines & 5x7 matrix
delay_uS(1000); //delay 1 milliseconds after sending data byte
send_cmd(0x0C); //Display on,Cursor Off
delay_uS(1000); //delay 1 milliseconds after sending data byte
send_cmd(0x01); //clearing the screen
delay_uS(1000); //delay 1 milliseconds after sending data byte
send_cmd(0x80); //cursor return at home
delay_uS(1000); //delay 1 milliseconds after sending data byte
}
char row_for_first_coloumn()
{
R1=R2=R3=R4 = 1; //make Row pins high
C1=C2=C3=C4 = 0; //make coloumn pins low
if(R1 == 0) //check whether first row is low or high
{
button = '1'; //if low then put '1' in button variable so that it can be returned from this func
}
else if(R2 == 0) //check whether second row is low or high
{
button = '4';
}
else if(R3 == 0) //check whether third row is low or high
{
button = '7';
}
else if(R4 == 0) //check whether forth row is low or high
{
button = '*';
}
return button; //return the button variable
}
char row_for_second_coloumn()
{
R1=R2=R3=R4 = 1; //make Row pins high
C1=C2=C3=C4 = 0; //make coloumn pins low
if(R1 == 0) //check whether first row pin is low or high
{
button = '2'; //if low then put '1' in button variable so that it can be returned from this func
}
else if(R2 == 0) //check whether second row pin is low or high
{
button = '5';
}
else if(R3 == 0) //check whether third row pin is low or high
{
button = '8';
}
else if(R4 == 0) //check whether fourth row pin is low or high
{
button = '0';
}
return button;
}
char row_for_third_coloumn()
{
R1=R2=R3=R4 = 1; //make Row pins high
C1=C2=C3=C4 = 0; //make coloumn pins low
if(R1 == 0) //check whether first row pin is low or high
{
button = '3';
}
else if(R2 == 0) //check whether second row pin is low or high
{
button = '6';
}
else if(R3 == 0) //check whether third row pin is low or high
{
button = '9';
}
else if(R4 == 0) //check whether fourth row pin is low or high
{
button = '#';
}
return button;
}
char row_for_fourth_coloumn()
{
R1=R2=R3=R4 = 1; //make Row pins high
C1=C2=C3=C4 = 0; //make coloumn pins low
if(R1 == 0) //check whether first row pin is low or high
{
button = 'A';
}
else if(R2 == 0) //check whether second row pin is low or high
{
button = 'B';
}
else if(R3 == 0) //check whether third row pin is low or high
{
button = 'C';
}
else if(R4 == 0) //check whether fourth row pin is low or high
{
button = 'D';
}
return button;
}
void main()
{
unsigned char character; //declare a variable to hold the data of keypad
init_LCD(); //initialize the LCD funtion very begining
while(1)
{
C1=C2=C3=C4= 1; //make coloumn pin high
R1=R2=R3=R4= 0; //make row pin low
if(C1 == 0) //if coloumn pin 1 is low then do these stuff
{
character = row_for_first_coloumn();
send_data(character);
}
else if(C2 == 0) //if coloumn pin 2 is low then do these stuff
{
character = row_for_second_coloumn();
send_data(character);
}
else if(C3 == 0) //if coloumn pin 3 is low then do these stuff
{
character = row_for_third_coloumn();
send_data(character);
}
else if(C4 == 0) //if coloumn pin 4 is low then do these stuff
{
character = row_for_fourth_coloumn();
send_data(character);
}
delay_uS(50); //delay a little bit
send_cmd(0x80); //put th e cursor on home position
}
}
সার্কিটঃ
8051 মাইক্রোকন্ট্রোলারের সাথে সেভেন সেগমেন্ট ডিসপ্লে ইন্টারফেসঃ
সেভেন সেগমেন্ট ডিসপ্লে সাধারণত বিভিন্ন ধরনের মান দেখতে এমন ধরনের প্রজেক্টে ব্যবহৃত হয়। এটা সাধারণত কমন অ্যানোড এবং কমন ক্যাথোড কনফিগারেশনের হয়ে থাকে। আমরা কোডে দুই ধরনের মডেলের অপারেশনই দেখতে পাব। তাহলে নিচে কোড এবং সার্কিটটি দেখে নেয়া যাক।
#include <reg52.h>
#define common_cathod_port P2 //declare PORT 2 for common cathod segment
#define common_anode_port P3 //declare PORT 3 for common anode segment
void delay_ms(unsigned int t) //this function just count some number to create a delay
{
unsigned int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<100;j++);
}
}
/*
_______________________________________________________________
for common anode configuration|for common cathod configuration|
------------------------------|-------------------------------|
hex binary digit |hex binary digit |
----------------------------- |-------------------------------|
0xC0 11000000 0 |0x3F 00111111 0 |
0xF9 11111001 1 |0x06 00000110 1 |
0xA4 10100100 2 |0x5B 01011011 2 |
0xB0 10110000 3 |0x4F 01001111 3 |
0x99 10011001 4 |0x66 01100110 4 |
0x92 10010010 5 |0x6D 01101101 5 |
0x82 10000010 6 |0x7D 01111101 6 |
0xF8 11111000 7 |0x07 00000111 7 |
0x80 10000000 8 |0x7F 01111111 8 |
0x90 10010000 9 |0x6F 01101111 9 |
--------------------------------------------------------------|
*/
void main()
{
char common_anode[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //for common anode
char common_cathod[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //for common cathod
common_anode_port = 0xC0; //at first show digit 0
common_cathod_port = 0x3F; //at first show digit 0
while(1)
{
unsigned char i; //declare a variable to repeate loop
for(i=0;i<10;i++)
{
common_anode_port = common_anode[i]; //pass the index number to show digit
delay_ms(1000);
}
for(i=0;i<10;i++)
{
common_cathod_port = common_cathod[i]; //pass the index number to show digit
delay_ms(1000);
}
}
}
#include <reg52.h>
#define common_cathod_port P2 //declare PORT 2 for common cathod segment
#define common_anode_port P3 //declare PORT 3 for common anode segment
void delay_ms(unsigned int t) //this function just count some number to create a delay
{
unsigned int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<100;j++);
}
}
/*
_______________________________________________________________
for common anode configuration|for common cathod configuration|
------------------------------|-------------------------------|
hex binary digit |hex binary digit |
----------------------------- |-------------------------------|
0xC0 11000000 0 |0x3F 00111111 0 |
0xF9 11111001 1 |0x06 00000110 1 |
0xA4 10100100 2 |0x5B 01011011 2 |
0xB0 10110000 3 |0x4F 01001111 3 |
0x99 10011001 4 |0x66 01100110 4 |
0x92 10010010 5 |0x6D 01101101 5 |
0x82 10000010 6 |0x7D 01111101 6 |
0xF8 11111000 7 |0x07 00000111 7 |
0x80 10000000 8 |0x7F 01111111 8 |
0x90 10010000 9 |0x6F 01101111 9 |
--------------------------------------------------------------|
*/
void main()
{
char common_anode[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //for common anode
char common_cathod[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //for common cathod
common_anode_port = 0xC0; //at first show digit 0
common_cathod_port = 0x3F; //at first show digit 0
while(1)
{
unsigned char i; //declare a variable to repeate loop
for(i=0;i<10;i++)
{
common_anode_port = common_anode[i]; //pass the index number to show digit
delay_ms(1000);
}
for(i=0;i<10;i++)
{
common_cathod_port = common_cathod[i]; //pass the index number to show digit
delay_ms(1000);
}
}
}
সার্কিটঃ
8051 মাইক্রোকন্ট্রোলারের মাধ্যমে ডিসি মোটরের স্পীড কন্ট্রোলঃ
মাইক্রোকন্ট্রোলারের মাধ্যমে ডিসি মোটরের স্পীড কন্ট্রোল সাধারণত PWM টেকনিকের মাধ্যমে করা হয়। অনেক আধুনিক মাইক্রোকন্ট্রোলারের টাইমার পেরিফেরালসে্র সাথেই PWM জেনারেট করার কিছু ফিচার থাকে। কিন্তু 8051 অনেক আগের মাইক্রোকন্ট্রোলার হওয়ায় টাইমারের যথাযথ ব্যবহারের মাধ্যমেই ডিসি মোটরের স্পীড কন্ট্রোল করা হয়ে থাকে। টাইমার পেরিফেরালস্ ভালোভাবে বুঝে থাকলে জাস্ট কোড দেখলেই বিষয়টা বোঝা যাবে বলে আশা করি।
কোড এবং সার্কিট নিচে দেয়া হল।
#include<reg52.h> //header file for at89s52 mcu
sbit motor_pin_a = P2^0; //declare the direction pin of motor driver ic
sbit motor_pin_b = P2^1; //declare the direction pin of motor driver ic
sbit motor_speed = P2^2; //declare the pwm or enable pin of motor driver ic
bit pwm_flag = 0; //variable that remember whether the pwm pin is high or low
unsigned char pwm_width; //pulse width variable,holds the value from 0-255,0 means stop,255 means full speed
/*
|-------------| |-----------| |--------
| | | | |
| | | | |
| | | | |
----------| |------------------| |--------------------|
<----t_on-----><-----t_off-------><---t_on--> <-------t_off------>
<-------------period------------><-------------period------------>
duty_cycle = t_on / (t_on + t_off)
1 period = t_on + t_off
*/
void delay(unsigned int t) //approximate delay function to differentiate the operation
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<100;j++);
}
void init_timer() //timer 0 initialize function, for pwm control
{
TMOD = 0x00; //start on mode-0
pwm_width = 100; //set base pwm 100
ET0 = 1; //set timer0 interrupt
EA = 1; //set global interrupt enable bit
TR0 = 1; //start the timer0
}
void motor_run(unsigned char speed,char direction) //function that calls the direction and speed of motor
{
switch(direction) //check for direciton
{
case 0: //0 means counter-clockwise
motor_pin_a = 0; //controls the direction of motor
motor_pin_b = 1; //controls the direction of motor
pwm_width = speed; //put the global variable so that interrput can take care of it
break;
case 1: //1 means clock wise according to the connection
motor_pin_a = 1; //controls the direction of motor
motor_pin_b = 0; //controls the direction of motor
pwm_width = speed; //put the global variable so that interrput can take care of it
break;
}
}
void main()
{
motor_pin_a = 0; //declare the motor direction pin as output
motor_pin_b = 0; //declare the motor direction pin as output
motor_speed = 0; //declare the motor pwm pin as output
init_timer(); //initialize the timer
while(1)
{
motor_run(100,1); //set the motor speed and direction by function
delay(3000); //approximate delay to understand the action
motor_run(200,0); //set the motor speed and direction by function
delay(3000); //approximate delay to understand the action
}
}
void timer_0() interrupt 1 //this is the main part, interrupt part takes care the pwm pin
{
if(!pwm_flag) //check whether the pin is high or low
{
pwm_flag = 1; //if low make the flag high
motor_speed = 1; //make the pwm pin high
TH0 = 255- pwm_width; //set the time for being high
TF0 = 0; //clear the flag bit of over-flow
}
else
{
pwm_flag = 0; //if high make the flag low
motor_speed = 0; //make the pwm pin low
TH0 = pwm_width; //set the time for being low
TF0 = 0; //clear the flag bit of overflow
}
}
সার্কিটঃ
8051 মাইক্রোকন্ট্রোলারের সাথে সার্ভো মোটর ইন্টারফেসঃ
সার্ভো মোটর হল এক বিশেষ ধরনের মোটর যা pulse width দিয়ে কন্ট্রোল করা হয়। সাধারণত ১ মিলিসেকেন্ডের পালসে্ এটি ০ডিগ্রী , ১.৫ মিলিসেকেন্ডের পালসে্ এটি ৯০ ডিগ্রী এবং ২ সেকেন্ডের পালসে্ এটি ১৮০ ডিগ্রী পর্যন্ত ঘুরে থাকে। যেহেতু এটি পালস ছাড়া কন্ট্রোল করা যায়না , সেহেতু এটি চালাতে মাইক্রোকন্ট্রোলার অপরিহার্য। তবে আধুনিক মাইক্রোকন্ট্রোলার অপেক্ষা 8051 দিয়ে সার্ভো কন্ট্রোল তুলনামূলক ভাবে কঠিন। সার্ভো মোটরের ওয়ার্কিং প্রিন্সিপাল না জেনে থাকলে কোড বোঝা একটু কঠিন হয়ে যাবে। এজন্যে আগে সার্ভো মোটরের ওয়ার্কিং প্রিন্সিপাল সম্পর্কে জেনে নেয়া ভালো হবে। নিচে কোড এবং সার্কিট দেখে নেয়া যাক।
#include<reg52.h> //header file for at89s52 mcu
#include<intrins.h>
sbit servo_pin = P2^0; //set P2.0 pin as servo pin
/* 0degree 90degree 180degree
|------| |---------| |------------|
| | | | | |
| | | | | |
-------| |--------------| |-----------| |---------
<-1ms-> <----19ms----> <-1.5ms-> <--18.5ms--><----2ms---> <--18ms->
some servos varies these signals from 600 microseconds to 2400 microseconds
angle of servo is not exact due to some extra machine cycles in c code.the argument
of servo_delay() function is to be adjusted watching the signal in oscilloscope.
*/
void delay(unsigned int t) //approximate delay function for watch every action perfectly
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<100;j++);
}
void servo_delay(unsigned int time) //use timer0 for servo pulse,pass pulse as argument
{
TH0 = 0xFF - (time>>8)&0xFF; //put the upper byte of the argument into TH0 register
TL0 = 0xFF - time&0xFF; //put the lower byte of the argument into TL0 register
TR0 = 1; //start ticking of timer0 peripheral
while(TF0 == 0); //wait for overflow
TF0 = 0; //clear the flag bit
TR0 = 0; //stop the timer
}
void main()
{
servo_pin = 0; //make the servo pin as output
TMOD = 0x01; //start the timer0 in mode 1
while(1) //never ending loop
{
servo_pin = 1; //make the servo pin high
servo_delay(1000); //keep the pin high for 1000 microseconds (0 degree)
servo_pin = 0; //make the servo pin low
servo_delay(19000); //keep the pin low for 19000 microseconds
delay(2000); //this delay just hold the position for a little bit of times
servo_pin = 1; //make the servo pin high
servo_delay(1500); //keep the pin high for 1500 microseconds (90 degrees)
servo_pin = 0; //make the servo pin low
servo_delay(18500); //keep the pin low for 18500 microseconds
delay(2000); //this delay just hold the position for a little bit of times
servo_pin = 1; //make the servo pin high
servo_delay(2000); //keep the pin high for 2000 microseconds (180 degrees)
servo_pin = 0; //make the servo pin low
servo_delay(18000); //keep the pin low for 18000 microseconds
delay(2000); //this delay just hold the position for a little bit of times
}
}
মন্তব্যসমূহ
একটি মন্তব্য পোস্ট করুন