تبدیل فوریه در میکروکنترلر. تجزیه و تحلیل طیفی سیگنال ها تبدیل فوریه سریع

پردازنده‌های تخصصی زیادی برای پردازش سیگنال دیجیتال (DSP) وجود دارد، مانند DSP از سری TMS320 تگزاس اینسترومنت، که هم هسته‌های عدد صحیح ساده و هم هیولاهایی مانند زیرخانواده خانواده C6000 را شامل می‌شود که داده‌های ممیز شناور را پردازش می‌کند. یک سری کامل ADSP از دستگاه های آنالوگ وجود دارد (که شامل BlackFin کم و بیش جهانی می شود)، همچنین راه حل های ساده تری از MicroChip - dsPIC وجود دارد.

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

امسال سال 2000 نیست، راه‌حل‌های تک‌تراشه‌ای مبتنی بر هسته‌های ARM7/Cortex-M3 با کارایی بالا وجود دارد که قیمت آن‌ها به میزان قابل توجهی کاهش یافته است ، تقریباً یک عملیات ضرب-انباشت DSP و نتیجه 64 بیتی است) و Cortex-M3 نیز شامل تقسیم سخت افزاری است.

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

تقریباً برای هر DSP، کار ذکر شده در بالا ساده و سرراست است. اما یک هسته RISC با هدف کلی چگونه رفتار خواهد کرد؟ اگر AVR یا PIC را در نظر بگیریم، بعید است که کافی باشند. 8 بیت و فرکانس ساعت پایین تاثیر دارد. اگرچه علم چان طرح هایی دارد که در آنها یک FFT روی AVR انجام می دهد و طیف سیگنال را ترسیم می کند. با این حال، در این حالت، در زمان واقعی، به سادگی تصویرسازی (با حداقل دقت پردازش) انجام می شود و نه پردازش سیگنال کامل با کیفیت صوتی قابل قبول.

LPC2146 به عنوان یک تراشه آزمایشی، بر اساس هسته ARM7TDMI-S و دارای حداکثر فرکانس ساعت 60 مگاهرتز (در عمل، در 72 یا حتی 84 مگاهرتز کار نمی کند) انتخاب شد. چرا؟ اولاً من یک برد اشکال زدایی برای آن دارم و ثانیاً یک ADC و DAC روی برد وجود دارد ، یعنی. حداقل تریم خارجی مورد نیاز است.

کمی تئوری

اول از همه، ارزیابی عملکرد FFT (تبدیل فوریه سریع) روی میکروکنترلرهای ARM جالب بود. بر اساس این ارزیابی، می‌توان نتیجه گرفت که آیا سرعت کافی برای پردازش جریانی از داده‌های صوتی و سیگنال با چه فرکانس نمونه‌برداری و چند کانال را می‌توان روی چنین میکروکنترلری پردازش کرد یا خیر.

بر اساس تبدیل فوریه، می توانید فیلترهای هوشمندانه ای (با ویژگی های بسیار جذاب) بسازید. من در درجه اول به مشکلات تغییر صدای سیگنال (بالا و کاهش طیف) و "انعکاس" طیف علاقه مند بودم. مورد دوم در رادیوهای SDR برای گوش دادن به پخش‌های رادیویی با باند پایین LSB مورد نیاز است.

من شما را با تئوری بار نمی کنم و توضیح نمی دهم که تبدیل فوریه چیست، مطالب بسیار زیادی در مورد این موضوع وجود دارد، از آنچه من استفاده کردم: یک ویکی و یک فصل از یک کتاب بسیار خوب و آموزنده.

پیاده سازی نرم افزار

پیاده سازی نرم افزارهای زیادی برای FFT وجود دارد، با این حال، من خودم نوشتم. هدف اصلی من بهینه سازی کد برای یک معماری خاص بود. اولاً من فوراً روی 32 بیت تمرکز کردم ، ثانیاً فقط محاسبات اعداد صحیح مورد نیاز بود و مطلوب بود که از عملیات تقسیم اجتناب شود. پیدا کردن چیزی آماده برای برآورده کردن این الزامات از قبل مشکل ساز است.

تمام ثابت هایی که از قبل قابل محاسبه بودند محاسبه و در جداول (عمدتا مقادیر توابع مثلثاتی) قرار گرفتند. این بهینه سازی اصلی الگوریتم است، در غیر این صورت تقریباً به طور کامل الگوریتم توصیف شده را تکرار می کند.

مهمترین مورد نیاز برای محاسبات اعداد صحیح است. در طول فرآیند پیاده سازی، حتی خطایی وجود داشت که باعث سرریز در یکی از متغیرهای حلقه 32 بیتی شد. علاوه بر این، در تمام داده‌های آزمایشی ظاهر نشد، بنابراین تا زمانی که پیدا شد باعث سردرد شد.

من تمام متون منبع را در یک آرشیو جمع آوری کردم. پیاده سازی نهایی نیست، محاسبات تکراری وجود دارد (تقارن طیف و فاز در نظر گرفته نمی شود) و بهینه سازی استفاده از بافرها مورد نیاز است، زیرا در حال حاضر رم بیش از حد برای محاسبات استفاده می شود (تقریبا 12k برای تبدیل 1024 امتیاز). ).

اولین تست ها

درام رول: من در حال آزمایش سرعت تبدیل برای نمونه ای از 1024 امتیاز هستم، فرکانس هسته پردازنده 60 مگاهرتز است. آزمایش در یک شبیه ساز انجام شد، بنابراین ادعا نمی کند که 100٪ دقیق است، اما این نتیجه می تواند به عنوان یک نشانگر استفاده شود (در تجربه قبلی من، اگرچه شبیه ساز دروغ گفت، اما زیاد نبود). تست نسخه اول کد، کامپایلر RealView MDK، گزینه بهینه سازی O3، حالت تولید کد ARM.

بنابراین آنچه می بینیم:

6 میلی‌ثانیه برای هر تبدیل، در مجموع کمی بیش از 12 میلی‌ثانیه برای تبدیل رفت و برگشت. به نظر می رسد که با فرکانس نمونه برداری 44100 هرتز (استاندارد برای صدا) و نمونه هایی با وضوح حداکثر 16 بیت، محاسبات خالص ~ 44 * 12 میلی ثانیه = 528 میلی ثانیه طول می کشد. و این در یک نسخه میانی از سیستم عامل است، زمانی که برخی از بهینه سازی کد هنوز کامل نشده است (طبق برآوردها، الگوریتم را می توان تقریباً 2 برابر شتاب داد)! به نظر من، این فقط یک شاخص عالی است.

در مجموع، انتظار می رود که بار اصلی حدود 50٪ باشد، 50٪ دیگر برای تبدیل در طیف و هزینه های سربار در هنگام کار با ADC، DAC و سایر انتقال داده ها باقی می ماند. اگر فرکانس نمونه برداری را به سطح "تلفن" (حدود 4800-9600 هرتز) کاهش دهید، بار هسته حتی کمتر می شود (حدود 15-30٪).

بنابراین، بخش ریاضی کم و بیش روشن است. می توانید به اجرای ملموس ادامه دهید.

اهن

برای پلتفرم تست، ما از یک برد توسعه Keil MCB2140 با یک بلندگو استفاده کردیم. یک سیم مینی جک برای اتصال به خروجی خطی دستگاه لحیم شده و یک زنجیره ورودی ساده مونتاژ می شود. همانطور که قبلا ذکر شد، برد از قبل دارای یک بلندگو است که به خروجی آنالوگ میکروکنترلر متصل است و کنترل هایی (دکمه و پتانسیومتر) وجود دارد.

در اینجا یک طرح از مدار ورودی است:


اشکال زدایی نرم افزار در مراحل زیر انجام شد:

  1. اشکال زدایی تمام لوازم جانبی لازم: ADC، DAC، تایمر، نشانگر LED.
  2. تست با دیجیتالی شدن سیگنال: داده ها را با سرعت مورد نیاز دیجیتالی می کنم و در بافر قرار می دهم، سپس داده ها را از بافر استخراج می کنم و سیگنال را پخش می کنم. آن ها تغییر سیگنال ساده در زمان، بدون هیچ تغییری. در این مرحله مکانیسم کار با 2 بافر لازم برای کار بیشتر مورد آزمایش قرار می گیرد.
  3. تبدیل فوریه رو به جلو و معکوس به نسخه قبلی اضافه شده است. این تست در نهایت عملکرد صحیح کد FFT را تأیید می کند و همچنین بررسی می کند که آیا کد با عملکرد موجود مطابقت دارد.
  4. پس از این، اسکلت اصلی اپلیکیشن انجام شد، می توانید به سراغ کاربردهای عملی بروید.

مشکل پس از اضافه کردن FFT به کد ایجاد شد: نویز و سوت های اضافی در سیگنال ظاهر شد. به طور کلی این رفتار برای من بسیار عجیب به نظر می رسید، زیرا ... بدون تبدیل، سیگنال عبوری از مسیر دیجیتال کاملاً تمیز باقی می ماند. دلیل اول برای این: پس از مدار آنالوگ، دامنه سیگنال در ADC کامل نبود (0-3.3V)، بلکه فقط در 0.5-2V در حداکثر حجم پخش کننده بود، دوم: نویز بسیار قوی به دلیل عدد صحیح محاسبات (+-1 واحد، که معلوم شد برای ایجاد تداخل شنیداری کافی است).

برای مبارزه با اولین مشکل، تصمیم گرفته شد تا تنظیم قسمت آنالوگ را آغاز کنیم. و برای حل مشکل نویز، از فیلتر پایین گذر استفاده کنید.

کاربرد 1: تغییر صدای سیگنال

برد دارای یک پتانسیومتر (مقاومت متغیر) است که می توان از آن برای کنترل استفاده کرد. در این مورد، طیف سیگنال را به سمت بالا و پایین تنظیم می کند، به اندازه ای که ترکیبات مورد علاقه شما را «تبدیل» کند.

در اینجا چیزی است که در حوزه فرکانس اتفاق می افتد:


در این مورد، نتیجه تبدیل در 2 بافر قرار می گیرد. یک بافر قسمت واقعی و دیگری قسمت خیالی است. معنای فیزیکی اعداد به دست آمده در آنها: بخش واقعی حاوی مقادیر هارمونیک ها است، بخش خیالی شامل تغییر فاز برای این هارمونیک ها است. علاوه بر این، همانطور که می بینید، سیگنال اولیه توسط N-value توصیف می شود و پس از تبدیل، مقدار 2N به دست می آید. مقدار اطلاعات تغییر نمی کند و افزایش 2 برابری در مقدار اطلاعات به دلیل این واقعیت است که داده های بافر دارای افزونگی در قالب تکرار مقادیر هستند.

یک نشانگر LCD کاراکتری دو خطی به عنوان دستگاه نمایشگر استفاده می شود. نکته اصلی در اجرای این پروژه سخت افزار نیست، بلکه نرم افزار، به طور دقیق تر پیاده سازی تبدیل فوریه گسسته (DFT) بر روی یک میکروکنترلر 8 بیتی است. فوراً باید توجه داشت که نویسنده در این زمینه متخصص نیست و بنابراین با مبانی شروع کرده است - با تبدیل فوریه گسسته ساده. الگوریتم تبدیل فوریه سریع نه تنها سریع است، بلکه بسیار پیچیده است.

تبدیل فوریه گسسته (در ادبیات انگلیسی DFT، تبدیل فوریه گسسته) یکی از تبدیل های فوریه است که به طور گسترده در الگوریتم های پردازش سیگنال دیجیتال استفاده می شود (اصلاحات آن در فشرده سازی صدا در MP3، فشرده سازی تصویر در JPEG و غیره) و همچنین در حوزه های دیگر مربوط به تجزیه و تحلیل فرکانس ها در یک سیگنال گسسته (به عنوان مثال، آنالوگ دیجیتالی شده). تبدیل فوریه گسسته به یک تابع گسسته به عنوان ورودی نیاز دارد. چنین توابعی اغلب با نمونه برداری (نمونه گیری مقادیر از توابع پیوسته) ایجاد می شوند.

نمودار مدار یک آنالایزر طیف سیگنال صوتی بسیار ساده است و می توان آن را به دو بخش دیجیتال و آنالوگ تقسیم کرد.

قسمت دیجیتال توسط یک میکروکنترلر و یک نشانگر LCD متصل به آن تشکیل می شود. میکروکنترلر از یک تشدید کننده کوارتز 16 مگاهرتز کلاک می شود. ولتاژ تغذیه +5 ولت به عنوان ولتاژ مرجع برای ADC میکروکنترلر استفاده می شود.
گذرگاه داده نشانگر LCD به پورت C میکروکنترلر (خطوط ورودی/خروجی PC0-PC3) و باس کنترل به پورت D (PD5, PD6) میکروکنترلر متصل است. نشانگر در حالت 4 بیتی کار می کند. برای تنظیم کنتراست از یک مقاومت متغیر با مقدار اسمی 4.7 کیلو اهم استفاده شده است. برای کار با نشانگر، نمادهای سفارشی برای نمایش 8 ستون افقی از آنالیزور ایجاد شدند.

میکروکنترلر از یک تشدید کننده کوارتز خارجی 16 مگاهرتز کار می کند.

قسمت آنالوگ دستگاه مهمترین قطعه و پیش تقویت کننده سیگنال میکروفون الکترت است که خروجی آن به کانال ADC0 ADC تعبیه شده در میکروکنترلر متصل می شود. ما باید سطح صفر را در ورودی ADC دقیقاً به نصف ولتاژ مرجع تنظیم کنیم، یعنی. 2.5 V. در این مورد، می توانیم از نیم موج مثبت و منفی سیگنال استفاده کنیم، اما دامنه آن نباید از حد تعیین شده، یعنی. بهره باید به خوبی تنظیم شود تا از اضافه بار جلوگیری شود. تمام شرایط فوق توسط یک تراشه تقویت کننده عملیاتی کم مصرف مشترک برآورده می شود.

الگوریتم DFT در مقایسه با تبدیل فوریه سریع کمی کندتر است. اما آنالایزر طیف ما به سرعت بالایی نیاز ندارد و اگر بتواند نرخ به روز رسانی حدود 30 فریم در ثانیه را ارائه دهد، این برای تجسم طیف سیگنال صوتی بیش از اندازه کافی خواهد بود. در هر صورت، در نسخه ما امکان دستیابی به سرعت 100 فریم در ثانیه وجود دارد، اما این مقدار پارامتر برای یک نشانگر LCD کاراکتری دو خطی بسیار زیاد است و توصیه نمی شود. فرکانس نمونه برداری برای تبدیل فوریه گسسته 32 نقطه ای 20 کیلوهرتز است و از آنجایی که نتیجه تبدیل متقارن است، فقط باید از نیمه اول استفاده کنیم. 16 نتیجه اول بنابراین می توانیم طیف فرکانس را تا 10 کیلوهرتز نمایش دهیم و وضوح آنالایزر 10 کیلوهرتز/16 = 625 هرتز است.

نویسنده طرح تلاش کرد تا سرعت محاسبات DFT را افزایش دهد. اگر این تبدیل N نقطه داشته باشد، باید مقادیر N2/2 سینوس و کسینوس را پیدا کنیم. برای تبدیل 32 نقطه ای ما باید 512 مقدار سینوس و کسینوس را پیدا کنیم. اما، قبل از پیدا کردن آنها، باید زاویه (درجه) را محاسبه کنیم، که مقداری زمان CPU را می گیرد، بنابراین تصمیم گرفته شد از جداول مقادیر برای این محاسبات استفاده کنیم. هنگام محاسبه در برنامه میکروکنترلر، از اعداد ممیز شناور و دقت مضاعف استفاده نمی شود، زیرا پردازش در یک میکروکنترلر 8 بیتی بیشتر طول می کشد. در عوض، مقادیر موجود در جداول جستجو از داده‌های عدد صحیح 16 بیتی ضرب در 10000 استفاده می‌کنند. سپس پس از انجام تبدیل، نتایج بر 10000 تقسیم می‌شوند. با این رویکرد، امکان انجام 120 تبدیل 32 نقطه‌ای در هر واحد وجود دارد. دوم، که برای دستگاه های ما بیش از اندازه کافی است.

نمایش عملکرد یک آنالایزر طیف بر روی میکروکنترلر ATmega32

دانلودها

کد منبع (برنامه میکروکنترلر، جداول داده های سینوسی، کسینوس و زاویه) -

  • واضح است که رفتن فراتر از نور و موسیقی در AVR دشوار است، پارامترها درست نیستند. اما 120 تبدیل 32 امتیازی در ثانیه ممکن است برای اکثر کارها کافی باشد. و البته می توانید نمونه دیگری با فرکانس 625 هرتز بگیرید یا بهتر است نرخ تازه سازی را از دست بدهید. شایان ذکر است که MK از نظر عملکرد احساس بدی خواهد داشت. اما در اینجا می توانید خروجی نتیجه را با استفاده از روش های انتقال داده های سخت افزاری سازماندهی کنید. سپس یک میکروکنترلر کمکی خواهد بود و اصلی‌ترین آن فقط داده‌ها را از آن دریافت می‌کند و آن را سازگار با سایر فرآیندها پردازش می‌کند. به طور کلی، هنوز هم به فرکانس پردازنده بستگی دارد. روزی روزگاری امکان اورکلاک مگا بالای 20 مگاهرتز وجود داشت، اما برای این کارها احتمالاً فقط در فرکانس های بالا دچار اشکال می شویم. ایده خوب است، اگر فقط قسمت های بیشتری از ریاضی نوشته شود ... این پیاده سازی آن در MK است
  • من همچنین تحلیلگرهای جالب تری ساخته ام: You Tube یا نسخه ای روی LCD رنگی: You Tube بر اساس کتابخانه معروف Chen است :)
  • "ما باید زاویه (درجه ها) را محاسبه کنیم" آیا کسی می تواند با جزئیات بیشتری به ما بگوید که مقادیر این جداول چگونه محاسبه می شوند؟
  • با جدول سینوس ها و کسینوس ها همه چیز مشخص است. مشخص نیست مقادیر جدول درجه_جستجو چگونه محاسبه می شوند؟

معرفی

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

این اثر تظاهر به کامل بودن و منسجم بودن نمی کند.

پس از خواندن نظرات اضافه شد.
انتشارات بی شماری در مورد نحوه ساخت FFT وجود دارد، اما به وضوح انتشارات کافی در مورد نحوه ساخت FFT، تبدیل طیف، و مونتاژ مجدد سیگنال و حتی در زمان واقعی وجود ندارد. نویسنده سعی دارد این خلأ را پر کند.

بخش اول، بررسی اجمالی

دو راه اصلی برای ساخت سیستم های دینامیکی خطی گسسته وجود دارد. در ادبیات، چنین سیستم هایی معمولاً فیلترهای دیجیتال نامیده می شوند که به دو نوع اصلی تقسیم می شوند: فیلترهای پاسخ ضربه محدود (FIR) و فیلترهای پاسخ ضربه نامحدود (IIR).

ماهیت الگوریتمی فیلتر FIR محاسبه گسسته انتگرال کانولوشن است:

جایی که x(t) سیگنال ورودی است
y (t) - سیگنال خروجی
h(t) – پاسخ ضربه ای فیلتر یا پاسخ فیلتر به تابع دلتا. پاسخ ضربه ای تبدیل فوریه معکوس پاسخ فرکانسی پیچیده فیلتر K(f) است.

برای ایجاد یک تصویر واضح برای خواننده، مثالی از محاسبه گسسته انتگرال کانولوشن در زبان C در زمان واقعی ارائه می دهیم.

#define L (4) //طول فیلتر int FIR(int a) ( static int i=0; // موقعیت فعلی static int reg[L]؛ //آرایه مقادیر ورودی Const static int h[L]= (1, 1,1,1);//پاسخ int b=0;//مقدار خروجی reg[i]=a; //مقدار ورودی را در آرایه مقادیر ورودی برای (int j=0) کپی کنید ;j

با فراخوانی این تابع در بازه های زمانی معین T و ارسال سیگنال ورودی به عنوان آرگومان، در خروجی سیگنال خروجی مربوط به واکنش فیلتر را با پاسخ ضربه ای به شکل زیر دریافت می کنیم:

H(t)=1 در 0 h(t)=0 در موارد دیگر.

برای همه حاضران، فیلتری با چنین پاسخ ضربه ای بهتر به عنوان "فیلتر میانگین متحرک" شناخته می شود و بر این اساس، اجرای آن بسیار ساده تر است. در این مورد، چنین پاسخ ضربه ای به عنوان مثال استفاده می شود.

مقالات زیادی به سنتز پاسخ های ضربه ای فیلترهای FIR اختصاص یافته است. نویسنده ابزار Buggy Filter Design را از بسته Matlab ترجیح می دهد، اما این یک موضوع سلیقه ای است.

با استفاده از فیلتری با پاسخ ضربه محدود، می توان کمی بالاتر از واقعیت معمول اوج گرفت، زیرا در طبیعت هیچ سیستم دینامیکی وجود ندارد که پاسخ ضربه محدودی داشته باشد. فیلتر FIR تلاشی برای ورود به دامنه زمان-فرکانس از طرف دیگر است، نه آنطور که طبیعت می‌رود، بنابراین ویژگی‌های فرکانس این فیلترها اغلب دارای ویژگی‌های غیرمنتظره هستند.

فیلترهایی با پاسخ ضربه بی نهایت به طبیعت نزدیکتر هستند. ماهیت الگوریتمی فیلترها با پاسخ ضربه ای نامتناهی به حل تکراری (با بازگشتی اشتباه نشود!) معادله دیفرانسیل توصیف کننده فیلتر است. یعنی هر مقدار بعدی سیگنال خروجی فیلتر بر اساس مقدار قبلی محاسبه می شود. این دقیقاً نحوه عملکرد فرآیندها در دنیای واقعی است. سنگی که در هر ثانیه از آسمان خراش سقوط می کند، سرعت خود را 9.8 متر بر ثانیه افزایش می دهد Speed=Speed+9.8، و مسافت طی شده هر ثانیه افزایش می یابد Distance=Distance+Speed. هر کی گفت این الگوریتم تکراری نیست، اولین نفری باشه که به من سنگ میزنه. فقط در ما ماتریسفاصله زمانی فراخوانی تابعی که موقعیت سنگ را برمی گرداند بسیار کمتر از قیمت تقسیم ابزار اندازه گیری در دسترس ما است.

به طور جداگانه، من می خواهم مفهوم "ترتیب فیلتر" را تعریف کنم. این تعداد متغیرهایی است که در معرض عملیات مکرر هستند. در مثال بالا تابعی که سرعت سنگ را برمی گرداند درجه اول است و تابعی که مسافت طی شده را برمی گرداند درجه دوم است.

برای اینکه در نهایت خواننده روشن شود، ساده ترین فیلتر پایین گذر را که به طور گسترده به عنوان فیلتر صاف کننده نمایی شناخته می شود، به زبان C مثال می زنیم.

#define alfa (2) //پارامتر صاف کردن int filter(int a) ( static int out_alfa=0; out_alfa=out_alfa - (out_alfa >>alfa) + a; return (out_alfa >> alfa); )

با فراخوانی این تابع با فرکانس F و ارسال سیگنال ورودی به عنوان آرگومان، سیگنال خروجی مربوط به پاسخ یک فیلتر پایین گذر مرتبه اول با فرکانس قطع دریافت می کنیم:

مثال ارائه شده از کد منبع از نقطه نظر درک ماهیت الگوریتم کاملاً غیرقابل درک است. از نظر ماهیت مکرر (به "سقوط سنگ" مراجعه کنید) الگوریتم، y=y+((x-y)>>آلفا) صحیح تر است؛ اما در این حالت کاهش آلفا قابل توجه است. ارقام عبارت فیلتر مکرر از کد مثال به گونه ای ساخته شده است که از دست دادن بیت های قابل توجه جلوگیری کند. این دقت محدود محاسبات است که می تواند زیبایی یک فیلتر دیجیتال را با پاسخ بی نهایت ضربه ای از بین ببرد. این امر به ویژه در فیلترهای درجه بالا با فاکتور کیفیت بالا قابل توجه است. در سیستم‌های دینامیک واقعی این مشکل به وجود نمی‌آید ماتریسمحاسباتی را با دقت باورنکردنی برای ما انجام می دهد.

ادبیات زیادی به سنتز چنین فیلترهایی اختصاص داده شده است و همچنین محصولات نرم افزاری آماده وجود دارد (به بالا مراجعه کنید).

بخش دوم. فیلتر فوریه

از دوره های دانشگاهی (برای شما واقعاً دوره OTEC بود)، بسیاری از حاضران دو رویکرد اصلی برای تجزیه و تحلیل سیستم های دینامیکی خطی را به خاطر دارند: تجزیه و تحلیل در حوزه زمان و تجزیه و تحلیل در حوزه فرکانس. تحلیل حوزه زمان حل معادلات دیفرانسیل، انتگرال کانولوشن و دوهامل است. این روش های تجزیه و تحلیل به طور مجزا در فیلترهای دیجیتال IIR و FIR گنجانده شده اند.

اما یک رویکرد فرکانسی برای تحلیل سیستم های دینامیکی خطی وجود دارد. گاهی اوقات به آن عملگر می گویند. تبدیل فوریه، تبدیل لاپلاس و غیره به عنوان عملگر استفاده می شود. در ادامه فقط در مورد تبدیل فوریه صحبت خواهیم کرد.

این روش آنالیز در ساخت فیلترهای دیجیتال کاربرد زیادی ندارد. نویسنده نتوانست توصیه های عملی منطقی برای ساخت چنین فیلترهایی به زبان روسی پیدا کند. تنها ذکر مختصری از چنین فیلتری در ادبیات عملی [Rabiner L., Gould B., Theory and Application of Digital Signal Processing 1978] است، اما در این کتاب توجه به چنین فیلتری بسیار سطحی است. در این کتاب این طرح ساخت فیلتر نام دارد: "پیچیدگی بلادرنگ با استفاده از روش FFT" که به نظر من به هیچ وجه بیانگر اصل نیست، نام باید کوتاه باشد وگرنه زمانی باقی نمی ماند. برای استراحت

پاسخ یک سیستم دینامیکی خطی تبدیل فوریه معکوس حاصلضرب تصویر فوریه سیگنال ورودی x(t) و ضریب انتقال مختلط K(f) است:

از نظر عملی، این عبارت تحلیلی روش زیر را در نظر می گیرد: تبدیل فوریه سیگنال ورودی را می گیریم، نتیجه را در ضریب انتقال مختلط ضرب می کنیم، تبدیل فوریه معکوس را انجام می دهیم که نتیجه آن سیگنال خروجی است. در زمان گسسته واقعی، این روش قابل انجام نیست. چگونه انتگرال را در طول زمان از منهای به مثبت بی نهایت ببریم؟! فقط در زمانی خارج از زمان می توان آن را گرفت...

در دنیای گسسته، ابزاری برای انجام تبدیل فوریه وجود دارد - الگوریتم تبدیل فوریه سریع (FFT). این همان چیزی است که ما هنگام پیاده سازی فیلتر فوریه خود از آن استفاده خواهیم کرد. آرگومان تابع FFT آرایه ای از نمونه های زمانی از 2^n عنصر است، نتیجه دو آرایه با طول 2^n عناصر مربوط به بخش های واقعی و خیالی تبدیل فوریه است. یکی از ویژگی های گسسته الگوریتم FFT این است که سیگنال ورودی به صورت دوره ای با فاصله 2^n در نظر گرفته می شود. این محدودیت هایی را بر روی الگوریتم فیلتر فوریه اعمال می کند. اگر دنباله‌ای از نمونه‌های سیگنال ورودی را بگیرید، یک FFT روی آن‌ها انجام دهید، نتیجه FFT را در بهره مختلط فیلتر ضرب کنید و تبدیل معکوس را انجام دهید. هیچ چیز کار نخواهد کرد!سیگنال خروجی دارای اعوجاج غیرخطی بزرگی در مجاورت اتصالات نمونه خواهد بود.

برای حل این مشکل، باید از دو تکنیک استفاده کنید:

  • 1. نمونه ها باید توسط تبدیل فوریه با همپوشانی پردازش شوند. یعنی هر نمونه بعدی باید شامل بخشی از نمونه قبلی باشد. در حالت ایده آل، نمونه ها باید با (2^n-1) نمونه همپوشانی داشته باشند، اما این نیاز به تلاش محاسباتی عظیمی دارد. در عمل، بیش از سه چهارم (2^n-2^(n-2))، نصف (2^(n-1)) و حتی یک چهارم همپوشانی (2^(n-2)) کافی است.
  • 2. نتایج تبدیل فوریه معکوس، برای به دست آوردن سیگنال خروجی، باید قبل از همپوشانی با یکدیگر در یک تابع وزنی (آرایه ای از ضرایب وزنی) ضرب شوند. تابع وزن دهی باید شرایط زیر را برآورده کند:
  • 2.1 در همه جا به جز بازه 2^n برابر با صفر است.
  • 2.2 در لبه های بازه به صفر میل می کند.
  • 2.3 و مهمتر از همه، مجموع توابع وزنی Fv(t) که با فاصله همپوشانی k جابجا شده اند باید ثابت باشد:

چنین توابعی به طور گسترده ای در فناوری پردازش سیگنال دیجیتال استفاده می شود و معمولاً به آنها پنجره گفته می شود. به نظر متواضع نویسنده، بهترین، از نظر عملی، پنجره ای به نام خان است:

شکل نمودارهایی را نشان می دهد که ویژگی های پنجره هان را با طول 2^n=256 نشان می دهد. نمونه های پنجره با نیمی از همپوشانی k=128 ساخته می شوند. همانطور که می بینید، تمام املاک ذکر شده در بالا موجود است.

به درخواست کارگران، شکل زیر نمودار محاسبات فیلتر فوریه را نشان می دهد، با طول نمونه 2^n=8، تعداد نمونه ها 3 می باشد. در چنین ارقامی نمایش روند محاسبات بسیار دشوار است. ، نشان دادن چرخه بودن آن به خصوص دشوار است، بنابراین تعداد نمونه ها را به سه محدود کردیم.

سیگنال ورودی به بلوک‌هایی به طول 2^n=8 با همپوشانی 50% تقسیم می‌شود، از هر بلوک یک FFT گرفته می‌شود، نتایج FFT تحت تبدیل لازم قرار می‌گیرد، FFT معکوس گرفته می‌شود، نتیجه FFT معکوس می‌شود. به صورت اسکالار در پنجره ضرب می شود، پس از ضرب بلوک ها با همپوشانی اضافه می شوند.

هنگام انجام تبدیل های طیف، ویژگی اصلی آرایه FFT سیگنال های واقعی را فراموش نکنید، نیمه اول آرایه FFT به طور پیچیده با نیمه دوم مزدوج است، یعنی Re[i]=Re[(1)<

اکنون همه چیزهایی را که برای نوشتن یک الگوریتم فیلتر فوریه نیاز داریم، می دانیم. بیایید الگوریتم را در زبان C توضیح دهیم.

#عبارتند از #تعریف FSempl (8000) //فرکانس نمونه برداری هرتز #تعریف BufL (64) //طول بافر پردازش #تعریف Perk (2) //همپوشانی فریم 2-1/2، 4-3/4 //محدودیت طیف، فیلتر باند #تعریف FsrLow (300)//فرکانس فیلتر پایین هرتز #تعریف FsrHi (3100)//فرکانس فیلتر بالا هرتز #تعریف FsrLowN ((BufL*FsrLow+(FSempl/2))/FSempl)//فرکانس پایین در هارمونیک ها #define FsrH ((BufL*FsrHi +(FSempl/2))/FSempl)//فرکانس بالا در هارمونیک ها //تغییر طیف #تعریف SdvigSp (0)//تغییر طیف در هارمونیک ها +(پایین) -(بالا) 0 (بدون تغییر) //فیلتر طیف زمانی، پژواک #define FilterSpekrtaT_EN (1)//استفاده از فیلتر طیف 1/0 #define FiltSpektrFsr (0.100025f) //فیلتر طیف قطع فرکانس فرار بدون علامت کوتاه ShBuf;// شمارنده بافر ورودی با امضای کوتاه BufIn;// بافر ورودی امضا شده کوتاه BufOut;//بافر خروجی امضا شده کوتاه BufInOut;//بافر برای بازنویسی float FurRe;//بخش واقعی فوریه float FurIm;//قسمت خیالی فوریه #if (FilterSpekrtaT_EN!=0) float FStektr;//filter طیف #endif //جدول کسینوس سینوسی #اگر BufL==64 شناور SinCosF= ( 0.000000000 , 0.098017140 , 0.195090322 , 0.290284677 , 0.347, 0.301, 0.32 55570233، 0.634393284، 0.707106781، 0.773010453، 0.831469612، 0.881921264، 0.923879533، 0.923879533، 0.938،0.95690 0.995184727 ، 1.000000000 ، 0.995184727 ، 0.980785280 ، 0.95694036 ، 0.923879533 ، 0.8881921264 ، 0.831469612 ، 0.77730101045 3 ، 0.770101045 3 ، 0.7730101045 3 ، 0.7730101045 3 ، 0.471396737 ، 0: 0.471396737، -0.555570233، -0.634393284، -0.707106781، -0.773010453، -0.831469612، -0.881921264، -0.881921263، -0.938 -0.93 0785280, -0.9 95184727 -1.000000000 -0.995184727 -0.980785280 -0.956940336 -0.923879533 -0.8261921 - ، -0.831469612 ، -0.773010453 ، -0.707106781 ، -0.634393284 ، -0.55570233 ، -0.471396737 ، -0.382683432 ، -0.290.29028467777 0 ، 0.000000000 ، 0.098017140 ، 0.195090322 ، 0.290284677 ، 0.382683432 ، 0.471396737 ، 0.555570233 ، 0.634393284 ، 0.70 7106781 , 0.773010453, 0.831469612 , 0.881921264 , 0.923879533 , 0.956940336 , 0.980785280 , 0.995184727 ); #endif //جدول مرتب‌سازی FFT #if BufL==64 مرتب‌سازی کوتاه بدون علامتFFT= ( 0x0000,0x0020,0x0008,0x0028,0x0018,0x0038,004,00,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 C، 0x002C، 0x001C، 0x003C 0x0002,0x0022,0x0012,0x0032,0x000A,0x002A,0x001A,0x003A, 0x0006,0x0026,0x0016,0x0036,0x0000E,2x000E,0x 1,0x0011,0x0031,0x0009,0x0029,0x0019,0x0039,0x0005, 0x0025,0x0015,0x0035,0x000D,0x002D,0x001D,0x003D, 0x0003,0x0023,0x0013,0x0033,0x000B,0x002B,070B,0x0 0x0017,0x0037,0x000F,0x002F,0x001F,0x003F )؛ #endif //جدول پنجره Han #if BufL==64 const float WinHanF= (0. 0 ، 0.002407637 ، 0.00960736 ، 0.021529832 ، 0.038060234 ، 0.084265194 ، 0.113494773 ، 0.1464609 ، 0.18280 33580 33580 33580 ، 284 ، 0: 0.853553391، 0.886505227، 0.915734806، 0.940960632، 0.961939766، 0.978470168، 0.99039264، 0.99039264، 0.99039264، 0.239 , 0,990 39264, 0,978470168, 0,961939766, 0,940960632, 0,915734806, 0,886505227, 0,853553391, 0.853553391, 0.85353391, 0.85353391, 0.85353391, 0.8533391, 0.8553391 5698368, 0.691341716, 0.645142339, 0.597545161, 0.54900857 0.5، 0.45099143، 0.402454839، 0.354857661، 0.308658284، 0.264301632، 0.222214883، 0.1828033154، 0.1828033158 0.08426519 4، 0.059039368، 0.038060234، 0.021529832، 0.00960736، 0.002407637); #endif //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@//محاسبه تبدیل فوریه مستقیم مستقیم //برهانها //اشاره به آرایه واقعی ReFT و قسمت خیالی ImFT //پس از اجرا، آرایه ها حاوی ضریب هستند. قسمت های واقعی و خیالی void FFTnoInv(float* ReFT,float* ImFT) (//کپی و تنظیم مجدد برای(int i=0;i >1; طولانی arg=0; //آگومان هسته، فاز برای (int j=0;j >1; طولانی arg=0;////آگومان هسته، فاز برای (int j=0;j 0 //طیف را به پایین تغییر دهید، Karabas-Barabas for(int i=1;i<(BufL/2);i++) { if(i>=(BufL/2-SdvigSp)) (FurRe[i]=FurIm[i]=0؛ FurRe=FurIm=0؛ ادامه؛ ) FurRe[i]=FurRe; FurIm[i]=FurIm; FurRe=FurRe[i]; FurIm=-FurIm[i]; ) #endif #if SdvigSp<0 //сдвиг спектра вверх, Буратино for(int i=(BufL/2-1);i>0;i--) (اگر(i<=(-SdvigSp)) { FurRe[i]=FurIm[i]=0; FurRe=FurIm=0; continue; } FurRe[i]=FurRe; FurIm[i]=FurIm; FurRe=FurRe[i]; FurIm=-FurIm[i]; } #endif //обрезание спектра, полосовой фильтр FurRe=0.0F;FurIm=0.0F; //постоянная составляющая FurRe[(BufL/2)]=0.0F;FurIm[(BufL/2)]=0.0F;//последняя гармоника float ZnStektr;//амплитудный спектр кадра for(int i=1;i<(BufL/2);i++) { if((i < FsrLowN)//нижняя частота || (i >FsrHiN)//فرکانس بالا) (//قطع طیف، هارمونیک های خارج از باند صفر هستند FurRe[i]=0.0F;FurIm[i]=0.0F;//هارمونیک های مستقیم FurRe=0.0F;FurIm=0.0F ;// هارمونیک های مزدوج ) else //محاسبه طیف دامنه قسمت بریده نشده ( ZnStektr[i]=sqrtf(FurRe[i]*FurRe[i])+(FurIm[i]*FurIm[i]);// طیف دامنه ) ) // فیلتر طیف دامنه در زمان، اکو برای (int i= FsrLowN;//فرکانس پایین تر i<=FsrHiN ;//верхняя частота i++) { #if FilterSpekrtaT_EN!=0 //фильтр спектра во времени, эхо FStektr[i]=FStektr[i]+ FiltSpektrFsr*(ZnStektr[i]-FStektr[i]); #endif //переходим от модуля к комплексному числу FurRe[i]=FurRe=(FStektr[i]*FurRe[i])/ZnStektr[i]; FurIm[i]=(FStektr[i]*FurIm[i])/ZnStektr[i]; FurIm=-FurIm[i]; } //выполняем обратное БПФ FFTInv(FurRe,FurIm); //копирование буферов for(int i=0;i<(BufL);i++) { BufInOut[i]=((signed short)(FurRe[i]+0.5f)); } } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //Фурье фильтр signed short FureFilter(signed short t1) { //записываем во входной буфер BufIn=t1; //выходное значение signed short out=BufOut; //инкремент указателя буфера ShBuf=(ShBuf+1)&((BufL*2)-1); //если в буфере часть кадра обработки if((ShBuf&((BufL/Perk)-1))==0) { //переписываем буфер обработки в выходной буфер int ShTmpOut=ShBuf; int ShTmpIn=(ShBuf-BufL)&((BufL*2)-1); for(int i=0;i<(BufL);i++) { if(i<(BufL-(BufL/Perk))) { //переписываем первую часть буфера обработки в выходной буфер BufOut=BufOut+BufInOut[i]; } else { //переписываем вторую часть буфера обработки в выходной буфер BufOut=BufInOut[i]; } //инкремент указателя выходного буфера ShTmpOut=(ShTmpOut+1)&((BufL*2)-1); //переписываем входной буфер в буфер обработки BufInOut[i]=BufIn; //инкремент указателя входного буфера ShTmpIn=(ShTmpIn+1)&((BufL*2)-1); } }//конец if((ShBuf&((BufL/Perk)-1))==0) //вызов функции обработки //в на реальном процессоре распараллелить! if((ShBuf&((BufL/Perk)-1))==0)ObrBuf(); return out; }

با فراخوانی تابع ()FureFilter با فرکانس FSempl و ارسال یک سیگنال ورودی به عنوان آرگومان، نتیجه یک سیگنال خروجی خواهد بود. در این مثال، سیگنال ورودی به صورت زیر پردازش می شود: سیگنال از یک فیلتر باند با فرکانس های قطع FsrLow، FsrHi عبور می کند، تمام اجزای طیفی بالا و پایین فرکانس های نشان داده شده سرکوب می شوند، طیف سیگنال جابجا می شود (برای سیگنال های صوتی این که به عنوان اثر Buratino-Karabas درک می شود، طیف دامنه سیگنال توسط یک فیلتر پایین گذر صاف می شود (برای صدا این اثر یک اتاق پررونق است). این اقدامات با سیگنال به عنوان نمونه به منظور نشان دادن تکنیک های فنی برای پردازش سیگنال در حوزه فرکانس انجام می شود، مانند: حفظ مزدوج پیچیده ضرایب، بازگرداندن طیف پیچیده از دامنه، بدون استفاده از توابع مثلثاتی و غیره.

نتیجه

شایان ذکر است که به احتمال زیاد، این عملکرد فیلتر فوریه در عمل کار نخواهد کرد. هنگام فراخوانی این تابع، حتی با فرکانس پایین 8000 هرتز، تا زمان تماس بعدی، زمان اجرای آن را نخواهد داشت، عملکرد کافی نخواهد بود. این کد فیلتر فوریه به عنوان توصیفی از الگوریتم، بدون اشاره به منابع سخت افزاری خاص ارائه شده است و صرفاً اهداف آموزشی دارد (به مقدمه مراجعه کنید).

در اجرای عملی، لازم است که اجرای تابع پر کردن-تخلیه بافر BufInOut (ترجیحاً DMA و غیره) و تابع پردازش بافر (ObrBuf) را موازی کنیم، اما این یک داستان کاملاً متفاوت است.

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

تبدیل فوریه سریع

تبدیل فوریه سریع یک الگوریتم محاسباتی است که با موفقیت از خواص تناوب توابع مثلثاتی برای جلوگیری از محاسبات غیر ضروری در تبدیل فوریه گسسته (DFT) استفاده می‌کند و در نتیجه یافتن ضرایب در بسط فوریه را سریع‌تر می‌کند. تفاوت اصلی با تبدیل گسسته فقط در روش محاسبه مقادیر عددی (الگوریتم) است و نه در خود پردازش سیگنال. هم در مورد FFT و هم در مورد DFT نتیجه محاسبات یکسان است. تنها مورد نیاز برای الگوریتم FFT یک اندازه نمونه است که مضربی از N = 2L باشد، که در آن L هر عدد صحیح مثبت است. متداول‌ترین الگوریتم‌های FFT پایه 2 عبارت‌اند از: کاهش‌دهنده زمان و کاهش فرکانس.

در این کار، یک الگوریتم FFT radix-2 با نازک شدن زمان (الگوریتم Cooley-Tukey) پیاده سازی شده است. با مطالعه برخی از قوانین DFT به راحتی به دست می آید. بیایید به اصطلاح ضریب چرخش را معرفی کنیم:

در این حالت، در DFT، ضرایب فوریه برای تعدادی از مقادیر سیگنال (f0,f1,…,fN-1) با این رابطه بیان می شود:

یک سری سیگنال از 4 مقدار را در نظر بگیرید: (f0,f1,f2,f3). اجازه دهید تبدیل فوریه را به شکل ماتریس ارائه کنیم (ضریب نرمال سازی 1/N در بردار ستون Cij در سمت راست عبارت گنجانده شده است):

پس از نوشتن ضرایب چرخش با استفاده از فرمول اویلر و تعیین مقادیر آنها برای k = 0، 1، 2،.. 9، می توانید نموداری بسازید (شکل 2) که از آن الگوی تکرار ضرایب قابل مشاهده است.

شکل 2. سری توان w برای N=4

با جایگزینی مقادیر عددی به (4) دریافت می کنیم:

یعنی مقادیر w از w4 با مقدار مربوطه از w0 تا w3 برابر است. در مرحله بعد، معادله ماتریس (4) را به شکل غیر استاندارد بازنویسی می‌کنیم (نشان‌های مشابه برای وضوح عملیات بیشتر معرفی می‌شوند):

بیایید ستون های ماتریس را با هم عوض کنیم و آن را به دو گروه تقسیم کنیم: با شاخص های زوج f0، f2 و فرد f1، f3:

اجازه دهید در نظر بگیریم که wk+1 = wkw1، سپس عبارت (6) به صورت زیر بازنویسی می‌شود:

با استفاده از نسبت ها:

ضرایب انبساط مورد نیاز را در قالب یک بردار ستونی با مقادیر سلول بدست می آوریم:

نمایش گرافیکی الگوریتم (شکل 3) شبیه یک پروانه با بال های باز است، به همین دلیل است که این روش محاسبه "پروانه" نامیده می شود.

شکل 3. نمودار پروانه ای برای یک سری از 4 عبارت

بنابراین، در مرحله اول الگوریتم، اعضای یک سری مقادیر سیگنال به دو شاخص زوج و فرد تقسیم می شوند. سپس نمودار "پروانه" اجرا می شود که از دو مرحله تشکیل شده است که تعداد آنها برابر است با توان دو عدد از اندازه نمونه (N = 4 = 22). در هر مرحله، دو "پروانه" اجرا می شود و تعداد کل آنها بدون تغییر باقی می ماند. هر عمل پروانه مربوط به یک عملیات ضرب است. برای مقایسه: در DFT با نمونه برداری (f0,f1,f2,f3) عملیات ضرب باید 4×4 = 16 بار و در مورد FFT فقط 4 بار انجام شود.

تئوری

اول، کمی تئوری. همانطور که همه می دانند، چنین تحلیلگرهایی از تبدیل فوریه سریع استفاده می کنند و اغلب گفته می شود که DFT را نمی توان در چنین طراحی هایی استفاده کرد، فقط از FFT و حتی در اسمبلر استفاده کرد. من از تبدیل فوریه گسسته (DFT) و تبدیل والش به جای آن استفاده کردم. و در این مقاله من ثابت خواهم کرد که شما حتی می توانید نه تنها از FFT، بلکه از DFT که به زبان C نوشته شده است استفاده کنید. DFT به طور کلاسیک به این صورت است:

از آنجایی که μ منابع کمی دارد، cos و sin را با آرایه‌هایی با ابعاد N جایگزین می‌کنند. علاوه بر این، μ 8 بیتی است و ذخیره آرایه‌ها در قالب مقادیر 8 بیتی مصلحت‌تر است. از آنجایی که cos و sin از 1- تا 1 متفاوت هستند، بهتر است این محدوده را 127 برابر افزایش دهید، زیرا یک متغیر علامت دار 8 بیتی می تواند مقادیر را از 127- تا 127 ذخیره کند. بنابراین، با در نظر گرفتن تبدیل فرمول ، خواهد بود:

جایی که m از 0 به N-1 با پله ای برابر با k تغییر می کند، وقتی m بزرگتر از N می شود، m با N-1 کاهش می یابد. در مجموع از 12 کانال استفاده می شود، بنابراین قدرت DFT به تعداد کمی از کانال ها محدود می شود.

به عنوان مثال، ما 512 نمونه ADC داریم که باید قطعات موهومی و واقعی را برای 150 هرتز در فرکانس نمونه برداری 19200 هرتز محاسبه کنیم.

بنابراین، قطعات واقعی و خیالی بسیار سریعتر از روش سنتی، اما 127 برابر بزرگتر به دست می آیند. برای به دست آوردن مقادیر واقعی آنها باید بر 127 تقسیم کنید، اما MK تقسیم ندارد، بسیار منطقی تر است که شعر را تقسیم نکنید، بلکه آن را تغییر دهید! یک شیفت برابر است با تقسیم بر 2. یعنی اگر یک عدد را 7 بار جابجا کنید، در اصل آن را بر 128 تقسیم می کنید! از آنجایی که از دست دادن دقت در حال حاضر اجتناب ناپذیر بود، تقسیم بر 128 تصویر را تغییر نخواهد داد.

تبدیل فوریه گسسته برای 150 هرتز با نرخ نمونه برداری 19200 هرتز به شکل زیر است:

برای والش، امواج سینوسی و کسینوس را با میانگین های دوره های مربوطه جایگزین می کنیم. یعنی برای گناه از 0 تا 180 درجه 1 و از 180> تا 360 می شود -1. بر این اساس، برای یک سینوس از 0 تا 90 برابر 1، از 90 تا 270 برابر با 1 است و از 270 تا 360 برابر با 1 است. مقدار ADC یعنی وقتی مثلاً سینوس برابر با 1 باشد مقدار ADC اضافه می شود و وقتی -1 کم می شود. عیب این راه حل باز هم خطا است که به ناچار افزایش می یابد و به 20 درصد می رسد. اما از آنجایی که طرح من فقط 8 مقدار دارد، باز هم افراد کمی متوجه تفاوت قابل توجهی خواهند شد.

نمونه ای از اجرای محاسبه قطعات خیالی و واقعی برای 150 هرتز در فرکانس نمونه برداری 19200 و 512 نمونه:

به این ترتیب قسمت های خیالی و واقعی را خیلی سریع و بدون مراحل ضرب بدست می آوریم.

و بنابراین، با به دست آوردن قسمت های خیالی و واقعی، باید دامنه طیف را پیدا کرد. برای این کار باید ریشه مجموع مربعات قسمت های خیالی و واقعی را پیدا کنید. اما اگر از یک تابع از کتابخانه ریاضی استفاده کنید، استخراج زمان زیادی طول می کشد و تابع نیز یک قطعه نسبتاً بزرگ رام را می خورد. پس از کمی جستجو در اینترنت، یک عملکرد زیبا پیدا کردم، که به دلیل این واقعیت که بر روی مقادیر کوچک کار می کند، آن را کمی ساده تر کردم. این تابع است:

با مقایسه این تابع و تابع از کتابخانه ریاضی، به این نتیجه رسیدم که دقت آن برای یکسان بودن نتیجه کافی است. خود عملکرد 2% در مقابل 12% رام MK وزن دارد. علاوه بر این، بسیار سریعتر محاسبه می کند.

اما چگونه شد که MK موفق به محاسبه 12 کانال و حتی در DFT شد. در کنار تمام ترفندهای شیفت به جای تقسیم و تابع مربع سریع، یک ترفند دیگر نیز وجود دارد. که الان بهت میگم واقعیت این است که هرچه فرکانس انتخاب بیشتر باشد، باند عبور فیلتر باریکتر می شود، زیرا انتقال cos و sin تسریع می شود و تعداد دوره ها افزایش می یابد. و هر چه تعداد پاس‌های cos و sin بیشتر باشد، پهنای باند کمتر می‌شود. به عنوان مثال برای فرکانس 150 هرتز، cos و sin 4 بار و برای 1.2 کیلوهرتز، cos و sin 32 بار تکرار می شوند. از اینجا می توان دریافت که برای اینکه باند عبور در همه محدوده ها یکنواخت باشد و همه محدوده های فرکانسی را پوشش دهد، باید با افزایش فرکانس فیلتر تعداد نمونه ها کاهش یابد. به عنوان مثال، برای 150 هرتز تمام 512 نمونه، برای 600 هرتز 256 نمونه، و برای 2.4 کیلوهرتز 32 نمونه و غیره حفاری می شوند. جایگزین کردن آن با کاهش تعداد نمونه ها با افزایش فرکانس، کار سختی نیست، سرعت DFT به شدت افزایش می یابد، زیرا ضرب و مجموع بسیار کمتری باید انجام شود.

پیاده سازی عملی

و بنابراین قسمت تئوری آماده می شود، می توانیم شروع به توصیف طرح کنیم. کل طراحی شامل یک میکروکنترلر، 4 ترانزیستور، چندین خازن و مقاومت های زیادی است. بهتر است تعداد زیادی مقاومت نصب کنید، اگرچه می توانید خود را فقط به مقاومت های افقی محدود کنید، یعنی. برای هر پین پورت یکی این طرح کلاسیک است، به جز تنها موردی که من از 3 پورت در هر 1 پاس اسکن پویا به جای 1 استفاده کردم، همانطور که در همه جاهای دیگر انجام می دهند. این امکان کاهش فرکانس اسکن و کاهش تعداد ترانزیستورها را به 4 فراهم کرد. نتیجه در واقع مقیاس 24x4 بود.

آنالایزر طیف با نرخ نمونه برداری 19.2 کیلوهرتز از یک کریستال 16 مگاهرتز کار می کند.

تحلیلگر طیف، دامنه های طیفی فرکانس های زیر را محاسبه می کند:

9.6 کیلوهرتز، 4.8 کیلوهرتز، 2.4 کیلوهرتز، 1.6 کیلوهرتز، 1.2 کیلوهرتز، 800 هرتز، 600 هرتز، 500 هرتز، 400 هرتز، 300 هرتز، 150 هرتز، 75 هرتز. این برنامه برای 33 هرتز آزمایش شد و DFT با وجود اینکه ابعاد cos و sin برابر با 512 شد موفق شد، اما تصمیم گرفت آن را به 75 هرتز محدود کند.

در اینجا فرکانس هایی وجود دارند که مضرب 2 به توان n نیستند، اما با این وجود محاسبه می شوند. به عنوان مثال، 400 هرتز وقتی بر 19200 تقسیم می شود، 48 به دست می آید که مضربی از 2 به توان n نیست. با گرفتن عددی نزدیک به عدد 2 به توان n راهی برای خروج از موقعیت انتخاب کردم. نزدیکترین آن 240 است، نزدیک به 256 است. یعنی از 512 نمونه فقط 240 نمونه برداشتیم. علاوه بر این، شما نمی توانید چیزی را نزدیک کنید. برای مثال، می‌توانیم 480 را بگیریم که نزدیک به 512 است، اما با این وجود ما نزدیک به 256 گرفتیم. توضیح این موضوع این است که در فرکانس‌های مختلف تعداد نمونه‌ها بر پهنای باند تأثیر می‌گذارد. هر چه تعداد نمونه ها بیشتر باشد، پهنای باند کمتر می شود. این به این دلیل است که در فرکانس بالا کسینوس دوره ای را بسیار سریعتر از فرکانس پایین طی می کند و دامنه آنقدر دقیق محاسبه می شود که فرکانس های همسایه به سادگی به بیرون پرتاب می شوند و مناطق فرکانس کور بین فرکانس هایی که درک نمی شوند تشکیل می شود. توسط آنالیزور برای اینکه آنالایزر تمام فرکانس ها را درک کند و کل طیف را پوشش دهد، لازم است باند را در فرکانس های بالا با گرفتن نمونه های کمتر گسترش داد و در فرکانس های پایین تا حد امکان با گرفتن نمونه های بیشتر آن را محدود کرد. بنابراین، با انتخاب عملی تعداد خواندن، موارد زیر را انتخاب کردم:

9.6 کیلوهرتز 16 شمارش، 4.8 کیلوهرتز 32 شمارش، 2.4 کیلوهرتز 32 شمارش، 1.6 کیلوهرتز 64 شمارش، 800 هرتز 240 شمارش، 600 هرتز 250 شمارش، 250 عدد تعداد، 300 هرتز 512 شمارش، تعداد 150 هرتز 512، تعداد 75 هرتز 512.

این انتخاب تعداد نمونه ها باعث شد که باند در کل محدوده فرکانس یکنواخت باشد.

یک دام دیگر در فرکانس 9.6 کیلوهرتز رخ داد. از آنجایی که هیچ بخش خیالی وجود ندارد (این را می توان به راحتی با جایگزین کردن عدد طیف 256 در فرمول بالا با 512 نمونه بررسی کرد و سینوس همیشه برابر با 0 خواهد بود)، بخش واقعی می تواند به شدت تغییر کند به دلیل این واقعیت که مقدار کسینوس هر بار در پادفاز سیگنال اصلی محاسبه خواهد شد. یعنی یکبار محاسبه خواهد شد. برای جلوگیری از این امر، لازم است حداقل 2 مقدار از قسمت واقعی که 90 درجه جابجا شده است را محاسبه کرده و حداکثر دو مقدار را انتخاب کنید.

الگوریتم برنامه 512 نمونه را در بازه زمانی جمع آوری می کند، میکروکنترلر را به حالت خواب منتقل می کند و زمانی که نمونه بعدی آماده شد بیدار می شود. علاوه بر این، LED ها با فرکانس 150 هرتز اسکن می شوند - این 128 برابر فرکانس نمونه برداری 19200 است. یعنی قبل از اینکه ADC همه نمونه ها را بگیرد، زمان لازم برای تکمیل یک اسکن کامل را خواهد داشت. به محض آماده شدن تمام نمونه ها، تمام دامنه های طیف در چرخه برنامه اصلی محاسبه می شود. در این زمان، جارو ادامه می یابد، اما MK به خواب نمی رود، بلکه دامنه ها را می شمارد. به محض محاسبه دامنه ها، میکروکنترلر به حالت خواب می رود و برنامه دوباره تکرار می شود. دامنه ها بر اساس محدوده 20 دسی بل محاسبه می شوند، یعنی لگاریتمی هستند.

بر اساس زمان دریافت همه قرائت ها و زمان محاسبه تمام دامنه ها، فرکانس به روز رسانی در منطقه 10-15 هرتز است.


دنیای برنامه های رایگان و نکات مفید
2024 whatsappss.ru