ميكروكنترل: ضبط صوت دیجیتال توسط میکرو AVR
دراین مقاله با موارد زیر اشنا میشوید :
- پخش صدای ضبط شده در میکرو بدون نیاز به حافظه جانبی.
- ضبط صدا توسط میکرو.
- ارتباط با کارت های حافظه های MMC و SD جهت ذخیره و خواندن اطلاعات.
- پخش صدا توسط PWM در میکرو.
- و ...
بنا به سفارش یکی از دوستان که مداری مشابه یکی از توضیحات شرکت اتمل در مورد Digital Sound Recorder که از آدرس زیر میتوانید مطالعه کنید به من شد.
www.atmel.com/atmel/acrobat/doc1456.pdfمن هم پس از مطالعه مطلب فوق با ایجاد اصلاحاتی در مدار آن را مجددا طراحی و ساختم که در ادامه با آن آشنا می شوید.
من در برنامه خودم اطلاعات صدای شروع ویندوز XP را که به اسم Windows XP Startup.wav در سیستم قرار دارد را توسط برنامه WinHex در فلاش رام میکرو قرار دادم. تا میکرو بدون نیاز به هیچگونه حافظه جانبی بتواند صدای فوق را پخش کند. البته طبق محاسبات من برای پخش هر یک ثانیه صدای مونو شما نیاز به حدود 7 کیلو بایت حافظه دارید که با توجه به اینکه من از میکرو ATmega32 با 32 کیلوبایت حافظه فلاش استفاده کردم میتوانستم تا 4 ثانیه صدا در آن ذخیره کنم. توجه داشته باشید که در اغلب برنامه ها ما درصد کمی از این حافظه را مورد استفاده قرار میدهیم پس در پروژه های خود میتوانید برای کاربر پسندتر شدن از این قابلیت بهره ببرید. مثلا میتوانید با استفاده از میکرو ATmega128 تا حدود 18 ثانیه صدا ذخیره کنید و بعنوان مثال تک تک اعداد 0 تا 9 و برخی ارقام و حروف را در آن قرار دهید و تا پس از آن هر شماره ای را که میخواهید برایتان بخواند!
خوب حال برای تبدیل فایل صوتی به فرمتی که بتوان در سورس برنامه از آن استفاده کرد به برنامه های زیر نیاز داریم :
- ImTOO Video Converter Ultimate برای تبدیل فرمت های مختلف صدا و تصویر به هم.
- WinHex برای ویرایش و مشاهده فایلها بصورت Hex.
- Sound Recorder ویندوز که بهمراه ویندوز بر روی کامپیوتر نصب میشود.
فوق العاده برنامه سبک ولی کارآمدی هست که تا با اون کار نکنید متوجه منظور من نخواهید شد. از اون دسته برنامه هایی هست که واقعا من خوشم میاد ساده و کاربردی و سبک. هیچ فرمتی را نمیتونید پید ا کنید که ساپورت نکنه. شما هم اگه فایل صوتی با فرمتی غیر از wav دارید برای تبدیل و یا برش قسمتی از آن میتونید از این برنامه استفاده کنید. برای دانلود فایل با حجم 42.45 مگابایت از آدرس زیر استفاده کنید:
http://www.brothersoft.com/imtoo-video-converter-ultimate-250449.htmlحالا که فایل wav شما آماده شد باید توسط برنامه Sound Recorder ویندوز فایل را باز کنید. باز کردن این برنامه بر روی Start کلیک کنید.بر رروی All Programs رفته ، بر روی Accessories بروید ، بر روی Entertainment رفته و Sound Recorder را اجرا کنید.
فایل مورد نظرتان را در باین برنامه باز کنید. و منوی File گزینه Save As را انتخاب کنید در پنجره باز شده بر روی دکمه Change کلیک کنید و در پنجره جدید از منوی کشویی Attributes گزینه اول (8.000kHz;8Bit;Mono) را انتخاب کنید و Ok کنید و فایلتان را ذخیره کنید.
حالا نوبت به تبدیل فایل به اطلاعات قابل استفاده در برنامه است. با توجه به اینکه من برنامه را به زبان سی نوشتم (البته توضیحات فوق را با کمی تغییر میتواند در مورد سایر زبانها همچون بیسیک و یا اسمبلی هم استفاده کرد) باید مراحل زیر را دنبال کنید.
برای این منظور برنامه WinHex را دانلود کنید:
http://winhex.software.informer.com/download سپس بعد از اجرای برنامه فایل مورد نظر را در آن باز کنید.
سپس بر روی کدهای نشان داده شده کلیک کنید و دکمه های Ctrl+A را بزنید تا تماما انتخاب شوند.
حال از منوی Edit گزینه Copy Block و از منوی باز شده گزینه C Source را انتخاب کنید.
در این مرحله در برنامه خود Paste کنید. خواهید دید کدی مشابه زیر تولید شده:
unsignedchardata[104]={0x3E,0x3E,0x3E,0x27,0x44,0x75,0x70,0x6C,0x69,0x63,0x61,0x74,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x27,0x25,0x73,0x27,0x6F,0x72,0x65,0x64,0x2E,0x27,0x29,0x3B,0x0D,0x0A,0x44,0x75,0x61,0x74,0x65,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x3A,0x5C,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x46,0x69,0x44,0x65,0x73,0x69,0x67,0x6E,0x20,0x45,0x78,0x70,0x6C,0x6F,0x39,0x39,0x20,0x53,0x45,0x5C,0x53,0x79,0x73,0x74,0x65,0x6D,0x67,0x6E,0x6F,0x72,0x65,0x64,0x2E,0x0D,0x0A,0x3E,0x3E,0x3E,0x6C,0x69,0x63,0x61,0x74,0x65,0x20,0x64,0x69,0x72,0x65,0x63};
این کدها بصورت آرایه میباشند که شامل اطلاعات صدا هستند. برای اینکه این کدها در بخش حافظه flash ذخیره شوند باید ابتدای تعریف آرایه کلمه const را اضافه کنید.
این کدها بصورت آرایه میباشند که شامل اطلاعات صدا هستند. برای اینکه این کدها در بخش حافظه flash ذخیره شوند باید ابتدای تعریف آرایه کلمه const را اضافه کنید.
در این بخش جرئیات استفاده از مبدل آنالوگ به دیجیتال جهت ضبط صدا ، استفاده از باس SPI جهت ارتباط با حافظه MMC و مدالسیون پهنای باند PWM برای پخش آشنا میگردید. نمونه کاربردهای که نیاز یک یا تعدادی از این بلوک ها دارند عبارتند از لاگرهای دما ، دستگاه های پاسخگویی تلفن ، یا ضبط کنندهای دیجیتالی صدا.
حافظه MMC مورد استفاده میتواند از هر رنجی انتخاب شود. این حافظه ها با ولتاژ 3.3 ولت و با واسط SPI کار میکنند که برای دسترسی سریع به حافظه بهتر است که بصورت سکتورهای 512 بایتی به آن دسترسی داشته باشیم برای این منظور یک ارایه بعنوان بافر در برنامه جهت دسترسی به حافظه تعریف شده است.
همانطور که عنوان شد حافظه MMC جهت ارتباط از رابط سریال SPI برای دسترسی به اطلاعات استفاده میکند این واسط سخت افزار ساده تری نیاز دارد و باعث کاهش نویز و کاهش ابعاد و تعداد پین های فعال میگردد. نمونه کاربردهای این حافظه ذخیره سازی تصویر، اطلاعات و یا صوت است.
برای تامین ولتاژ 3.3 ولت مورد نیاز حافظه از یک رگولاتور خطی بنام LF33 استفاده شده است. حافظه در فرکانس 2MHz کار میکند و در مد صفر ارتباط بین میکروکنترولر و حافظه برقرار شده است.
در این مدار میکرو ATmega32 برای گرفتن نمونه های آنالوگ از میکروفن ، از مبدل آنالوگ به دیجیتال داخلی استفاده کرده و انتقال اطلاعات بین میکرو حافظه نیز با استفاده از رابط SPI میکرو انجام میشود. از PWM میکرو نیز برا ی پخش صدا استفاده شده است. کدهای اصلی برنامه خیلی کم هستند و براحتی میتوان در میکروهای کوچکتر نیز قرار داد.
قبل ار اینکه صدا را بتوان در حافظه ذخیره نمود باید آنرا به سیگنالهای دیجیتال تبدیل کرد. اینکار در طی چندین مرحله انجام میشود.
تصویر 1، نمونه سیگنال آنالوگ.
نخست، سیگنال آنالوگ(تصویر1) به نمونه های زمانی (تصویر 2) تبدیل میشود. زمان بین دو نمونه "پریود نمونه برداری" نامیده میشود. و متقابلا آن به "فرکانس نمونه برداری" وابسته است.مطابق با قضیه نمونه برداری ، فرکانس نمونه برداری باید دو برابر فرکانس سیگنال باشد.
یک سیگنال صدا شامل اطلاعات ماکزیمم زیر 3000Hz است. بنابراین یک فیلتر پایین گذر را میتوان بعنوان محدود کننده باند سیگنال استفاده نمود.
برای یک فیلتر پایین گذر ایده ال با فرکانس قطع 3000Hz فرکانس نمونه برداری باید 6000Hz باشد. عمل برداشتن مقادیر دیجیتال از روی نمونه های آنالوگ کوانتیزیشن نامیده میشود.سیگنال آنالوگ کوانتیزه شده بسیار نزدیک به سیگنال اصلی است.(تصویر 3). تعداد مقادیر دیجیتال را رزولوشن مینامند که مقادیر محدودی هستند. برای نمونه تا 256 مقدار برای یک سیگنال دیجیتال 8 بیتی یا 10 مقدار در این مثال. بنابراین در کوانتیزه کردن سیگنالهای آنالوگ همیشه بخشی از اطلاعات از بین میروند. این خطای کوانتیزه کردن رابطه عکس با رزولوشن سیگنال دیجیتال ،محدوده حداکثر و حداقل مقادیر ( 3 تا 8 در این مثال) دارد.مبدل آنالوگ به دیجیتال میکرو میتواند برای رنج دینامیک سیگنال توسط AGND و AREF برروی مینیمم و ماکزیمم مقادیر سیگنال تنظیم شود.
از سوی دیگر آمپلیفایر میکروفن را میتوان برروی حد دینامیک ADC تنظیم نمود.
هر دوی این روشها مقادر خطای کوانتیزه کردن را کاهش میدهد تصویر 4 مقادیر دیجیتال بدست آمده از سیگنال آنالوگ را نشان میدهد. اینها مقادیر خوانده شده از نتایج تبدیلات ADC هستند.
در این مدار مقادیر ماکزیمم و مینیمم با ارزش نیستند. و بخش بالای ماکزیمم و زیر مینیمم حاوی اطلاعاتی نمیباشند. و میتوان آنها را برای صرفه جویی در حافظه حذف نمود.
اینکار را میتوان با شیفت به پایین دادن تمام سیگنال و برش بالای max انجام داد.(تصویر 5).
تصویر 2، سیگنال زمان گسسته.
تصویر 3، سیگنال کوانتیزه.
تصویر 4، سیگنال دیجیتال.
تصویر 5، سیگنال دیجیتال با کاهش بیت.
در این مدار نتیجه سیگنالها 8 بیتی است. این سیگنال اکنون میتواند در حافظه ذخیره شود.
برای پخش اطلاعات ابتدا انها از حافظه خوانده میشود و سپس با توجه به مقدار خوانده شده پالسی با عرض متناسب تولید میگردد. هرچه مقدار خوانده شده بزرگتر باشد عرض پالس تولیدی نیز بزرگتر خواهد بود و بالعکس.(تصویر 6)
تصویر 6، دو از مثال از سیگنال PWM.
در تصویر 6 دو نمونه از سیگنال نشان داده شده است. مبدل PWM دوشیبه است در شیب اول تا زمانیکه مقدار شمارنده به عدد مورد نظر نرسیده خروجی صفر است پس از رسیدن شمارنده خروجی یک میشود. سپس در شیب نزولی تا زمانیکه مقدار شمارنده از عدد مورئ نظر کمتر نشده مقدار خروجی یک باقی می ماند. به این ترتیب پالسی با عرض متناسب با عدد مورد نظر تولید میشود در تصویر 7 خروجی PWM برای سیگنال مثال نشان داده شده است.
فرکانس سیگنال PWM باید دو برابر فرکانس سیگنال باشد. اما مقدار 4 برابر بزرگتر از سیگنال اصلی معمولا توصیه میشود. بسته به فیلتر خروجی میتوان بهترین گزینه را با افزایش کلاک یا کاهش رزولوشن سیگنال انتخاب نمود.
تصویر 7، سیگنال خروجی PWM فیلتر شده.
در این مدار فرکانس قطع فیلتر خروجی بر روی 4000Hz تنظیم شده است، که یک چهارم فرکانس PWM (15,686Hz) است.
سرعت کلاک سیستم و رزولوشن PWM مقدار فرکانس PWM را تعیین میکنند. با کلاک سیستم 8MHz برای رزولوشن 10 بیت 3922Hz است(8MHz/2x2^10=3922Hz) 7843Hz برای رزولوشن 9 بیت و 15,686Hz برای رزولوشن 8 بیت.
فقط آخرین مقدار به اندازه کافی بزرگ است تابعنوان سیگنال کریر برای سیگنال 4000Hz استفاده شود.
فیلتر خروجی فرکانس های بالای سیگنال حامل PWM را حذف میکند. نتیجه خروجی سیگنال برای سیگنال نمونه نشان داده شده ، شبیه تصویر 8 است.
تصویر 8، سیگنال خروجی PWM.
مدار میکروفن و اسپیکر
آمپلی فایر میکروفن یک آمپلی فایر معکوس ساده است. گین مدار توسط مقاومت R1 و R9 تنظیم میشود.(گین = R1 / R9). R4 برای تامین تغذیه میکروفن و C1 برای مسدود کردن ورود مقادیر DC به آمپلی فایر استفاده شده. R2 ,R3 مقدار افست را تنظیم میکنند.R5 و C8 یک فیلتر پایین گذر ساده را تشکیل میدهند. بعلاوه R5 محافظت میکند آمپلی فایر را از هرگونه خطر در صورتیکه خروجی اتصال کوتاه شده باشد. مدار اسپیکر شامل 5 طبقه فیلتر پایین گذر چبیچو است و یک طبقه تقویت کننده.
فیلتر ها از دو طبقه دوتایی فیلتر اکتیو(R6 , R7 , R8 , C2 , C7 و R7 , R10 , R11 , R9 , C9 , C5) و یک طبقه فیلتر پسیو(R11 , C4) است.
جهت مشاهده نقشه در ابعاد بزرگتر برروی آن کلیک کنید
برنامه میکرو
/***************************************************** This program was produced by the CodeWizardAVR V1.25.9 Professional Automatic Program Generator © Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 2010/05/21 Author : Hossein Lachini Company : HLachini Comments: Chip type : ATmega32 Program type : Application Clock frequency : 8.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 512 *****************************************************/#include #include #include #include #include "mmc_lib.h" #include "Windows XP Startup.c" #define KEY_PLAY PIND.1 #define KEY_RECORD PIND.2 #define KEY_ERASE PIND.3 #define LED PORTB.0 #define ON 1 #define OFF 0 #define SectorSize 512 #define MMC_CS PORTB.4 #define RECORD_TIME 30 // Alphanumeric LCD Module functions #asm .equ__lcd_port=0x15;PORTC#endasm #include #define ADC_VREF_TYPE 0x60 typedefunsignedcharBYTE;typedefunsignedintWORD;BYTEbuf_mmc[SectorSize];// Read the 8 most significant bits // of the AD conversion result unsignedcharread_adc(unsignedcharadc_input){ADMUX=adc_input|(ADC_VREF_TYPE&0xff);// Delay needed for the stabilization of the ADC input voltage delay_us(10);// Start the AD conversion ADCSRA|=0x40;// Wait for the AD conversion to complete while((ADCSRA&0x10)==0);ADCSRA|=0x10;returnADCH;}// Declare your global variables here unsignedchart1ovf;// Timer 1 overflow interrupt service routine interrupt[TIM1_OVF]voidtimer1_ovf_isr(void){// Place your code here if(t1ovf)t1ovf--;}voidplay_sample(void){WORDidx;for(idx=0;idx<DURATION;idx++){OCR1B=data[idx];t1ovf=2;while(t1ovf);}OCR1B=0;}voidmenu(void){lcd_clear();lcd_putsf("PLY REC ERS");}voidrecord(void){WORDi,mmc_sector_num;lcd_clear();lcd_putsf("Record");lcd_gotoxy(0,1);LED=ON;for(mmc_sector_num=0;mmc_sector_num<RECORD_TIME*14;mmc_sector_num++){for(i=0;i<SectorSize;i++){buf_mmc[i]=read_adc(0);t1ovf=2;while(t1ovf);}mmc_write(mmc_sector_num,buf_mmc);if(mmc_sector_num%(RECORD_TIME*14/10)==0)lcd_putsf("#");}LED=OFF;menu();}voidplay(void){WORDidx,mmc_sector_num;lcd_clear();lcd_putsf("Play");lcd_gotoxy(0,1);LED=ON;for(mmc_sector_num=0;mmc_sector_num<RECORD_TIME*14;mmc_sector_num++){mmc_read(mmc_sector_num,buf_mmc);for(idx=0;idx<SectorSize;idx++){OCR1B=buf_mmc[idx];t1ovf=2;while(t1ovf);}if(mmc_sector_num%(RECORD_TIME*14/10)==0)lcd_putsf("#");}LED=OFF;menu();}voidmic2spk(void){lcd_clear();lcd_putsf("Mic -> Spk");lcd_gotoxy(0,1);lcd_putsf(" REC => EXIT");while(~KEY_ERASE){OCR1B=1*read_adc(0);t1ovf=2;while(t1ovf);}menu();}voidadc2lcd(void){BYTEad;charstr[8];staticunsignedcharad_old;lcd_clear();lcd_putsf("ADC -> LCD");lcd_gotoxy(0,1);lcd_putsf(" REC => EXIT");delay_ms(3000);while(~KEY_RECORD){ad=read_adc(0);if(ad!=ad_old){lcd_clear();lcd_putsf("ADC=");itoa(ad,str);lcd_gotoxy(5,0);lcd_puts(str);lcd_gotoxy(0,1);ad_old=ad;ad/=16;for(;ad;ad--)lcd_putsf("#");delay_ms(100);}}menu();}voidtestmmc(void){WORDi,mmc_sector_num;lcd_clear();lcd_putsf("Erase");LED=ON;for(mmc_sector_num=0;mmc_sector_num<DURATION/SectorSize;mmc_sector_num++){for(i=0;i<SectorSize;i++){buf_mmc[i]=data[mmc_sector_num*SectorSize+i];}mmc_write(mmc_sector_num,buf_mmc);}for(i=0;i<SectorSize;i++){buf_mmc[i]=0;}mmc_read(0,buf_mmc);for(i=0;i<SectorSize&&buf_mmc[i]==data[i];i++);lcd_clear();if(i==SectorSize){lcd_putsf("MMC OK");LED=OFF;}else{lcd_putsf("MMC Fail!");}delay_ms(1000);menu();}voidinit(void){// Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00;DDRA=0x00;// Port B initialization // Func7=In Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out // State7=T State6=0 State5=T State4=T State3=T State2=T State1=T State0=0 PORTB=0x00;DDRB=0xB1;// Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00;DDRC=0x00;// Port D initialization // Func7=In Func6=In Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=T State2=T State1=T State0=T PORTD=0x00;DDRD=0x10;LED=OFF;// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x00;TCNT0=0x00;OCR0=0x00;// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 8000.000 kHz // Mode: Ph. correct PWM top=00FFh // OC1A output: Discon. // OC1B output: Non-Inv. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: On // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x21;TCCR1B=0x01;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x00;OCR1AL=0x00;OCR1BH=0x00;OCR1BL=0x00;// Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00;TCCR2=0x00;TCNT2=0x00;OCR2=0x00;// External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00;MCUCSR=0x00;// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x04;// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80;SFIOR=0x00;// ADC initialization // ADC Clock frequency: 1000.000 kHz // ADC Voltage Reference: AVCC pin // Only the 8 most significant bits of // the AD conversion result are used ADMUX=ADC_VREF_TYPE&0xff;ADCSRA=0x83;// LCD module initialization lcd_init(16);// SPI initialization // SPI Type: Master // SPI Clock Rate: 2000.000 kHz // SPI Clock Phase: Cycle Half // SPI Clock Polarity: Low // SPI Data Order: MSB First SPCR=0x50;SPSR=0x00;mmc_init();LED=OFF;// Global enable interrupts #asm("sei") }voidmain(void){// Declare your local variables here init();lcd_clear();lcd_putsf("LOADING...");lcd_gotoxy(0,1);lcd_putsf("PLY ERS");play_sample();if(KEY_PLAY)mic2spk();if(KEY_ERASE)adc2lcd();menu();while(1){// Place your code here if(KEY_PLAY)play();if(KEY_RECORD)record();if(KEY_ERASE)testmmc();};}
مطالب مشابه :
مدار فرستندهVHF=مدار ویدئو سندر
C9 تشکیل یک مدار اسیلاتور کولپیتس را عکس - sms - سینما - هنر - ترفند - نوکیا - نرم افزار
ميكروكنترل: ضبط صوت دیجیتال توسط میکرو AVR
c2 , c7 و r7 , r10 , r11 , r9 , c9 , c5) و یک طبقه فیلتر پسیو(r11 , c4) است. دانلود نرم افزار نوکیا سری 90;
کد جاوا اسکرسیپت " ساعت عقربه دار ثابت "
کد مخفی گوشی های نوکیا و سامسونگ و سونی اریکسون هم موجوده. آهنگ زنگ گوشی موبایل هم هست.
مدار فرستندهVHF=مدار ویدئو سندر
C9 تشکیل یک مدار اسیلاتور کولپیتس را عکس - sms - سینما - هنر - ترفند - نوکیا - نرم افزار
برچسب :
نوکیا c9