Микроконтроллер дээрх Фурье хувиргалт. Дохионы спектрийн шинжилгээ. Хурдан Фурье хувиргалт

Энгийн бүхэл тоон цөм, хөвөгч цэгийн өгөгдлийг боловсруулдаг C6000 гэр бүлийн дэд бүлэг гэх мэт мангасуудыг багтаасан Texas Instruments TMS320 цувралын DSP зэрэг дижитал дохио боловсруулах (DSP) олон тусгай процессорууд байдаг. Analog Devices-ийн бүхэл бүтэн цуврал ADSP байдаг (үүнд бүх нийтийн BlackFin багтдаг), MicroChip - dsPIC-ээс илүү хялбар шийдлүүд байдаг.

Гэсэн хэдий ч тусгай DSP сайн, гэхдээ энэ нь үргэлж шаардлагатай байдаг уу? Тийм ээ, асар их мэдээллийн урсгалтай бол үүнийг орлуулшгүй, гэхдээ боловсруулахад хялбар даалгавар байдаг. Тодруулбал, би давхар хөрвүүлэх даалгаврыг сонирхож байсан - аудио дохио нь эргэлдэж, улмаар спектрийг олж авдаг бөгөөд дараа нь спектр дээр ямар ч үйлдлүүдийг хийж, урвуу хувиргалтыг хийж, улмаар боловсруулсан дохиог олж авдаг. Энэ бүгдийг бодит цаг хугацаанд хийж, утасны чанараас доогуур биш чанарыг авах хэрэгтэй.

Энэ бол 2000 он биш, өндөр хүчин чадалтай ARM7/Cortex-M3 цөмд суурилсан нэг чиптэй шийдлүүд байгаа бөгөөд үнэ нь мэдэгдэхүйц буурсан; тэдгээр нь 32 бит, 32 битийн үржүүлэх үйлдлийн техник хангамжийн хэрэгжилттэй (түүнээс гадна) , бараг DSP үржүүлэх-хуримтлуулах үйлдэл ба 64 битийн үр дүн), Cortex-M3 нь мөн техник хангамжийн хуваагдлыг агуулдаг.

Дохио боловсруулах нь миний мэргэжил биш гэдгийг би даруй анхааруулахыг хүсч байна, бараг бүх мэдлэг (эсвэл зарчмын талаархи ойлголт) хүрээлэнгээс хадгалагдан үлдсэн боловч одоо би үүнийг туршиж, хэрэгжүүлэхийг хүссэн. Миний хэлэх гэсэн зүйл бол тайлбар, ойлголтыг орлуулах гэх мэт алдаатай байж магадгүй юм. Үнэндээ эрдэм шинжилгээний нарийвчлал намайг нэг их санаа зовсонгүй.

Бараг ямар ч DSP-ийн хувьд дээр дурдсан даалгавар нь энгийн бөгөөд ойлгомжтой байдаг. Гэхдээ ерөнхий зориулалтын RISC цөм үүн дээр хэрхэн ажиллах вэ? Хэрэв бид AVR эсвэл PIC гэж үзвэл тэдгээр нь хангалттай байх магадлал багатай. 8 бит ба бага цагийн давтамж нөлөө үзүүлдэг. Хэдийгээр Элм-Чан нь AVR дээр FFT хийж, дохионы спектрийг зурдаг загвартай байдаг. Гэсэн хэдий ч энэ тохиолдолд бодит цаг хугацаанд зөвхөн дүрслэлийг (боловсруулах хамгийн бага нарийвчлалтайгаар) хийдэг бөгөөд дохиог хүлээн авах боломжтой аудио чанараар бүрэн боловсруулдаггүй.

LPC2146-ийг туршилтын чип болгон сонгосон бөгөөд ARM7TDMI-S цөмд суурилсан бөгөөд хамгийн их давтамж нь 60 МГц (практикт 72 эсвэл бүр 84 МГц давтамжтай ажилладаггүй). Яагаад? Нэгдүгээрт, надад дибаг хийх самбар байгаа, хоёрдугаарт, самбар дээр ADC ба DAC байдаг, өөрөөр хэлбэл. хамгийн бага гадаад обудтай байх шаардлагатай.

Бага зэрэг онол

Юуны өмнө ARM микроконтроллерууд дээрх FFT (Fast Fourier Transform)-ийн гүйцэтгэлийг үнэлэх нь сонирхолтой байв. Энэхүү үнэлгээнд үндэслэн бид аудио мэдээллийн урсгалыг боловсруулахад хангалттай хурдтай эсэх, ийм микроконтроллер дээр ямар түүвэрлэлтийн давтамж, хэдэн сувгийг боловсруулах боломжтой дохиог дүгнэж болно.

Фурье хувиргалт дээр үндэслэн та ухаалаг шүүлтүүр (маш сэтгэл татам шинж чанартай) бүтээж болно. Би дохионы аяыг өөрчлөх (спектрийг өсгөх, багасгах) болон спектрийг "тусгах" асуудлуудыг голчлон сонирхож байсан. Сүүлийнх нь LSB доод зурвасын радио нэвтрүүлгийг сонсохын тулд SDR радиод шаардлагатай.

Би танд онол ачихгүй бөгөөд Фурье хувиргалт гэж юу болохыг тайлбарлахгүй; миний ашигласан зүйлээс энэ сэдвээр маш олон материал байгаа: вики, маш сайн, мэдээлэл сайтай номын нэг бүлэг.

Програм хангамжийн хэрэгжилт

FFT-ийн програм хангамжийн олон хувилбарууд байдаг, гэхдээ би өөрөө бичсэн. Миний зорьж байсан гол зорилго бол тодорхой архитектурын кодыг оновчтой болгох явдал байв. Нэгдүгээрт, би тэр даруй 32 бит дээр анхаарлаа төвлөрүүлсэн, хоёрдугаарт, зөвхөн бүхэл тоон тооцоолол хийх шаардлагатай байсан тул хуваах үйлдлээс зайлсхийх нь зүйтэй болов. Эдгээр шаардлагыг хангахад бэлэн зүйлийг олох нь аль хэдийн асуудалтай байдаг.

Урьдчилан тооцоолж болох бүх тогтмолуудыг тооцоолж, хүснэгтэд байрлуулсан (ихэвчлэн тригонометрийн функцүүдийн утгууд). Энэ бол алгоритмын гол оновчлол бөгөөд өөрөөр хэлбэл энэ нь тайлбарласан алгоритмыг бараг бүрэн давтах болно.

Хамгийн чухал нь бүхэл тоон тооцоонд тавигдах шаардлага юм. Хэрэгжүүлэх явцад 32 битийн давталтын хувьсагчийн аль нэгэнд халихад хүргэсэн алдаа гарсан. Түүгээр ч барахгүй туршилтын бүх өгөгдөл дээр харагдахгүй байсан тул олдох хүртэл нэлээд толгой өвдсөн.

Би бүх эх бичвэрийг нэг архивт цуглуулсан. Хэрэгжилт нь эцсийнх биш, давхардсан тооцоолол (спектр ба фазын тэгш хэмийг тооцдоггүй) байгаа бөгөөд буферийн ашиглалтыг оновчтой болгох шаардлагатай, учир нь тооцоололд хэт их хэмжээний RAM ашигладаг (1024 цэгийг хөрвүүлэхэд бараг 12к) ).

Эхний туршилтууд

Бөмбөрийн оролт: Би хөрвүүлэх хурдыг 1024 цэгийн дээжээр туршиж байна, процессорын гол давтамж нь 60 МГц. Туршилтыг эмулятор дээр хийсэн тул 100% үнэн зөв гэж хэлэхгүй, гэхдээ энэ үр дүнг үзүүлэлт болгон ашиглаж болно (миний өмнөх туршлагаас харахад эмулятор худал хэлж байсан ч тийм ч их биш байсан). Кодын эхний хувилбарын туршилт, RealView MDK хөрвүүлэгч, O3 оновчтой болгох сонголт, ARM код үүсгэх горим.

Тэгэхээр бид юу харж байна:

Хөрвүүлэлт бүрт 6 мс, хоёр талдаа хөрвүүлэхэд нийтдээ 12 мс гаруй. Дээж авах давтамж 44100 Гц (аудиогийн стандарт) ба 16 бит хүртэлх нарийвчлалтай дээжтэй бол цэвэр тооцоололд ~ 44 * 12 мс = 528 мс шаардлагатай болно. Энэ нь зарим кодын оновчлол хараахан дуусаагүй байгаа програм хангамжийн завсрын хувилбар дээр байна (тооцооллоор алгоритмыг бараг 2 дахин хурдасгах боломжтой)! Миний бодлоор энэ бол зүгээр л маш сайн үзүүлэлт юм.

Нийтдээ үндсэн ачаалал нь ойролцоогоор 50% байх төлөвтэй байгаа бөгөөд ADC, DAC болон бусад өгөгдөл дамжуулахтай ажиллах үед спектрийн хөрвүүлэлт, нэмэлт зардалд 50% үлдэх болно. Хэрэв та дээж авах давтамжийг "утас" түвшинд (ойролцоогоор 4800-9600 Гц) бууруулбал үндсэн ачаалал бүр бага (ойролцоогоор 15-30%) байх болно.

Тэгэхээр математикийн хэсэг нь их бага тодорхой байна. Та тодорхой хэрэгжилтийг үргэлжлүүлж болно.

Төмөр

Туршилтын платформын хувьд бид чанга яригчтай Keil MCB2140 хөгжүүлэх самбар ашигласан. Төхөөрөмжийн шугаман гаралттай холбохын тулд Mini-Jack утсыг гагнаж, энгийн оролтын хэлхээг угсардаг. Өмнө дурьдсанчлан, самбар нь микроконтроллерийн аналог гаралттай холбогдсон чанга яригчтай бөгөөд удирдлага (товчлуур ба потенциометр) байдаг.

Энд оролтын хэлхээний тойм зураг байна.


Програм хангамжийн дибаг хийх үе шаттайгаар явагдсан:

  1. Шаардлагатай бүх дагалдах хэрэгслийн дибаг хийх: ADC, DAC, таймер, LED заалт.
  2. Дохионы дижиталчлалтай тест: Би өгөгдлийг шаардлагатай хурдаар дижитал болгож, буферт хийж, дараа нь буферээс өгөгдлийг гаргаж аваад дохиог тоглуулдаг. Тэдгээр. ямар ч өөрчлөлтгүйгээр цаг хугацааны энгийн дохио шилжилт. Энэ үе шатанд цаашдын ажилд шаардлагатай 2 буфертэй ажиллах механизмыг туршиж байна.
  3. Урд болон урвуу Фурье хувиргалтыг өмнөх хувилбарт нэмсэн. Энэхүү тест нь эцэст нь FFT кодын зөв ажиллаж, код нь боломжит гүйцэтгэлд нийцэж байгаа эсэхийг шалгадаг.
  4. Үүний дараа програмын үндсэн араг яс хийгдсэн тул та практик хэрэглээ рүү шилжиж болно.

Код дээр FFT нэмсний дараа асуудал үүссэн: дохионд гадны чимээ, шүгэл гарч ирэв. Ерөнхийдөө энэ зан надад их хачин санагдсан, учир нь... Хөрвүүлэлт хийлгүйгээр тоон замаар дамждаг дохио нь нэлээд цэвэр хэвээр байв. Үүний эхний шалтгаан нь: аналог хэлхээний дараа ADC дээрх дохионы далайц бүрэн биш байсан (0-3.3V), гэхдээ тоглуулагчийн хамгийн их эзлэхүүн дээр зөвхөн 0.5-2V дотор байсан бол хоёр дахь нь: бүхэл тооноос болж нэлээд хүчтэй дуу чимээ. тооцоолол (+-1 нэгж, энэ нь сонсогдоход саад учруулахад хангалттай байсан).

Эхний асуудалтай тэмцэхийн тулд аналог хэсгийг тохируулж эхлэхээр шийдсэн. Дуу чимээний асуудлыг шийдэхийн тулд бага нэвтрүүлэх шүүлтүүр ашиглаж үзээрэй.

Хэрэглээ 1: дохионы аяыг өөрчлөх

Самбар нь потенциометртэй (хувьсах резистор) бөгөөд үүнийг удирдахад ашиглаж болно. Энэ тохиолдолд энэ нь таны дуртай зохиолуудыг "өөрчлөх" хангалттай дохионы спектрийг дээш доош шилжүүлэхээр тохируулдаг.

Давтамжийн домэйнд юу болдог вэ:


Энэ тохиолдолд хөрвүүлэлтийн үр дүн 2 буферт агуулагдана. Нэг буфер нь бодит хэсэг, нөгөө нь төсөөллийн хэсэг юм. Тэдгээрээс олж авсан тоонуудын физик утга нь: бодит хэсэг нь гармоникуудын утгыг агуулдаг бол төсөөлөл нь эдгээр гармоникуудын фазын шилжилтийг агуулдаг. Үүнээс гадна, таны харж байгаагаар анхны дохиог N-утгуудаар дүрсэлсэн бөгөөд хөрвүүлсний дараа 2N-утгыг олж авдаг. Мэдээллийн хэмжээ өөрчлөгдөхгүй бөгөөд мэдээллийн хэмжээ 2 дахин нэмэгдэх нь буфер өгөгдөл нь утгын давхардал хэлбэрээр илүүдэлтэй байгаатай холбоотой юм.

Хоёр мөрт тэмдэгтийн LCD үзүүлэлтийг дэлгэцийн төхөөрөмж болгон ашигладаг. Энэ төслийг хэрэгжүүлэх гол зүйл бол техник хангамж биш, харин програм хангамж, илүү нарийвчлалтай 8 битийн микроконтроллер дээр дискрет Фурье хувиргалтыг (DFT) хэрэгжүүлэх явдал юм. Зохиогч нь энэ чиглэлээр мэргэшсэн мэргэжилтэн биш тул үндсэн ойлголтоос эхлээд энгийн Furier хувиргалтаас эхэлсэн гэдгийг нэн даруй тэмдэглэх нь зүйтэй. Хурдан Фурье хувиргах алгоритм нь хурдан төдийгүй нэлээд төвөгтэй юм.

Дискрет Фурье хувиргалт (Англи уран зохиолд DFT, Discrete Fourier Transform) нь дижитал дохио боловсруулах алгоритмд өргөн хэрэглэгддэг Фурье хувиргуудын нэг юм (түүний өөрчлөлтийг MP3 форматаар аудио шахах, JPEG форматаар дүрсийг шахах гэх мэт) ашигладаг. салангид (жишээлбэл, дижитал аналог) дохионы давтамжийг шинжлэхтэй холбоотой бусад хэсгүүд. Дискрет Фурье хувиргалт нь дискрет функцийг оролт болгон шаарддаг. Ийм функцийг ихэвчлэн түүвэрлэлт (үргэлжилсэн функцүүдээс түүврийн утгууд) үүсгэдэг.

Аудио дохионы спектр анализаторын хэлхээний диаграм нь маш энгийн бөгөөд тоон болон аналог хэсэгт хуваагддаг.

Дижитал хэсэг нь микроконтроллер ба түүнд холбогдсон LCD индикатороос бүрдэнэ. Микроконтроллер нь 16 МГц-ийн кварцын резонатороос ажилладаг бөгөөд +5 В тэжээлийн хүчдэлийг микроконтроллерийн ADC-ийн лавлах хүчдэл болгон ашигладаг.
LCD индикаторын өгөгдлийн автобус нь микроконтроллерийн C порттой (PC0-PC3 оролт/гаралтын шугамууд), хяналтын автобус нь микроконтроллерийн D (PD5, PD6) порттой холбогдсон. Заагч нь 4 битийн горимд ажилладаг. 4.7 кОм-ийн нэрлэсэн утгатай хувьсах резисторыг тодосгогчийг тохируулахад ашигладаг. Заагчтай ажиллахын тулд анализаторын 8 хэвтээ баганыг харуулах тусгай тэмдэгтүүдийг бүтээсэн бөгөөд эдгээр тусгай тэмдэгтүүд нь LCD үзүүлэлтийн бүх 64 байт RAM-ыг эзэлдэг.

Микроконтроллер нь гадны 16 МГц кварц резонатороос ажилладаг.

Төхөөрөмжийн аналог хэсэг нь хамгийн чухал хэсэг бөгөөд цахилгаан микрофоны дохионы урьдчилсан өсгөгч бөгөөд гаралт нь микроконтроллерт суурилуулсан ADC-ийн ADC0 сувагт холбогдсон байдаг. Бид ADC оролт дээрх тэг түвшинг лавлагааны хүчдэлийн яг хагаст тохируулах хэрэгтэй, өөрөөр хэлбэл. 2.5 V. Энэ тохиолдолд бид дохионы эерэг ба сөрөг хагас долгионыг ашиглаж болох боловч түүний далайц нь тогтоосон хязгаараас хэтрэхгүй байх ёстой, i.e. Хэт ачааллаас сэргийлэхийн тулд олзыг нарийн тохируулах ёстой. Дээрх бүх нөхцөлийг бага чадлын үйлдлийн өсгөгчийн нийтлэг микро схемээр хангадаг.

DFT алгоритм нь Fast Fourier Transform-тай харьцуулахад арай удаан байдаг. Гэхдээ манай спектрийн анализатор нь өндөр хурд шаарддаггүй бөгөөд хэрэв энэ нь секундэд 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 МГц-ээс дээш мега-г overclock хийх боломжтой байсан ч эдгээр даалгаврын хувьд бид зөвхөн өндөр давтамжтай үед алдаа гарах болно. Санаа сайн байна, хэрвээ илүү олон тооны математикийн хэсгүүдийг бичсэн бол ... энэ нь MK дээр хэрэгжсэн явдал юм
  • Би бас илүү сонирхолтой анализатор хийсэн: You Tube эсвэл өнгөт LCD дээрх хувилбар: You Tube нь алдарт Чен номын сан дээр суурилдаг :)
  • "Бид өнцгийг (градус) тооцоолох хэрэгтэй" Эдгээр хүснэгтийн утгыг хэрхэн тооцдог талаар хэн нэгэн бидэнд илүү дэлгэрэнгүй хэлж чадах уу?
  • Синус ба косинусын хүснэгтээр бүх зүйл тодорхой байна. Зэрэглэл_хайлтын хүснэгт дэх утгыг хэрхэн тооцдог нь тодорхойгүй байна уу?

Оршил

Дижитал дохионы боловсруулалтын талаархи ном, хэвлэлийг зохиогчид ихэвчлэн хөгжүүлэгчдэд тулгарч буй бэрхшээлүүдийн талаар ямар ч ойлголтгүй, ойлгодоггүй зохиогчид бичсэн байдаг. Энэ нь ялангуяа бодит цаг хугацаанд ажилладаг системүүдийн хувьд үнэн юм. Эдгээр зохиолчид өөрсдийгөө цаг хугацаа, орон зайнаас гадуур орших бурхны дүрд даруухан үүрэг гүйцэтгэдэг нь ийм уран зохиолын уншигчдын дунд эргэлзээ төрүүлдэг. Энэхүү нийтлэл нь ихэнх хөгжүүлэгчдийн дунд үүссэн төөрөгдлийг арилгах, "орох босго"-ыг даван туулахад нь туслах зорилготой бөгөөд эдгээр зорилгоор текст нь програмчлалын талбараас аналоги, нэр томъёог зориудаар ашигладаг.

Энэхүү зохиол нь бүрэн, уялдаа холбоотой дүр эсгэдэггүй.

Сэтгэгдэл уншсаны дараа нэмсэн.
Хэрхэн 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]; //оролтын утгуудын массив static const int h[L]= (1, 1,1,1);//импульсийн хариу үйлдэл int b=0;//гаралтын утга reg[i]=a; //оролтын утгыг for(int j=0) оролтын утгуудын массив руу хуулна. ;ж

Энэ функцийг тодорхой хугацааны T интервалаар дуудаж, оролтын дохиог аргумент болгон дамжуулснаар гаралт дээр бид импульсийн хариу үйлдэл бүхий шүүлтүүрийн хариутай тохирох гаралтын дохиог хүлээн авах болно.

0-д H(t)=1 бусад тохиолдолд h(t)=0.

Энд байгаа бүх хүмүүст ийм импульсийн хариу үйлдэл бүхий шүүлтүүрийг "хөдөлгөөнт дундаж шүүлтүүр" гэж нэрлэдэг бөгөөд үүний дагуу хэрэгжүүлэхэд илүү хялбар байдаг. Энэ тохиолдолд ийм импульсийн хариу урвалыг жишээ болгон ашигладаг.

Олон тооны уран зохиолыг FIR шүүлтүүрийн импульсийн хариу урвалын нийлэгжилтэд зориулдаг бөгөөд тодорхой шинж чанартай шүүлтүүрийг олж авахад бэлэн програм хангамжийн бүтээгдэхүүнүүд байдаг. Зохиогч нь Matlab багцын алдаатай шүүлтүүрийн дизайны хэрэгслийг илүүд үздэг боловч энэ нь амттаны асуудал юм.

Хязгаарлагдмал импульсийн хариу үйлдэл бүхий шүүлтүүрийг ашигласнаар ердийн бодит байдлаас бага зэрэг дээшлэх боломжтой, учир нь байгальд хязгаарлагдмал импульсийн хариу үйлдэл бүхий динамик систем байдаггүй. FIR шүүлтүүр нь цаг хугацааны давтамжийн домэйнд байгалийн жам ёсоор бус нөгөө талаас нь оруулах оролдлого тул эдгээр шүүлтүүрүүдийн давтамжийн шинж чанар нь ихэвчлэн гэнэтийн шинж чанартай байдаг.

Хязгааргүй импульсийн хариу үйлдэл бүхий шүүлтүүрүүд нь байгальд илүү ойр байдаг. Хязгааргүй импульсийн хариу үйлдэл бүхий шүүлтүүрүүдийн алгоритмын мөн чанар нь шүүлтүүрийг тодорхойлсон дифференциал тэгшитгэлийн давтагдах (рекурсивтай андуурч болохгүй!) шийдэлд хүрдэг. Өөрөөр хэлбэл, шүүлтүүрийн гаралтын дохионы дараагийн утга бүрийг өмнөх утга дээр үндэслэн тооцдог. Бодит ертөнцөд үйл явц яг ийм байдлаар явагддаг. Тэнгэр баганадсан байшингаас секунд тутамд унасан чулуу хурдаа 9.8 м/с-ээр нэмэгдүүлж Хурд=Хурд+9.8, туулсан зам нь секунд тутамд нэмэгддэг Зай=Зай+Хурд. Энэ нь давтагдах алгоритм биш гэж хэн хэлсэн ч тэр над руу хамгийн түрүүнд чулуу шидэх болтугай. Зөвхөн манайд МатрицЧулууны байрлалыг буцаадаг функцийг дуудах хугацааны интервал нь бидэнд байгаа хэмжих хэрэгслийн хуваах үнээс хамаагүй бага байна.

Би "шүүлтийн дараалал" гэсэн ойлголтыг тусад нь тодорхойлохыг хүсч байна. Энэ нь давтагдах үйлдлүүдэд хамаарах хувьсагчдын тоо юм. Дээрх жишээн дээр чулууны хурдыг буцаадаг функц нь нэгдүгээр зэрэглэлийн, туулсан зайг буцаадаг функц нь хоёрдугаар эрэмбийнх юм.

Эцэст нь уншигчдыг гэгээрүүлэхийн тулд бид "экспоненциал гөлгөр шүүлтүүр" гэгддэг хамгийн энгийн бага нэвтрүүлэх шүүлтүүрийн жишээг Си хэлээр өгөх болно.

#альфаг тодорхойлох (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)>>alfa); гэхдээ энэ тохиолдолд альфа мэдэгдэхүйц алдагдалтай байна. цифрүүд. Жишээ кодын давтагдах шүүлтүүрийн илэрхийлэл нь чухал битийг алдахгүй байхаар бүтээгдсэн. Хязгааргүй импульсийн хариу үйлдэл бүхий дижитал шүүлтүүрийн гоо үзэсгэлэнг сүйтгэж болох тооцооллын эцсийн нарийвчлал юм. Энэ нь ялангуяа өндөр чанарын хүчин зүйл бүхий өндөр зэрэглэлийн шүүлтүүрүүдэд мэдэгдэхүйц юм. Бодит динамик системд энэ асуудал гардаггүй; бидний Матрицбидний хувьд гайхалтай нарийвчлалтай тооцоолол хийдэг.

Ийм шүүлтүүрийн нийлэгжилтэд маш олон уран зохиол зориулагдсан бөгөөд бэлэн програм хангамжийн бүтээгдэхүүнүүд байдаг (дээрхийг үзнэ үү).

Хоёрдугаар хэсэг. Фурье шүүлтүүр

Их сургуулийн хичээлүүдээс (таны хувьд энэ нь үнэхээр OTEC курс байсан) ихэнх хүмүүс шугаман динамик системд дүн шинжилгээ хийх хоёр үндсэн аргыг санаж байна: цаг хугацааны мужид дүн шинжилгээ хийх ба давтамжийн муж дахь шинжилгээ. Цагийн домэйн шинжилгээ нь дифференциал тэгшитгэл, эргэлт ба Духамелийн интегралын шийдэл юм. Эдгээр шинжилгээний аргуудыг дижитал IIR болон FIR шүүлтүүрт тусад нь тусгасан болно.

Гэхдээ шугаман динамик системийн шинжилгээнд давтамжийн хандлага байдаг. Заримдаа үүнийг оператор гэж нэрлэдэг. Фурье хувиргалт, Лапласын хувиргалт гэх мэтийг оператор болгон ашигладаг. Дараах зүйлд бид зөвхөн Фурье хувирлын тухай ярих болно.

Энэхүү шинжилгээний аргыг дижитал шүүлтүүр барихад өргөн ашигладаггүй. Зохиогч орос хэл дээр ийм шүүлтүүр бүтээх талаар эрүүл саруул практик зөвлөмжийг олж чадаагүй байна. Практик уран зохиолд ийм шүүлтүүрийн тухай товч дурдагдсан цорын ганц зүйл бол [Rabiner L., Gould B., Theory and Application of Digital Signal Processing 1978] боловч энэ номонд ийм шүүлтүүрийг авч үзэх нь маш өнгөцхөн байдаг. Энэхүү номонд шүүлтүүрийн угсралтын схемийг "FTT аргыг ашиглан бодит цагийн эргэлт" гэж нэрлэдэг бөгөөд энэ нь миний даруухан бодлоор мөн чанарыг огт тусгаагүй, нэр нь богино байх ёстой, эс тэгвээс цаг хугацаа үлдэхгүй. амрах зорилгоор.

Шугаман динамик системийн хариу үйлдэл нь оролтын дохио 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 Мөн хамгийн чухал нь k давхцлын интервалаар шилжсэн Fv(t) жингийн функцүүдийн нийлбэр тогтмол байх ёстой.

Ийм функцийг тоон дохио боловсруулах технологид өргөн ашигладаг бөгөөд тэдгээрийг ихэвчлэн цонх гэж нэрлэдэг. Зохиогчийн даруухан бодлоор практик талаасаа хамгийн сайн нь Хааны нэрэмжит цонх юм.

Зураг дээр 2^n=256 урттай Hahn цонхны шинж чанарыг харуулсан графикуудыг үзүүлэв. Цонхны тохиолдлуудыг k=128 хагас давхцалтайгаар бүтээдэг. Таны харж байгаагаар дээр дурдсан бүх шинж чанарууд бэлэн байна.

Ажилчдын хүсэлтээр Фурье шүүлтүүрийн тооцооны диаграммыг дараах зурагт үзүүлэв, дээжийн урт нь 2^n=8, дээжийн тоо 3. Ийм зурагт тооцооны үйл явцыг харуулах нь маш хэцүү байдаг. нь түүний мөчлөгийг харуулах нь ялангуяа хэцүү байдаг тул бид дээжийн тоог 3 хүртэл хязгаарласан.

Оролтын дохиог 2^n=8 урттай блокуудад хувааж, 50% давхцаж, блок бүрээс FFT авч, FFT-ийн үр дүнг шаардлагатай хувиргалт хийж, урвуу FFT-ийг авч, урвуу FFT-ийн үр дүн цонхоор скаляраар үржүүлж, үржүүлсний дараа блокуудыг давхцуулж нэмнэ.

Спектрийн хувиргалтыг хийхдээ бодит дохионы FFT массивын үндсэн шинж чанарыг мартаж болохгүй, FFT массивын эхний хагас нь хоёр дахь хагастай нарийн нийлдэг, өөрөөр хэлбэл Re[i]=Re[(1)<

Одоо бид Фурье шүүлтүүрийн алгоритмыг бичихэд хэрэгтэй бүх зүйлийг мэддэг болсон. Алгоритмыг Си хэлээр тайлбарлая.

#оруулна #define FSempl (8000) //Түүвэрлэлтийн давтамж Гц #define BufL (64) //буферийн уртыг боловсруулж байна #define Perk (2) //фрэймийн давхцал 2-1/2, 4-3/4 //спектр хязгаарлах, зурвас дамжуулах шүүлтүүр #define FsrLow (300)//бага шүүлтүүр давтамж Гц #define FsrHi (3100)//high filter давтамж Гц #define FsrLowN ((BufL*FsrLow+(FSempl/2))/FSempl)//гармоник дахь бага давтамжийг #define FsrHiN ((BufL*FsrHi +(FSempl/2))/FSempl)//гармоник дахь өндөр давтамж //Спектрийн шилжилт #define SdvigSp (0)//гармоник дахь спектрийн шилжилт +(доош) -(дээш) 0 (шилжилт байхгүй) //Цагийн спектрийн шүүлтүүр, echo #define FilterSpekrtaT_EN (1)//спектр шүүлтүүрийг ашиглах 1/0 #define FiltSpektrFsr (0.100025f) //спектр шүүлтүүрийн таслах давтамж тогтворгүй шинж тэмдэггүй богино ShBuf;//оролтын буфер тоолуур тэмдэгт богино BufIn;/ / оролтын буфер гарын үсэг зурсан богино BufOut;//гаралтын буфер гарын үсэг зурсан богино BufInOut;//хөвөгчийг дахин бичих буфер FurRe;//Фурьегийн бодит хэсэг хөвөх FurIm;//Фурьегийн төсөөлөл хэсэг #if (FilterSpekrtaT_EN!=0) float FStektr;//tude спектр #endif //Синусын косинусын хүснэгт #if BufL==64 const float SinCosF= ( 0.000000000 , 0.098017140 , 0.195090322 , 0.290284677 , 0.3826875 , 0.3826835 , 3234. 0233, 0.634393284, 0.707106781, 0.773010453, 0.831469612, 0.881921264, 0.923879533, 0.956940398, 0.956940338, 0.995184727, 1.000000000, 0.995184727, 0.980785280, 0.956940336, 0.923879533, 0.881921264, 0.881921264, 0.87014, 0.87013. 106781 , 0.634393284 , 0.555570233 , 0.471396737 , 0.382683432 , 0.290284677 , 0.195090328 , 0.195090328 , 0.00, 0.10000. 98017140, -0.195090322, -0.290284677, -0.382683432, - 0,471396737 , -0,555570233, -0,634393284, -0,707106781, -0,773010453, -0,831469612, -0,881921264, -0,881921264, -0,9593, -0,9593, -0,9593, -0,9593, 785280, -0.99 5184727, -1.000000000, -0.995184727, -0.980785280, -0.956940336, -0.923879533, -0.88192126 , - 0,831469612, -0,773010453, -0,707106781, -0,634393284, -0,555570233, -0,471396737, -0,382683432, -0,382683432, -0,902, -8902, -8902, -0,902 980 17140, 0.000000000, 0.098017140, 0.195090322, 0.290284677, 0.382683432, 0.471396737, 0.5355507, 0.535557, 0.5355507, 980. 81 , 0,773010453, 0,831469612, 0,881921264, 0,923879533, 0,956940336, 0,980785280, 0,995184727); #endif //FFT эрэмбэлэх хүснэгт #if BufL==64 const unsigned short sortFFT= ( 0x0000,0x0020,0x0010,0x0030,0x0008,0x0028,0x0018,0x0038, 0x0004,0400,0x0, 0x0004,040,0x0,0x x002C, 0x001C, 0x003C , 0x0002,0x0022,0x0012,0x0032,0x000A,0x002A,0x001A,0x003A, 0x0006,0x0026,0x0016,0x0036,0x0016,0x0036,0300,E00,E00 0x0001, 0x0021,0x0011,0x0031,0x0009,0x0029,0x0019,0x0039, 0x0005 ,0x0025,0x0015,0x0035,0x000D,0x002D,0x001D,0x003D, 0x0003,0x0023,0x0013,0x0033,0x0025,0x0000,B,0x000,B,0x000,B x0027,0 x0017,0x0037,0x000F,0x002F,0x001F,0x003F ); #endif //Han цонхны хүснэгт #if BufL==64 const float WinHanF= ( 0. 0, 0.002407637, 0.00960736, 0.021529832, 0.038060234, 0.059039368, 0.084265194, 0.113494776, 0.113494774, 0.113494774, 0.021529832, 0.608.5 22214883, 0,264301632, 0,308658284, 0,354857661, 0,402454839, 0,45099143, 0,5, 0,54900857, 0,54900857, 0,516215, 0,59015, 0,5919, 516413. 1716, 0.735698368, 0.777785117, 0.817196642, 0.853553391, 0.886505227, 0.915734806, 0.940960632, 0.961939766, 0.978470168, 0.99039264, 0.99039264, 0.9907, 0.99759, 36079.3. 9903 9264, 0.978470168, 0.961939766, 0.940960632, 0.915734806, 0.886505227, 0.853553391, 0.8427, 0.81717, 0.8427195. 68, 0.691341716, 0.645142339, 0.597545161, 0.54900857, 0.5, 0.45099143, 0.402454839, 0.354857661, 0.308658284, 0.264301632, 0.222214883, 0.182803358, 0.182803358, 0.4901, 0.354857661. 084265194, 0.059039368, 0.038060234, 0.021529832, 0.00960736, 0.002407637); #endif //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Хурдан Фурьегийн шууд хувиргалтын тооцоо //аргументууд //Бодит массивын заагч ReFT ба төсөөллийн хэсэг ImFT //Гүйцэтгэлийн дараа массивууд нь коэффициентийг агуулна. Бодит болон төсөөллийн хэсгүүд хүчингүй FFTnoInv(float* ReFT,float* ImFT) ( //for(int i=0;i) хуулж, дахин зохион байгуулах >1; урт arg=0; //цөмийн аргумент, үе шат for(int j=0;j >1; long arg=0;////цөмийн аргумент, үе шат for(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]);// далайцын спектр ) ) // далайцын спектрийн шүүлтүүр цаг хугацааны хувьд, echo for(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; }

FSempl давтамжтай FureFilter() функцийг дуудаж, оролтын дохиог аргумент болгон дамжуулснаар үр дүн нь гаралтын дохио болно. Энэ жишээнд оролтын дохиог дараах байдлаар боловсруулдаг: дохио нь FsrLow, FsrHi таслах давтамж бүхий зурвасын шүүлтүүрээр дамждаг, заасан давтамжаас дээш ба доорх бүх спектрийн бүрэлдэхүүн хэсгүүд дарагдаж, дохионы спектр шилждэг (аудио дохионы хувьд энэ нь Буратино-Карабасын эффект гэж ойлгогддог), дохионы далайцын спектрийг нам дамжуулалтын шүүлтүүрээр жигд болгодог (дууны хувьд энэ нь эрчимтэй хөгжиж буй өрөөний эффект юм). Дохиотой эдгээр үйлдлүүдийг давтамжийн муж дахь дохиог боловсруулах техникийн аргуудыг харуулахын тулд жишээ болгон гүйцэтгэдэг: коэффициентүүдийн нарийн төвөгтэй холболтыг хадгалах, тригонометрийн функцийг ашиглахгүйгээр далайцаас цогц спектрийг сэргээх гэх мэт.

Дүгнэлт

Энэ Фурье шүүлтүүрийн функц практик дээр ажиллахгүй байх магадлалтай гэдгийг тэмдэглэх нь зүйтэй. Энэ функцийг дуудах үед 8000 Гц-ийн бага давтамжтай байсан ч дараагийн дуудлагын үеэр ажиллах цаг гарахгүй, гүйцэтгэл хангалтгүй байх болно. Энэхүү Фурье шүүлтүүрийн код нь тодорхой техник хангамжийн нөөцөд ишлэлгүйгээр алгоритмын тайлбар хэлбэрээр өгөгдсөн бөгөөд зөвхөн боловсролын зорилготой (Танилцуулга хэсгийг үзнэ үү).

Практик хэрэгжилтийн хувьд буфер дүүргэх-хооллох функц BufInOut (илүү зохимжтой DMA гэх мэт) болон буфер боловсруулах ObrBuf() функцийг зэрэгцүүлэх шаардлагатай боловч энэ нь огт өөр түүх юм.

Фурьегийн теорем нь аливаа дохиог үечилсэн дохионы давтамжийн үржвэртэй давтамжтай үечилсэн функцуудын (жишээлбэл, синус ба косинус) ортонормаль багц дахь цуврал болгон өргөжүүлж болно гэж заасан. Тиймээс дохионы спектрийн шинжилгээ нь жингийн коэффициентийг (ерөнхий тохиолдолд, цогцолбор) хайхад суурилдаг бөгөөд модуль нь бүх гармоникийн ерөнхий суперпозицияд оруулсан харгалзах гармоникийн хэлбэлзлийн хүчний фракцтай тохирч байна.

Хурдан Фурье хувиргалт

Хурдан Фурье хувиргалт нь тригонометрийн функцүүдийн үечилсэн шинж чанарыг амжилттай ашигладаг тооцооллын алгоритм бөгөөд салангид Фурье хувиргалт (DFT) -д шаардлагагүй тооцоолол хийхээс зайлсхийх, улмаар Фурье тэлэлтийн коэффициентийг хурдан олох боломжийг олгодог. Дискрет хувиргалтаас гол ялгаа нь зөвхөн тоон утгыг (алгоритм) тооцоолох аргад байдаг бөгөөд дохиог өөрөө боловсруулахад биш юм. FFT-ийн хувьд ч, DFT-ийн хувьд ч тооцооллын үр дүн ижил байна. FFT алгоритмд тавигдах цорын ганц шаардлага нь түүврийн хэмжээ нь N = 2L-ийн үржвэр бөгөөд L нь эерэг бүхэл тоо юм. Хамгийн түгээмэл суурь-2 FFT алгоритмууд нь: цаг хугацааны бууралт ба давтамжийн бууралт юм.

Энэ ажилд цаг хугацааны сийрэгжилт бүхий radix-2 FFT алгоритмыг (Cooley-Tukey алгоритм) хэрэгжүүлсэн. Зарим DFT хуулиудыг судалснаар олж авахад хялбар байдаг. Эргэлтийн коэффициент гэж нэрлэгддэг зүйлийг танилцуулъя.

Энэ тохиолдолд DFT-д хэд хэдэн дохионы утгын Фурье коэффициентийг (f0,f1,…,fN-1) дараах харьцаагаар илэрхийлнэ.

4 утгын дохионы цувааг авч үзье: (f0,f1,f2,f3). Фурье хувиргалтыг матриц хэлбэрээр үзүүлье (нэвчиллийн коэффициент 1/N нь илэрхийллийн баруун талд байрлах Cij баганын векторт багтсан болно):

Эйлерийн томъёог ашиглан эргэлтийн коэффициентийг бичиж, k = 0, 1, 2, .. 9-ийн утгыг тодорхойлсны дараа та диаграммыг (Зураг 2) байгуулж, үүнээс давтагдах коэффициентүүдийн загварыг харж болно.

Зураг 2. N=4-ийн хувьд w чадлын цуваа

Тоон утгыг (4)-д орлуулснаар бид дараахь зүйлийг авна.

Өөрөөр хэлбэл, w4-ээс эхлэн w-ийн утга нь 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 ашиглаж болно гэдгийг нотлох болно, Харин C-д бичигдсэн DFT Гэхдээ эхлээд, дарааллаар, хэрхэн DFT болон Walsh дагуу энгийн DFT функцийг олж авах. DFT нь сонгодог байдлаар дараах байдалтай байна.

μ нь цөөн нөөцтэй тул cos болон sin-ийг N хэмжээст массиваар орлуулдаг. Үүнээс гадна μ нь 8 бит тул массивыг 8 битийн утгын хэлбэрээр хадгалах нь илүү тохиромжтой. Cos болон sin нь -1-ээс 1 хооронд хэлбэлздэг тул 8 битийн тэмдэгт хувьсагч нь -127-оос 127 хүртэлх утгыг хадгалах боломжтой тул энэ мужийг 127 дахин нэмэгдүүлэх нь зүйтэй. Тиймээс томьёоны хувиргалтыг харгалзан үзнэ. , энэ нь байх болно:

Энд m нь 0-ээс N-1 болж k-тэй тэнцүү алхамаар өөрчлөгддөг бол m N-ээс их бол m нь N-1-ээр буурдаг. Нийт 12 суваг ашигладаг тул DFT-ийн хүч нь ийм цөөн тооны сувгаар хязгаарлагддаг.

Жишээлбэл, бидэнд 512 ADC дээж байгаа бөгөөд бид 19200 Гц дээж авах давтамж дээр 150 Гц-ийн төсөөлөл болон бодит хэсгүүдийг тооцоолох хэрэгтэй.

Тиймээс бодит болон төсөөллийн хэсгүүд нь уламжлалт аргаар хамаагүй хурдан, гэхдээ 127 дахин том хэмжээтэй байдаг. Тэдний жинхэнэ утгыг авахын тулд та 127-д хуваах хэрэгтэй, гэхдээ МК-д хуваагдах зүйл байхгүй, шүлгийг хуваахгүй, харин шилжүүлэх нь илүү оновчтой байх болно! Нэг ээлж нь 2-т хуваагдсантай тэнцэнэ. Өөрөөр хэлбэл, хэрэв та тоог 7 удаа шилжүүлбэл 128-д хуваана! Нарийвчлалын алдагдал аль хэдийн зайлшгүй байсан тул 128-д хуваах нь дүр төрхийг өөрчлөхгүй.

19200 Гц түүвэрлэлтийн хурдаар 150 Гц-ийн дискрет Фурье хувиргах нь дараах байдалтай байна.

Уолшийн хувьд бид синус ба косинусын долгионыг тухайн үеийн дундаж утгуудаар солино. Өөрөөр хэлбэл, нүглийн хувьд 0-ээс 180 градус хүртэл 1, >180-аас 360 хүртэл -1 байх болно. Үүний дагуу 0-ээс 90 хүртэлх синус нь 1, 90-ээс 270 хүртэл -1, 270-аас 360 хүртэл 1 байна. Тиймээс төсөөлөл ба бодит хэсгүүдийн бүх тооцоо нь нийлбэр ба ялгааны энгийн хуримтлал байх болно. ADC утга. Жишээлбэл, синус 1-тэй тэнцүү бол ADC утгыг нэмж, -1-ийг хасах үед. Энэ шийдлийн сул тал нь дахин алдаа бөгөөд энэ нь зайлшгүй нэмэгдэж, 20% хүрдэг. Гэхдээ миний загвар ердөө 8-хан утгатай тул цөөхөн хүн мэдэгдэхүйц ялгааг анзаарах болно.

19200 ба 512 дээжийн дээж авах давтамж дээр 150 Гц-ийн төсөөлөл ба бодит хэсгүүдийг тооцоолох хэрэгжилтийн жишээ:

Ингэснээр бид үржүүлгийн процедургүйгээр төсөөлөл болон бодит хэсгүүдийг маш хурдан олж авдаг.

Тиймээс төсөөллийн болон бодит хэсгүүдийг олж авсны дараа спектрийн далайцыг олох шаардлагатай болно. Үүнийг хийхийн тулд та төсөөлөл ба бодит хэсгүүдийн квадратуудын нийлбэрийн үндсийг олох хэрэгтэй. Гэхдээ хэрэв та математикийн номын сангийн функцийг ашиглавал задлахад удаан хугацаа шаардагдах бөгөөд функц нь ROM-ийн нэлээд том хэсгийг идэх болно. Интернэтээс хэсэг ухаж үзсэнийхээ дараа би нэг гоёмсог функц олсон бөгөөд энэ нь жижиг утгууд дээр ажилладаг тул үүнийг арай хялбаршуулсан. Энэ функц нь:

Энэ функц болон математикийн номын сангийн функцийг харьцуулж үзээд үр дүн нь ижил байхын тулд түүний нарийвчлал хангалттай байна гэсэн дүгнэлтэд хүрсэн. Уг функц нь өөрөө MK ROM-ийн 12%-тай харьцуулахад 2% жинтэй. Үүнээс гадна энэ нь илүү хурдан тооцоолдог.

Гэхдээ MK 12 суваг, тэр ч байтугай DFT-ийг тооцоолж чадсан нь яаж болсон бэ? Хуваалтын оронд шилжих, хурдан квадрат функц бүхий бүх заль мэхүүдээс гадна өөр нэг заль мэх бий. Үүний талаар би одоо танд хэлэх болно. Баримт нь сонгох давтамж өндөр байх тусам шүүлтүүрийн нэвтрүүлэх зурвас нарийсдаг, учир нь cos болон sin шилжилт хурдасч, үеүүдийн тоо нэмэгддэг. Мөн ийм cos ба нүгэл өнгөрөх тусам зурвасын өргөн нарийсдаг. Жишээлбэл, 150 Гц давтамжийн хувьд cos болон sin 4 удаа, 1.2 кГц давтамжийн хувьд cos болон sin 32 удаа давтагдана. Үүнээс үзэхэд нэвтрүүлэх зурвас нь бүх мужид жигд байж, бүх давтамжийн мужийг хамрахын тулд шүүлтийн давтамж нэмэгдэхийн хэрээр дээжийн тоог багасгах шаардлагатай байна. Жишээлбэл, 150 Гц-ийн хувьд бүх 512 дээж, 600 Гц-ийн хувьд 256 дээж, 2.4 кГц-ийн хувьд 32 дээж гэх мэт. Өсөн нэмэгдэж буй давтамжтайгаар дээжийн тоог бууруулснаар DFT-ийн хурд огцом нэмэгддэг тул үржүүлэх, нийлбэрийг бага хэмжээгээр хийх шаардлагатай болдог гэдгийг солих нь тийм ч хэцүү биш юм.

Практик хэрэгжилт

Тиймээс онолын хэсэг бэлтгэгдсэн тул бид дизайныг дүрсэлж эхэлж болно. Бүх загвар нь нэг микроконтроллер, 4 транзистор, хэд хэдэн конденсатор, олон резистороос бүрдэнэ. Маш олон резистор суурилуулах нь илүү дээр юм, гэхдээ та зөвхөн резисторыг хэвтээ байдлаар хязгаарлаж болно, өөрөөр хэлбэл. портын зүү тус бүрт нэг. Динамик сканнердахдаа 1 портын оронд бусад хаа сайгүй хийдэг шиг би 3 порт ашигласан цорын ганц зүйлийг эс тооцвол энэ схем нь сонгодог юм. Энэ нь шүүрдэх давтамжийг багасгаж, транзисторын тоог 4 болгон багасгах боломжтой болсон. Үр дүн нь үнэндээ 24x4 масштабтай болсон.

Спектрийн анализатор нь 16 МГц-ийн талстаас 19.2 кГц-ийн дээж авах хурдаар ажилладаг.

Спектрийн анализатор нь дараах давтамжуудын спектрийн далайцыг тооцоолно.

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-ийг олж авдаг бөгөөд энэ нь n-ийн 2-ын үржвэр биш юм. Би 2-ын тоотой ойролцоо тоог n-ийн зэрэглэлд авснаар нөхцөл байдлаас гарах арга замыг сонгосон. Хамгийн ойр нь 240, 256-д дөхөж байна. Өөрөөр хэлбэл 512-оос 240 дээж авсан. Нэмж хэлэхэд та ямар нэг зүйлийг ойртуулж болохгүй. Жишээлбэл, бид 480-ийг авч болох бөгөөд энэ нь 512-той ойролцоо, гэхдээ бид 256-д ойртсон. Үүний тайлбар нь өөр өөр давтамжид дээжийн тоо нь зурвасын өргөнд нөлөөлдөг гэсэн үг юм. Дээжийн тоо их байх тусам зурвасын өргөн нарийсна. Энэ нь өндөр давтамжтай үед косинус нь бага үетэй харьцуулахад хамаагүй хурдан үеийг туулж, далайцыг маш нарийн тооцоолсонтой холбоотой бөгөөд хөрш зэргэлдээх давтамжуудыг зүгээр л хаяж, хүлээн авдаггүй давтамжуудын хооронд сохор давтамжийн бүсүүд үүсдэг. анализатороор. Анализатор бүх давтамжийг хүлээн авч, спектрийг бүхэлд нь хамрахын тулд цөөн дээж авах замаар өндөр давтамжийн зурвасыг өргөтгөх, бага давтамжтай үед илүү олон дээж авах замаар аль болох нарийсгах шаардлагатай. Тиймээс уншлагын тоог практикт сонгосноор би дараахь зүйлийг сонгосон.

9.6 кГц 16 тоолол, 4.8 кГц 32 тоолол, 2.4 кГц 32 тоо, 1.6 кГц 60 тоо, 1.2 кГц 64 тоо, 800 Гц 240 тоо, 600 Гц 256 тоо, 600 Гц, 55204с, тоолол 0 Гц 512 тоолол, 150 Гц 512 тоолол, 75 Гц 512 тоолол.

Дээжийн тоог энэ сонголт нь бүх давтамжийн мужид жигд байх боломжийг олгосон.

9.6 кГц давтамжтай өөр нэг алдаа гарсан. Төсөөллийн хэсэг байхгүй тул (үүнийг дээрх томьёонд 256 спектрийн дугаарыг 512 дээжээр орлуулах замаар хялбархан шалгаж болох ба синус нь үргэлж 0-тэй тэнцүү байх болно) косинусын утга учир бодит хэсэг нэлээд хүчтэй өөрчлөгдөж болно. үндсэн дохионы эсрэг фазын үед бусад цаг тутамд тооцоолно. Энэ нь нэг удаа тооцоолно гэсэн үг. Үүнээс зайлсхийхийн тулд 90 градусаар шилжсэн бодит хэсгийн дор хаяж 2 утгыг тооцоолж, хамгийн ихдээ хоёр утгыг сонгох шаардлагатай.

Програмын алгоритм нь интервалд 512 дээжийг хуримтлуулж, микроконтроллерыг унтах горимд шилжүүлж, дараагийн дээж бэлэн болмогц сэрдэг. Үүнээс гадна, LED нь 150 Гц давтамжтайгаар сканнердсан байна - энэ нь 19200 дээж авах давтамж 128 дахин юм. Өөрөөр хэлбэл, ADC бүх дээж авах өмнө, энэ нь нэг бүрэн шүүрдэж дуусгах цаг хугацаа байх болно. Бүх дээж бэлэн болмогц програмын үндсэн мөчлөгт спектрийн бүх далайцыг тооцоолно. Энэ үед шүүрдэх ажил үргэлжилж байгаа боловч MK унтдаггүй, харин далайцыг тоолдог. Далайцыг тооцоолсны дараа микроконтроллер унтаж, програм дахин давтагдана. Далайцыг 20 дБ мужид үндэслэн тооцдог, өөрөөр хэлбэл тэдгээр нь логарифм юм.

Бүх уншилтыг хүлээн авах хугацаа, бүх далайцыг тооцоолох цаг дээр үндэслэн шинэчлэх давтамж нь 10-15 Гц-ийн бүсэд байна.


Үнэгүй програмууд, ашигтай зөвлөмжүүдийн ертөнц
2024 whatsappss.ru