بازر (Buzzer)
مقدمه
بازر (Buzzer) یکی از سادهترین و در عین حال پراستفادهترین قطعات در پروژههای الکترونیکی است. از هشدارهای ساده گرفته تا پیغامهای خطا، آلارمها و سیستمهای اعلان صوتی، همه جا ردپای این قطعه کوچک اما مفید دیده میشود. در این مقاله قصد داریم به بررسی کامل بازر بپردازیم. ساختار داخلی آن را بررسی کنیم، انواع مختلفش را بشناسیم، کاربردهایش را یاد بگیریم و در نهایت، یک کتابخانه نوشته شده برای کنترل بازر با میکروکنترلر را بهصورت مفصل بررسی کنیم.
بازر چیست؟
بازر قطعهای الکترونیکی است که با اعمال ولتاژ، یک صدای ممتد یا متناوب تولید میکند. این صدا معمولاً برای هشدار دادن، اعلام وضعیت، یا توجه دادن کاربر به رخداد خاصی استفاده میشود. بازرها اغلب در پروژههای مبتنی بر میکروکنترلر، بردهای آردوینو، سیستمهای امنیتی، تجهیزات صنعتی و پزشکی، ساعتهای دیجیتال و دهها کاربرد دیگر به کار میروند.

انواع بازر
بازرها از نظر ساختار و عملکرد به دو دسته اصلی تقسیم میشوند:
1. بازر اکتیو (Active Buzzer)
- ویژگی: داخلی آن دارای نوسانساز است و با اعمال ولتاژ مستقیم (DC) صدا تولید میکند.
- نحوه استفاده: فقط کافی است آن را به ولتاژ وصل کنید؛ صدا تولید میکند.
- مزیت: راهاندازی بسیار ساده.
- عیب: امکان کنترل فرکانس یا نوع صدا وجود ندارد.
2. بازر پسیو (Passive Buzzer)
- ویژگی: داخلی آن نوسانساز ندارد و برای تولید صدا نیاز به سیگنال PWM یا مربعی دارد.
- نحوه استفاده: باید با میکروکنترلر یا آیسی تایمر فرکانس خاصی تولید شود.
- مزیت: میتوان نوع صدا، فرکانس و حتی آهنگ تولید کرد.
- عیب: برنامهنویسی پیچیدهتر نسبت به نوع اکتیو.
کاربردهای بازر
- اعلام هشدار در سیستمهای امنیتی
- صدای دکمه فشردهشده در دستگاههای خانگی
- آلارم پایان فرآیند در دستگاههای صنعتی
- هشدار حرارت بالا یا پایین آمدن ولتاژ
- تایمر و کرنومترها
- اعلام وضعیت در پروژههای میکروکنترلری
ساختار داخلی بازر
در سادهترین حالت، بازر از یک دیافراگم فلزی، سیمپیچ و آهنربا تشکیل شده است. با اعمال ولتاژ به سیمپیچ، میدان مغناطیسی ایجاد میشود و باعث ارتعاش دیافراگم و تولید صدا میگردد. در نوع پسیو، این فرآیند توسط سیگنالهای متناوب کنترل میشود. در نوع اکتیو، نوسانساز داخلی باعث تولید سیگنال شده و دیافراگم را مرتعش میکند.
معرفی کتابخانه بازر
در این بخش، کتابخانهای که برای کنترل بازر نوشته شده به صورت کامل بررسی و توضیح داده میشود. این کتابخانه قابلیت تولید صدای متناوب با تعداد تکرار دلخواه و تأخیر زمانی مشخص را دارد و برای بازرهای اکتیو بسیار مناسب است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#ifndef _BUZER_LIB_H #define _BUZER_LIB_H #define BUZ_DDR DDRA #define BUZ_PIN PORTA7 #define BUZ_PORT PORTA #define BUZ_IN PINA #define BUZ_PINMASK (1<<BUZ_PIN) #define BUZ_ON BUZ_PORT |= BUZ_PINMASK #define BUZ_OFF BUZ_PORT &= ~BUZ_PINMASK #define BUZ_STAT (BUZ_IN & BUZ_PINMASK) static int buzer_counter,buzer_delay,buzer_repeat; void buzzer_init() { BUZ_DDR |= BUZ_PINMASK; BUZ_PORT &= ~BUZ_PINMASK; } void buzzer_handel() { if (BUZ_STAT) { if (buzer_counter < buzer_delay) { buzer_counter++; if (buzer_counter >= buzer_delay) { buzer_counter = 0; BUZ_OFF; if(buzer_repeat)buzer_repeat--; } } } else { if (buzer_repeat) { if (buzer_counter < buzer_delay) { buzer_counter++; } if (buzer_counter >= buzer_delay) { buzer_counter = 0; BUZ_ON; } } } } void beep(int delay, char repeet){ buzer_delay = delay; buzer_counter = 0; buzer_repeat = repeet; BUZ_ON; } char buzzer_is_busy() { return (BUZ_STAT || buzer_repeat); } #endif |
فایل هدر کتابخانه
1 2 |
#ifndef _BUZER_LIB_H #define _BUZER_LIB_H |
این خطوط اطمینان حاصل میکنند که فایل کتابخانه فقط یک بار در پروژه فراخوانی شود.
تعریف پایهها
1 2 3 4 5 |
#define BUZ_DDR DDRA #define BUZ_PIN PORTA7 #define BUZ_PORT PORTA #define BUZ_IN PINA #define BUZ_PINMASK (1<<BUZ_PIN) |
- BUZ_DDR: رجیستر تعیین جهت پورت (خروجی یا ورودی).
- BUZ_PIN: پایهای که بازر به آن متصل شده.
- BUZ_PORT: رجیستر برای کنترل وضعیت پایه (روشن/خاموش).
- BUZ_PINMASK: ایجاد ماسک بیت برای کنترل دقیق پایه.
ماکروهای کنترل بازر
1 2 3 |
#define BUZ_ON BUZ_PORT |= BUZ_PINMASK #define BUZ_OFF BUZ_PORT &= ~BUZ_PINMASK #define BUZ_STAT (BUZ_IN & BUZ_PINMASK) |
- BUZ_ON: روشن کردن بازر
- BUZ_OFF: خاموش کردن بازر
- BUZ_STAT: بررسی وضعیت فعلی پایه بازر
متغیرهای داخلی
1 |
static int buzer_counter, buzer_delay, buzer_repeat; |
buzer_counter: شمارنده زمان روشن/خاموش بودن بازر
buzer_delay: تأخیر بین روشن و خاموش شدن
buzer_repeat: تعداد دفعاتی که بازر باید صدا تولید کند
راهاندازی اولیه بازر
1 2 3 4 5 |
void buzzer_init() { BUZ_DDR |= BUZ_PINMASK; BUZ_PORT &= ~BUZ_PINMASK; } |
این تابع پایه متصل به بازر را به خروجی تبدیل میکند و مطمئن میشود که بازر در ابتدا خاموش باشد.
تابع هندل یا مدیریت بازر
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void buzzer_handel() { if (BUZ_STAT) { if (buzer_counter < buzer_delay) { buzer_counter++; if (buzer_counter >= buzer_delay) { buzer_counter = 0; BUZ_OFF; if(buzer_repeat)buzer_repeat--; } } } else { if (buzer_repeat) { if (buzer_counter < buzer_delay) { buzer_counter++; } if (buzer_counter >= buzer_delay) { buzer_counter = 0; BUZ_ON; } } } } |
این تابع باید در حلقه اصلی یا تایمر فراخوانی شود. این تابع وظیفه دارد روشن و خاموش شدن متناوب بازر را بر اساس delay و repeat مدیریت کند.
تابع تولید صدا
1 2 3 4 5 6 |
void beep(int delay, char repeet){ buzer_delay = delay; buzer_counter = 0; buzer_repeat = repeet; BUZ_ON; } |
با فراخوانی این تابع، بازر شروع به کار میکند. برای مثال:
1 |
beep(100, 3); |
یعنی بازر با تأخیر 100 میلی ثانیه روشن و خاموش شده و این چرخه را 3 بار تکرار کند.
بررسی وضعیت اشغال بودن بازر
1 2 3 |
char buzzer_is_busy() { return (BUZ_STAT || buzer_repeat); } |
این تابع بررسی میکند که آیا بازر هنوز در حال فعالیت است یا خیر. اگر هنوز صدا میدهد یا دفعات باقی مانده دارد، مقدار 1 بازمیگرداند.
مثال کاربردی استفاده از کتابخانه بازر
فرض کنید میخواهید هنگام وقوع خطا در سیستم، بازر 5 بار با فاصله زمانی مشخص به صدا درآید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include "buzer_lib.h" int main(void) { buzzer_init(); while(1) { // کدهای اصلی سیستم if (خطا_رخ_داد) { beep(200, 5); } _delay_ms(1); buzzer_handel(); } } |
در این مثال، اگر خطا تشخیص داده شود، بازر 5 بار با تأخیر 200 به صدا در میآید.
مثال استفاده از وقفه تایمر برای کنترل بازر
در این مثال از تایمر صفر (Timer0) میکروکنترلر AVR استفاده میکنیم تا بهصورت تناوبی هر 1 میلیثانیه وقفه ایجاد کند و درون وقفه، تابع buzzer_handel()
را صدا بزنیم. این روش باعث اجرای دقیق، منظم و بدون تأخیر تابع بازر میشود.
کد کامل مثال با استفاده از وقفه تایمر:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <avr/io.h> #include <avr/interrupt.h> #include "buzer_lib.h" void timer0_init() { // تنظیم تایمر 0 برای ایجاد وقفه هر 1ms با فرکانس 1MHz و Prescaler برابر 64 TCCR0 = (1 << WGM01); // حالت CTC OCR0 = 249; // مقدار مقایسه برای 1ms: (1MHz / 64) = 15.625KHz → 1ms = 250 → OCR0 = 249 TIMSK |= (1 << OCIE0); // فعالسازی وقفه مقایسه TCCR0 |= (1 << CS01) | (1 << CS00); // شروع تایمر با prescaler = 64 } ISR(TIMER0_COMP_vect) { buzzer_handel(); // هر 1 میلیثانیه این تابع صدا زده میشود } int main(void) { buzzer_init(); // راهاندازی اولیه بازر timer0_init(); // راهاندازی تایمر 0 sei(); // فعالسازی وقفه سراسری beep(200, 5); // بازر 5 بار با فاصله 200ms صدا دهد while (1) { } } |
نکات مهم این روش:
نیاز به هیچ تأخیری در حلقه اصلی نیست.
اجرای دقیق بدون اختلال در زمانبندی سایر توابع.
مناسب برای پروژههایی با Multitasking دستی (مانند کنترل رله، سنسور، LCD و…).
فرکانس CPU در مثال بالا 1MHz فرض شده است. اگر فرکانس شما فرق دارد، مقدار OCR0 را باید متناسب تغییر دهید.
نتیجهگیری
بازرها ابزارهای ساده اما پرکاربردی در طراحی سیستمهای تعبیهشده هستند. با شناخت انواع آن، نحوه عملکرد، و استفاده از کتابخانههای بهینه مثل کتابخانهای که در این مقاله معرفی شد، میتوانید پروژههایی دقیق، قابل اعتماد و حرفهای طراحی کنید. این کتابخانه بهصورت ساده اما مؤثر امکان مدیریت صدای هشدار را در پروژههای میکروکنترلری برای شما فراهم میکند.