1-1- سخت افزار
سخت افزار شامل قسمت های زیر می باشد :
میکرو کنترولر ATmega8
رابط USB
LCD جهت ارتباط با کاربر
رله و راه انداز آن
1-1-1- میکرو کنترولر :
در این پروژه از ATmega8 به عنوان کنترولر و مدار فرمان رله ها استفاده شده است . در عین حال برای ارتباط با کامپیوتر از طریق پورت USB نیز ، از این میکرو کنترولر استفاده شده است.این میکرو کنترولر از خانواده میکروکنترولر های AVR است .
پروتکل USB به صورت نرم افزاری در برنامه (Firmware) میکرو پیاده سازی شده است و می تواند با استاندارد USB 1.1 Low به تبادل اطلاعات بپردازد.
برنامه این میکرو بر اساس کامپایلر GCC نوشته شده است که برای کامپایل آن می توان از برنامه WinAvr استفاده کرد .
LCD بکار رفته در این پروژه کاراکتری و 16*2 می باشد که بصورت مستقیم توسط نرم افزار کامپیوتری ، متن یا دستوالعمل را گرفته و اجرا می کند .
در برنامه کامپیوتری برای ارتباط با پورت USB از درایور آماده libusb استفاده شده است .
برنامه کامپیوتری توسط زبان C++Builder تهیه شده است. این برنامه مستقیماٌ از میکروفن کامپیوتر صوت را دریافت کرده و پس از ذخیره در بافر داخلی شروع به تجزیه و تحلیل می کند. روال کار به این صورت است که از اطلاعات ورودی که در بازه زمان هستند تبدیل فوریه (FFT) گرفته شده تا به بازه فرکانس بروند . سپس با پردازش روی طیف فرکانسی و کمی کار آماری حدود شباهت صوت دریافتی را با نمونه های ذخیره شده مقایسه می کند .
1-1-2- لخت افزار Firmware :
میکرو میتواند پنج دستورالعمل مختلف را از کامپیوتر دریافت نموده و اجرا نماید .
1- ارسال یک بایت دستورالعمل به LCD : cmdLCD_Command
2- ارسال یک بایت دیتا به LCD : cmdLCD_Data
3- نمایش یک رشته متنی روی LCD : cmdLCD_Str
4- روشن و خاموش کردن BackLight : cmdLCD_BL
5- کنترل رله ها : cmdSWITCH
برای کنترل LCD سه تابع طراحی شده است :
void LCD_Command(uchar command)
void LCD_Data(uchar data)
void LCD_Init(void)
این توابع برای ارسال دستورالعمل ودیتا و همچنین تنظیمات اولیه استفاده می شوند .
یکی از توابعی که در بخش USB آن استفاده می شود usbFunctionSetup است که توسط آن به درخواست رسیده شده از کامپیوتر پاسخ داده می شود .از تابع usbFunctionWrite جهت دریافت اطلاعات از کامپیوتر استفاده می گردد . تابع دیگری که برای ارسال دیتا به کامپیوتر از آن استفاده می شود usbFunctionRead نام دارد که در این پروژه از آن استفاده نگردیده است .
متن کامل این توابع را در زیر مشاهده می کنید :
void LCD_Command(uchar command){
PORTB &= 0b11000111;
PORTC &= 0b11100000;
PORTC |= (((command & 0b00000001) << 4) & 0b00010000);
PORTC |= (((command & 0b00000010) << 2) & 0b00001000);
PORTC |= (((command & 0b00000100) ) & 0b00000100);
PORTC |= (((command & 0b00001000) >> 2) & 0b00000010);
PORTC |= (((command & 0b00010000) >> 4) & 0b00000001);
PORTB |= (((command & 0b00100000) ) & 0b00100000);
PORTB |= (((command & 0b01000000) >> 2) & 0b00010000);
PORTB |= (((command & 0b10000000) >> 4) & 0b00001000);
PORTD &= ~(1 << 6);
PORTC |= (1 << 5);
_delay_ms(10);
PORTC &= ~(1 << 5);
}
void LCD_Data(uchar data){
PORTB &= 0b11000111;
PORTC &= 0b11100000;
PORTC |= (((data & 0b00000001) << 4) & 0b00010000);
PORTC |= (((data & 0b00000010) << 2) & 0b00001000);
PORTC |= (((data & 0b00000100) ) & 0b00000100);
PORTC |= (((data & 0b00001000) >> 2) & 0b00000010);
PORTC |= (((data & 0b00010000) >> 4) & 0b00000001);
PORTB |= (((data & 0b00100000) ) & 0b00100000);
PORTB |= (((data & 0b01000000) >> 2) & 0b00010000);
PORTB |= (((data & 0b10000000) >> 4) & 0b00001000);
PORTD |= (1 << 6);
PORTC |= (1 << 5);
_delay_ms(10);
PORTC &= ~(1 << 5);
}
void LCD_Init(void){
LCD_Command(0x38);
_delay_ms(100);
LCD_Command(0x0C);
_delay_ms(100);
LCD_Command(0x01);
_delay_ms(100);
}
uchar usbFunctionSetup(uchar data[8]) {
uchar len = 0;
if(data[1] == cmdLCD_Command){
LCD_Command(data[2]);
replyBuffer[0] = cmdOK;
len = 1;
} else if (data[1] == cmdLCD_Data) {
replyBuffer[0] = cmdOK;
len = 1;
} else if (data[1] == cmdLCD_Str) {
len = 0xff;
} else if (data[1] == cmdLCD_BL) {
if(data[2] != 0)
PORTD |= (1 << 7);
else
PORTD &= ~(1 << 7);
replyBuffer[0] = cmdOK;
len = 1;
} else if (data[1] == cmdSWITCH) {
sw = data[4];
PORTB |= 0b00000100;
PORTD |= 0b00111010;
PORTB &= (((sw | 0b11111110) << 2) | 0b11111011);
PORTD &= (((sw | 0b11111101) << 5) | 0b11011111);
PORTD &= (((sw | 0b11111011) << 4) | 0b11101111);
PORTD &= (((sw | 0b11110111) << 3) | 0b11110111);
PORTD &= (((sw | 0b11101111) << 2) | 0b11111011);
replyBuffer[0] = cmdOK;
len = 1;
}
usbMsgPtr = replyBuffer;
return len;
}
uchar usbFunctionRead(uchar *data, uchar len) {
return 0;
}
uchar usbFunctionWrite(uchar *data, uchar len) {
uchar i;
for (i = 0; i < len; i++) {
LCD_Data(data[i]);
}
return 0
طرح شماتیک و نقشه پشت بورد مدار بصورت زیر خواهد بود :
فصل دوم
2-1- نرم افزار: Software
در این برنامه برای ارتباط از طریق پورت USB از درایور libusb-win32 استفاده شده است . برای استفاده از آن باید یک فایل کتابخانه ای به نام LIBUSB.lib را به پروژه اضافه کرده و از توابع libusb0.dll استفاده نماییم.
توابع استفاده شده در این پروژه به این شرح می باشند :
void usb_init(void);
int usb_find_busses(void);
int usb_find_devices(void);
usb_dev_handle *usb_open(struct *usb_device dev);
int usb_close(usb_dev_handle *dev);
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);
برای نقل و انتقال اطلاعات و دستورالعمل از تابع زیر استفاده می شود :
static int usbtransmit(unsigned char receive, unsigned char functionid,
unsigned char send[4], unsigned char * buffer, int buffersize)
{
int nbytes;
nbytes = usb_control_msg(usbhandle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
functionid,
(send[1] << 8) | send[0],
(send[3] << 8) | send[2],
buffer, buffersize,
5000);
if(nbytes < 0){
MessageDlg("ControlMessage Error." , mtError, TMsgDlgButtons() << mbOK, 0);
exit(1);
}
return nbytes;
}
این تابع در واقع پایه همه توابعی است که در برنامه آمده است.
سایر توابع مورد نیاز به این شرح است :
unsigned char USB_LCD_Command(unsigned char byte)
{
unsigned char res[4];
unsigned char cmd[4];
cmd[0]=byte;
usbtransmit(1, cmdLCD_Command,cmd, res,sizeof(res));
return res[0];
}
//---------------------------------------------------------------------------
unsigned char USB_LCD_Data(unsigned char byte)
{
unsigned char res[4];
unsigned char cmd[4];
cmd[0]=byte;
usbtransmit(1, cmdLCD_Data,cmd, res,sizeof(res));
return res[0];
}
//---------------------------------------------------------------------------
unsigned char USB_LCD_Str(unsigned char *data,unsigned char len)
{
unsigned char cmd[4];
usbtransmit(0, cmdLCD_Str, cmd, data, len);
return 0;
}
//---------------------------------------------------------------------------
unsigned char USB_LCD_BL(unsigned char byte)
{
unsigned char res[4];
unsigned char cmd[4];
cmd[0]=byte;
usbtransmit(1, cmdLCD_BL,cmd, res,sizeof(res));
return res[0];
}
//---------------------------------------------------------------------------
unsigned char USB_SWITCH(unsigned char byte)
{
unsigned char res[4];
unsigned char cmd[4];
cmd[0]=byte;
usbtransmit(1, cmdSWITCH,cmd, res,sizeof(res));
return res[0];
}
اولین آرگومان تابع usbtransmit بیانگر ورودی/کنترلی ویا خروجی بودن فراخوانی آن را دارد که در توابع فوق فقط تابع USB_LCD_Str خروجی است و بقیه تابع کنترلی هستند .