در هر میکروکنترلر محدودیت پین و حافظه وجود دارد. برای عملیات رله ساده، یعنی روشن و خاموش، به 3 پین نیاز هست. 2 پایه برای کلیدهای روشن و خاموش و یکی برای کنترل رله است.در این پروژه فقط از یک پین برای روشن و خاموش کردن رله با استفاده یک سوئیچ فشاری استفاده می کنیم.
قطعات:
- میکروکنترلر Attiny 13
- سوئیچ فشاری
- مقاومت های 47K، 100k،10k
- رله 12 ولت
- ترانزیستور NPN 545
در این پروژه رله را با سوئیچ تک فشاری کنترل خواهیم کرد. برای کنترل رله از آی سی میکروکنترلر Attiny 13 استفاده می شود. آی سی میکروکنترلر Attiny 13 دارای 6 پایه ورودی/خروجی قابل برنامه ریزی است که ما فقط از دو پایه استفاده می کنیم، یکی برای رابط رله و دیگری برای دکمه فشاری است. اتصال کل مدار مطابق نمودار مدار است.
مدار:
جدول پین ها:
پین شماره | Register DDRB | ورودی/خروجی | تابع برای استفاده در کد |
5 | PB0 | ورودی | سوئیچ فشاری |
7 | PB2 | خارج | رله |
8 | VCC | 5 ولت | ولتاژ تغذیه |
4 | GND | زمین | زمین |
نکات مهم
در Attiny 13 فقط 1 پورت برای برنامه نویسی موجود است. سه مکان آدرس حافظه ورودی/خروجی برای هر پورت، یکی برای ثبت داده (Data Register) PORTx، ثبت جهت داده (Data Direction Register) DDRx و پین های ورودی پورت (Port Input Pins) PINx اختصاص داده شده است. محل ورودی/خروجی پینهای ورودی پورت فقط خواندنی است، در حالی که ثبت داده و ثبت جهت داده خواندن/نوشتن هستند .
می توانیم از پایه PB2 به عنوان خروجی و از پایه PB0 به عنوان ورودی استفاده کنیم، بنابراین مقدار را در PORTB به صورت 0x01 می نویسیم که در آن پایه PB0 به صورت داخلی روشن می شود، و مقدار 0xFE را در ثبات DDRB می نویسیم که در آن پایه PB0 فقط به عنوان ورودی استفاده می شود و پایه های دیگر به عنوان خروجی استفاده می شود.
منطق:
هنگامی که دکمه فشار در بار اول فشار داده می شود ، رله روشن می شود تا زمانی که دکمه فشار برای بار دوم فشار داده شود ، زمانی که دکمه فشاری در بار دوم فشار داده شود ، رله خاموش خواهد شد. این در حلقه اتفاق خواهد افتاد.
نمودار عملکرد :
کد :
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
unsigned char relay_on_off_flag =0;
unsigned char relay_flag =0;
//---------------------------------------------------------------
void init_port(void)
{
DDRB = 0xFE; //PIN no 0 as input
PORTB = 0x01; //0 internally pullup
}
//----------------------------------------------------------------
void relay_on(void)
{
PORTB =PORTB | 0x04; //function for relay on
}
void relay_off(void)
{
PORTB =PORTB & 0xFB; //function for relay off
}
//----------------------------------------------------------------
int main()
{
unsigned int flag=0;
init_port();
while(1)
{
if((bit_is_clear(PINB, 0 )) && (relay_on_off_flag ==0)) //If button is pressed at first time
{
relay_on_off_flag=1; //relay flag
relay_flag=1; //relay on off flag
_delay_ms(500); //delay in ms to avoid the key debounce
}
else if((bit_is_set(PINB, 0 )) && (relay_on_off_flag == 0)) //If button is not pressed
{
if(relay_flag !=1) //check relay is off or on
{
relay_flag=0; //relay off
relay_on_off_flag=0;
}
else
{
relay_flag=1; // relay on
relay_on_off_flag=1;
}
}
else if((bit_is_clear(PINB, 0 )) && (relay_on_off_flag == 1)) //If button is pressed at second time
{
relay_on_off_flag=1; //relay flag
relay_flag=0; //relay on off flag
_delay_ms(500); //delay in ms to avoid the key debounce
}
else if((bit_is_set(PINB, 0 )) && (relay_on_off_flag == 1)) //If button is not pressed
{
if(relay_flag !=1) //check relay is off or on
{
relay_flag=0; //relay off
relay_on_off_flag=0;
}
else
{
relay_flag=1; // relay on
relay_on_off_flag=1;
}
}
if(relay_flag==1) //check for relay on off flag
{
relay_on(); // if flag is 1 then relay on
}
else //else relay is off
{
relay_off();
}
}
}
//----------------------------------------------------------------