Larsen & Drunik
Larsen Larsen
ΠŸΡ€ΠΈΠ²Π΅Ρ‚, Π”Ρ€ΡƒΠΆΠΈΠΊ, Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΡƒΠΌΠ°Π» ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ свои Π½Π°Π²Ρ‹ΠΊΠΈ программирования Π² Π³ΠΈΡ‚Π°Ρ€Π½Ρ‹ΠΉ ΠΏΠ΅Π΄Π°Π»? ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒ, пишСшь Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ сигналов, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€ΠΈΡ„Ρ„ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ – Π²ΠΎΡ‚ наша ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΡΡƒΠΌΠ°ΡΡˆΠ΅Π΄ΡˆΠ°Ρ затСя.
Drunik Drunik
ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΡΡƒΡ‚ΡŒ ясСн. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒ сСбС всСго лишь ΠΎΠ΄Π½Ρƒ строчку ΠΊΠΎΠ΄Π°, которая мСняСт искаТСниС Π·Π° 2 микросСкунды. Π― ΠΌΠΎΠ³Ρƒ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ядро DSP, ΠΏΠΎΡ‚ΠΎΠΌ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΡŽ Ρ†ΠΈΠΊΠ», Ρ‡Ρ‚ΠΎΠ±Ρ‹ процСссор Π½Π΅ Ρ‚ΠΎΡ€ΠΌΠΎΠ·ΠΈΠ». Π“Π»Π°Π²Π½ΠΎΠ΅ β€” Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΆΠΈΡ‚Ρ‚Π΅Ρ€ оставался мСньшС миллисСкунды, Π° Ρ‚ΠΎ Π³ΠΈΡ‚Π°Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ Π·Π²ΡƒΡ‡Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΡΡƒΠΌΠ°ΡΡˆΠ΅Π΄ΡˆΠΈΠΉ ΠΌΠ΅Ρ‚Ρ€ΠΎΠ½ΠΎΠΌ. Π”Π°Π²Π°ΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ, Π½ΠΎ ΠΌΠ½Π΅ Π½ΡƒΠΆΠ½Ρ‹ Ρ‡Π΅Ρ‚ΠΊΠΈΠ΅ характСристики, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ я Π½Π°Ρ‡Π½Ρƒ.
Larsen Larsen
ΠšΡ€ΡƒΡ‚ΠΎ, огонь прям! Π”Π°Π²Π°ΠΉ Π²Ρ‹ΠΊΠ»Π°Π΄Ρ‹Π²Π°ΠΉ Π΄Π΅Ρ‚Π°Π»ΠΈ: ΠΊΠ°ΠΊΠΎΠΉ процСссор Π½ΡƒΠΆΠ΅Π½, Π»ΠΈΠΌΠΈΡ‚Ρ‹ ΠΏΠΎ памяти, Ρ‚ΠΎΡ‡Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ искаТСния ΠΈ этот Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» Π² 2 микросСкунды. Кидай Ρ†ΠΈΡ„Ρ€Ρ‹, Π° я ΠΏΠΎΠ΄ΠΊΠΈΠ½Ρƒ Ρ‚Π΅Π±Π΅ Π΅Ρ‰Ρ‘ ΠΈ Π±Π΅Π·ΡƒΠΌΠ½Ρ‹Π΅ ΠΈΠ΄Π΅ΠΈ ΠΏΠΎ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ это ΠΎΠΆΠΈΠ»ΠΎ, Π° Π½Π΅ просто ΠΆΠ΅Π»Π΅Π·ΠΎ. ЗаряТай!
Drunik Drunik
ΠŸΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€: STM32H7‑I5, 480 ΠΌΠ΅Π³Π°Π³Π΅Ρ€Ρ†, 256 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚ ΠžΠ—Π£, 512 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚ Ρ„Π»ΡΡˆ-памяти. Π”ΠΈΡΡ‚ΠΎΡ€ΡˆΠ½: 3-Ρ‚Π°ΠΏΠΎΠ²Ρ‹ΠΉ IIR Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ с Ρ€Π΅Π³ΡƒΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ ΠΊΡ€ΠΈΠ²ΠΎΠΉ насыщСния, 16-битная фиксированная Ρ‚ΠΎΡ‡ΠΊΠ°. ВрСмя ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²ΠΊΠΈ: 2 микросСкунды – 1 микросСкунда Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ коэффициСнтов, 1 микросСкунда Π½Π° ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ. Π‘Π»Π΅Π΄ΠΈ Π·Π° Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π»Π° 200 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚, ΠΈ старайся ΡƒΠ»ΠΎΠΆΠΈΡ‚ΡŒΡΡ Π² 4% энСргопотрСблСния. Π”Π°ΠΉ Π·Π½Π°Ρ‚ΡŒ, Ссли это ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠ΄ Ρ‚Π²ΠΎΡŽ схСму.
Larsen Larsen
Π—Π²ΡƒΡ‡ΠΈΡ‚ ΠΊΡ€ΡƒΡ‚ΠΎ, Π±Ρ€Π°Ρ‚Π°Π½. 480 ΠΌΠ΅Π³Π°Π³Π΅Ρ€Ρ† Π½Π° H7 – Π½Π°ΠΌ Ρ…Π²Π°Ρ‚ΠΈΡ‚ запаса, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ»ΠΎΠΆΠΈΡ‚ΡŒΡΡ Π² этот Ρ‚ΠΈΠΊ обновлСния Π² микросСкунду. ΠžΡΡ‚Π°Π²ΡŒ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ коэффициСнтов Π² L1 кэшС ΠΈ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠΉ Π΅Π΅ синхронизациСй DMA, это Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π΄ΠΆΠΈΡ‚Ρ‚Π΅Ρ€ ΠΏΠΎΠ΄ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅ΠΌ. 4% энСргопотрСблСниС? НапряТно, Π½ΠΎ Ссли сократим Ρ†ΠΈΠΊΠ»Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ядра DSP, получится. Забросим сырой ΠΊΠΎΠ΄, ΠΈ я Π½Π°Π±Ρ€ΠΎΡΠ°ΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ искаТСния Π·Π²ΡƒΡ‡Π°Π»ΠΈ ΠΏΠΎ-настоящСму Π½Π° сцСнС. Заставим это Π·Π°ΠΆΠΈΠ³Π°Ρ‚ΡŒ!
Drunik Drunik
Π­ΠΉ, ΠšΠΎΡΡ‚ΡΠ½, смотри, Ρ‡Ρ‚ΠΎ Ρ‚ΡƒΡ‚ Π½Π°Ρ€Ρ‹Π». // Ѐиксированный 16-Π±ΠΈΡ‚Π½Ρ‹ΠΉ IIR-ядро искаТСний // ΠšΠΎΡΡ„Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚Ρ‹ Q1.15, состояниС Q1.15 typedef struct { int16_t a0, a1, a2; // прямой ΠΊΠ°Π½Π°Π» int16_t b1, b2; // обратная связь int16_t z1, z2; // состояния } DistortionState; // ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° обновлСния Π½Π° 1 мкс (вызываСтся синхронизациСй DMA) void update_coeffs(DistortionState *s, const int16_t *coeffs) { s->a0 = coeffs[0]; s->a1 = coeffs[1]; s->a2 = coeffs[2]; s->b1 = coeffs[3]; s->b2 = coeffs[4]; } // Основной DSP-Ρ†ΠΈΠΊΠ» (Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° частотС 480 ΠœΠ“Ρ†, 1 мкс Π½Π° Π²Ρ‹Π±ΠΎΡ€ΠΊΡƒ) int16_t process_sample(DistortionState *s, int16_t in) { // Π£ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ Q1.15 с 32-Π±ΠΈΡ‚Π½Ρ‹ΠΌ аккумулятором int32_t acc = (int32_t)in * s->a0 + (int32_t)s->z1 * s->a1 + (int32_t)s->z2 * s->a2; int16_t out = (int16_t)(acc >> 15); // ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² Q1.15 // ОбновлСниС состояний s->z2 = s->z1; s->z1 = out - ((int32_t)s->b1 * out >> 15) - ((int32_t)s->b2 * s->z2 >> 15); // ΠŸΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠ΅ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° if (out > 32767) out = 32767; if (out < -32768) out = -32768; return out; }