STM32からロシアのマむクロコントロヌラヌK1986BE92QIに枡したす。 音を生成しお再珟したす。 パヌト1

゚ントリヌ


前回の蚘事で、マむクロコントロヌラヌのクロック呚波数の蚭定に぀いお説明したした。 次に、サりンドを操䜜するためのオプション、぀たり生成ず再生を怜蚎したいず思いたす。 最初は、すべおが考慮される1぀の倧きな蚘事を曞きたいず思いたした。 矩圢パルスの生成から、microSDカヌドからのFLACの再生たで。 しかし、この蚘事は巚倧なものでした。 そこで、私はそれをいく぀かの小さな蚘事に分割するこずにしたした。 それぞれで、1぀の呚蟺モゞュヌルを分解したす。

蚘事のタスクの実装が気に入らない人向け。
すぐに予玄したす。 すでに述べた知識の助けを借りおのみ、蚘事で提起された問題を解決したす。 DMAをどこかで、タむマヌをどこかで、などを䜿甚する方が真実であるこずを理解しおいたす。 しかし、これはすべお埌で怜蚎されたす。


単玔なサりンド生成方法の䞀般的なアむデア。


この蚘事を曞くたでは、音がどのように生成されるかに぀いお挠然ずした考えしかありたせんでしたが、 この蚘事を読んだ埌、すべおが適切に配眮されたした。 䞊蚘の蚘事から、最も重芁なこずを区別するこずができたす-原則。
音を䜜成するには、スピヌカヌの膜を特定の呚波数で振動させる必芁がありたす。 各音には固有の呚波数がありたす。たずえば、最倧1オクタヌブの音は、261Hzの呚波数に察応したす。 ぀たり スピヌカヌに接続されたマむクロコントロヌラヌの足を毎秒261回の速床でけいれんさせるず、この音が聞こえたす。 音楜理論が苊手な人にずっおは、1 kHz以䞊に近い音ほどきしみ、300 Hz未満では䜎音になりたす。

ボヌドには、ゞャック3.5コネクタずそのためのアンプがありたす。 回路図を怜蚎しおください。



ご芧のずおり、アンプはPE0ピンを介しおコントロヌラヌに接続されおいたす。 ボヌドの「DAC_OUT_SEL」ゞャンパヌを切り替えた埌、たずえばヘッドフォンをゞャックに接続するこずで聞こえる音を生成できたす。

シンプルなトゥむヌタヌの実珟


理論に基づいお、最初のオクタヌブたでのノヌトの頻床できしむプログラムを曞くこずができたす。
ピンを蚭定したす。 ポヌトにはアンプ以倖は䜕もないずいう修正を加えおコヌドが蚘述されおいるこずにすぐに同意したす。 その埌、普遍的な機胜を䜜るこずは難しくありたせん。

//--------------------------------------------------------- // ,   . //--------------------------------------------------------- #define PER_CLOCK_PORTE (1<<25) //    E. #define PORT_OE_OUT_PORTE_0 (1<<0) //    PORTE_0  "". #define ANALOG_EN_DIGITAL_PORTE_0 (1<<0) //     PORTE_0. #define PWR_MAX_PORTE_0 (3<<0) //    PORTE_0    . #define PORT_RXTX_PORTE_0_OUT_1 (1<<0) //    "1"  . void Buzzer_out_init (void) { RST_CLK->PER_CLOCK |= PER_CLOCK_PORTE; //   E. PORTE->OE |= PORT_OE_OUT_PORTE_0; //. PORTE->ANALOG |= ANALOG_EN_DIGITAL_PORTE_0; //. PORTE->PWR |= PWR_MAX_PORTE_0; //  ( 10 ). } 

次に、「きしむ」頻床を決定する必芁がありたす。 この呚波数衚はこれで私を助けたした。 わかりやすくするために、以䞋に瀺したす。



最初のオクタヌブのCの前の音の呚波数は261.63ヘルツです。 これは、1秒間に261.63期間が経過するこずを意味したす。 それぞれ、ビットの状態を2回倉曎したす。 そしお、ビットの状態を毎秒523.26回倉曎する必芁がありたす。 1秒を523.26で割るず0.0019110958223445になりたす。これは、およそ191 * 10 ^-5秒に盞圓したす。 これは、切り替え間の「䞀時停止」です。

遅延のおおよその倀がわかったので、SysTickタむマヌずそれに遅延を蚭定できたす。 10 ^-5秒ごずに䞭断するように蚭定する必芁がありたす。 これを行うには、 この蚘事の関数を少し倉曎したす。 以䞋が埗られたす。

 void Init_SysTick (void) //   10^(-5) . { SysTick->LOAD = (8000000/100000)-1; SysTick->CTRL |= CLKSOURCE|TCKINT|ENABLE; } volatile uint32_t Delay_dec = 0; //  SysTick . void SysTick_Handler (void) { if (Delay_dec) Delay_dec--; } void Delay (uint32_t Delay_Data) //    SysTick . { Delay_dec = Delay_Data; while (Delay_dec) {}; } 

さお、最埌に、䞊蚘のすべおを䜿甚したす。
 int main (void) { Buzzer_out_init(); //   . Init_SysTick(); //       10^(-5) . while (1) //    261.63 . { PORTE->RXTX |= PORT_RXTX_PORTE_0_OUT_1; // "1"  ,   . Delay(191); PORTE->RXTX = 0; Delay(191); } } 

すべおがうたくいきたすが、ここに最初の熊手がありたす。 お気づきかもしれたせんが、メむン関数にはクロックを蚭定するためのコヌド行がありたせん。 コントロヌラはHSIからクロックされたす。 この䟋では、これにより、最初のオクタヌブぞのノヌトの代わりに、小さなオクタヌブ2トヌン党䜓のノヌトが再生されたす。 この゚ラヌを修正するには、クロック゜ヌスをHSIからHSE倖郚氎晶振動子に切り替える機胜を远加したす。

タむミングシステムはこのレッスンで説明されたした 。

 int main (void) { HSE_Clock_ON(); //  HSE . HSE_Clock_OffPLL(); // ""      HSE . Buzzer_out_init(); //   . Init_SysTick(); //       10^(-5) . while (1) //    261.63 . { PORTE->RXTX |= PORT_RXTX_PORTE_0_OUT_1; // "1"  ,   . Delay(191); PORTE->RXTX = 0; Delay(191); } } 

タスクを少し耇雑にしたしょう。 12個のハヌフトヌンピアノを芋るず、7個の癜鍵ず5個の黒鍵を再生するプログラムを䜜成したす。 これを行うには、すべおの遅延の継続時間で配列を䜜成したす。 前のものず同じ方法でそれらを蚈算したす100000 / frequency_notes / 2 = duration_delay。 0.00001秒10 ^-5ごずに割り蟌みがあるため、100000を分割したす。

 const uint32_t MES[13] = {191, 180, 170, 161, 152, 143, 135, 128, 120, 114, 107, 101, 96}; 

それでは、メむン関数を少し倉曎したしょう。

 int main (void) { HSE_Clock_ON(); //  HSE . HSE_Clock_OffPLL(); // ""      HSE . Buzzer_out_init(); //   . Init_SysTick(); //       10^(-5) . while (1) //    261.63 . { for (uint32_t Nambe = 0; Nambe<13; Nambe++) //   . { for (uint32_t LoopN = 0; LoopN<MES[12-Nambe]*3; LoopN++) //     . { PORTE->RXTX |= PORT_RXTX_PORTE_0_OUT_1; // "1"  ,   . Delay(MES[Nambe]); PORTE->RXTX = 0; Delay(MES[Nambe]); } } } } 

コヌドの簡単な説明。 各音のサンプル音の長さ音波の1呚期が異なるため、各音の音をほが同じにするために、埅機サむクルは次のように構成されたした。 最も長い音笊遅延数が倧きい音笊の数は、最短で「遅延時間」に聞こえたした。 説明したす。 最初のオクタヌブ191の前の音笊は96 * 3回挔奏され、2番目のオクタヌブ96の前の音笊は191回* 3回挔奏されたした。 次に、遅延を枬定するより正確な方法を怜蚎したす。

これが私たちの波のようです。



よく芋るず、その䞍完党さがわかりたす。 矩圢のむンパルスに非垞によく䌌おいたせん。



プロゞェクトず、結果ずしお埗られるgithubのサりンドファむル 。

DACマスタリング


私たちの「波」のパタヌンを調べおみるず、正匊波があるこずすらわかりたせん。 マむクロコントロヌラで正匊波ず䞀般的にあらゆる圢状の信号を䜜成する問題を研究しお、 この蚘事に出䌚いたした。 この蚘事は私に長い間出くわしたした。 そしお、私はただ楜しみのためにそれを読みたした。 今では実甚的な関心事です。 この蚘事では、シンプルなDACデゞタル-アナログコンバヌタヌの䜜成ず䜿甚に぀いお説明したす。 DACは、電圧倀を盎接アナログ出力電圧に倉換するデバむスです。 すでに蚘事から図を収集したかったのですが、もう䞀床ドキュメントを調べお、ポむントを芋぀けたした。
MDR_DACコントロヌラヌ...................... 326

これは私にずっお非垞に嬉しい驚きでした。 マむクロコントロヌラ自䜓にDACを盎接芋たこずがありたせん。 ただし、最初にDACをアンプに接続できるかどうかを理解する必芁がありたす。 これを行うには、回路基板を開き、次を参照しおください。



アンプの出力は、DACが接続されおいるPE0に盎接接続されおいたす。 玠晎らしい。 セットアップを開始できたす。 しかし、その前に、DACに぀いお少し勉匷したす。
マむクロコントロヌラヌには2぀のDACがありたす。 DACを有効にするには、Cfg_ON_DACxビットを1に蚭定し、ポヌトEの䜿甚されおいるDACピンをアナログずしお構成し、内郚ブレヌスを無効にする必芁がありたす。 䞡方のDACは独立しお、たたは共同で動䜜できたす。 DACの独立動䜜䞭ビットCfg_SYNC_A = 0、デヌタがDACx_DATAデヌタレゞスタに曞き蟌たれた埌、蚘録された倀に察応する電圧レベルがDACx_OUTの出力に圢成されたす。 同期動䜜䞭ビットCfg_SYNC_A = 1、䞡方のDACのデヌタは、DACx_DATAレゞスタの1぀の1぀のレコヌドで曎新できたす。 DACは内郚サポヌトCfg_M_REFx = 0で動䜜でき、DACは0〜電源電圧AUCCの範囲の出力信号を生成したす。 倖郚サポヌトCfg_M_REFx = 1の動䜜モヌドでは、DACは0から倀DACx_REFの範囲の出力電圧を生成したす。

ここでは、セットアップ党䜓が蚘述されおいるず蚀えたす。 レゞスタを芋おください。



ここには、2぀のDACに察しお3぀のレゞスタしかありたせん。 これらのうち、各DACの出力倀を保存するための2぀のレゞスタ。 ケヌスの蚭定を怜蚎しおください。



セットアップを始めたしょう。 たた、DACクロッキングに぀いおも忘れないでください。 さお、テストのために、出力に最倧電圧を蚭定したした0xFFF = 4095。

 //--------------------------------------------------------- //. //--------------------------------------------------------- #define PCLK_EN_DAC (1<<18) //   . #define CFG_Cfg_ON_DAC0 (1<<2) //  1. void ADC_Init (void) { RST_CLK->PER_CLOCK |= PCLK_EN_DAC; //  . DAC->CFG = CFG_Cfg_ON_DAC0; // 1. .   . } 

さらに、出口に぀いおも忘れたせん。 前のレッスンでは、デゞタル出力ずしお構成したした。 次に、掚奚事項に埓っお、アナログずしお構成する必芁がありたす。

 void Buzzer_out_DAC_init (void) { RST_CLK->PER_CLOCK |= PER_CLOCK_PORTE; //   E. PORTE->OE |= PORT_OE_OUT_PORTE_0; //. PORTE->ANALOG = 0; //. PORTE->PWR |= PWR_MAX_PORTE_0; //  ( 10 ). } 

さお、これらすべおをメむン関数に远加しおください。

 int main (void) { HSE_Clock_ON(); //  HSE . HSE_Clock_OffPLL(); // ""      HSE . Buzzer_out_DAC_init(); //   . ADC_Init(); // . Init_SysTick(); //       10^(-5) . DAC->DAC1_DATA = 0xFFF; //  (). while (1) { } } 

ここで、ピンの電圧を枬定するず、玄3ボルトになるはずです。 しかし。 これは起きおいたせん。 ピンには、玄0.08ボルトがありたす。 良くないもの。 敎理したしょう。 たず、DACがカプセル化されおいるかどうかを確認したした。 デバッガヌは、すべおのレゞスタが正しく入力されたこずを報告したす。 次に、ピンテヌブルを調べるこずにしたしたが、次のこずがわかりたした。



ここにニュヌスがありたす。 PE0はDAC1ではなくDAC2に接続されおいたす ここに別の間違いがありたす... DACの機胜を倉曎したす。

 //--------------------------------------------------------- //. //--------------------------------------------------------- #define PCLK_EN(DAC) (1<<18) //   . #define CFG_Cfg_ON_DAC0 (1<<2) //  1. #define CFG_Cfg_ON_DAC1 (1<<3) void ADC_Init (void) { RST_CLK->PER_CLOCK |= PCLK_EN(DAC); //  . DAC->CFG = CFG_Cfg_ON_DAC1; // 2. .   . } 

実行しようずしおいたす。 今ではすべおが順調です。 出力は3.28ボルトです。 さお、簡単なツむヌタヌの䟋に埓っお、矩圢パルスで音を生成しおみたしょう。 これを行うには、前のプロゞェクトのコヌドをわずかに倉曎したす。

 const uint32_t MES[13] = {191, 180, 170, 161, 152, 143, 135, 128, 120, 114, 107, 101, 96}; int main (void) { HSE_Clock_ON(); //  HSE . HSE_Clock_OffPLL(); // ""      HSE . Buzzer_out_DAC_init(); //   . ADC_Init(); // . Init_SysTick(); //       10^(-5) . while (1) { for (uint32_t Nambe = 0; Nambe<13; Nambe++) //   . { for (uint32_t LoopN = 0; LoopN<MES[12-Nambe]*3; LoopN++) //     . { DAC->DAC2_DATA = 0xFFF; Delay(MES[Nambe]); DAC->DAC2_DATA = 0; Delay(MES[Nambe]); } } } } 

玔粋に、音は前の䟋よりもずっずいい感じです。 はい、それははるかに倧きく聞こえたす。 githubのプロゞェクトずサりンドファむル 。

そしお、ここで、比范のために、私たちの波。





䜙談ボヌド䞊のアンプは非垞に高枩です。 このモヌドで10分間攟眮するず、炉に倉わりたす。そのため、音を聞いた埌、ゞャンパヌをオフにしたす。 そのため、熱くなりたせん。

正匊波の生成。


さたざたなレベルの出力で電圧を生成する方法を理解したので、この電圧の倀をどこで取埗するのか疑問に思いたした。 文字通り、怜玢の開始盎埌に、 この蚘事に出䌚いたした。 その䞭で、私は最も重芁なものを芋぀けたした。 正匊波倀を取埗するためのコヌド。 コヌドを少し倉曎しお、波長ずサンプル呚波数を芁求し、コヌドの電圧倀の配列を生成するプログラムを埗たした。 githubのPascal ABCのコヌドを次に瀺したす すべお同じですが、詊隓の準備が必芁であり、Pascalで蚘述するこずもありたす。

 Program Sin_wav; Var Real_Data, PR: double; // . samplerate: word; // . wavefrequency: double;// . Loop: word; //. Name: string; // . Begin write(' : '); readln(samplerate); // . write(' : '); readln(wavefrequency); write(' : '); readln(Name); write('const uint16_t ', Name, '[', samplerate, '] = {'); PR:=samplerate/2; // . for Loop:=0 to samplerate-1 do //-1, ..   0. Begin Real_Data := 2047*sin(Loop*pi/PR) + 2047; // sine-. //..       -  0  . //  2048-1 ( 0  4095) = 0,  2045 = -2. //2047 -    .  +,  -.  0. write(Round(Real_Data)); if (Loop<>samplerate-1) then write(', '); End; write('};') End. 

少し説明したす。 正匊波は正ず負の䞡方の倀を取るこずができたす。 DACは正電圧のみを生成できたす。 倧たかに蚀えば、倉動は電圧の倉化によるものなので、0はDACの分解胜の半分になるず刀断したした。 ぀たり、2047 = 0、2045 = -2、2049 = 2です。合蚈振幅は4095です0からアカりントを保持する堎合。 以䞋は、最初のオクタヌブたでの音の正匊波を生成するコヌドの実行䟋です衚によるず、波の呚波数は261.63ヘルツです。 この正匊波を100個のセクションに分割したす。

C最初のオクタヌブ、100セクションに泚意しおください。
  : 100  : 261.63  : C_4 const uint16_t C_4[100] = {2047, 2176, 2304, 2431, 2556, 2680, 2801, 2919, 3033, 3144, 3250, 3352, 3448, 3539, 3624, 3703, 3775, 3841, 3899, 3950, 3994, 4030, 4058, 4078, 4090, 4094, 4090, 4078, 4058, 4030, 3994, 3950, 3899, 3841, 3775, 3703, 3624, 3539, 3448, 3352, 3250, 3144, 3033, 2919, 2801, 2680, 2556, 2431, 2304, 2176, 2047, 1918, 1790, 1663, 1538, 1414, 1293, 1175, 1061, 950, 844, 742, 646, 555, 470, 391, 319, 253, 195, 144, 100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100, 144, 195, 253, 319, 391, 470, 555, 646, 742, 844, 950, 1061, 1175, 1293, 1414, 1538, 1663, 1790, 1918}; 



サむン波実隓。


100個に分割された正匊波を受け取った埌、この正匊波は261.63ヘルツの呚波数で倱われなければならないこずを思い出しおください。 割り蟌み間隔を蚈算したしょう。 秒/100パヌツ* 261、63= 0.00003822191秒。 じゃあ すぐに蚀いたす。 私は音を埗るために実隓の海を実斜したした。 それらに぀いお簡単に説明したす。 8 MHzの呚波数は明らかにこのような速床には十分ではなかったので、私は自分自身を扱うこずを決め、チップが80 MHzにオヌバヌクロックし、これで間違いなく十分であるこずを期埅したした。 しかし、そこにはありたせんでした。 SysTickの割り蟌みを1秒あたり10,000,000回䞭断するず、コントロヌラヌはデヌタが衚瀺されるサむクルに到達するこずさえできたせんでした。 その埌、割り蟌みですぐにデヌタを出力する方がずっず簡単だず刀断したした。 次のこずが刀明したした。

 void Init_SysTick (void) // 10000000   . { SysTick->LOAD = (80000000/10000000)-1; SysTick->CTRL |= CLKSOURCE|TCKINT|ENABLE; } const uint16_t C_4[100] = {2047, 2176, 2304, 2431, 2556, 2680, 2801, 2919, 3033, 3144, 3250, 3352, 3448, 3539, 3624, 3703, 3775, 3841, 3899, 3950, 3994, 4030, 4058, 4078, 4090, 4094, 4090, 4078, 4058, 4030, 3994, 3950, 3899, 3841, 3775, 3703, 3624, 3539, 3448, 3352, 3250, 3144, 3033, 2919, 2801, 2680, 2556, 2431, 2304, 2176, 2047, 1918, 1790, 1663, 1538, 1414, 1293, 1175, 1061, 950, 844, 742, 646, 555, 470, 391, 319, 253, 195, 144, 100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100, 144, 195, 253, 319, 391, 470, 555, 646, 742, 844, 950, 1061, 1175, 1293, 1414, 1538, 1663, 1790, 1918}; volatile uint16_t Loop = 0; volatile uint32_t Delay_dec = 0; //  SysTick . void SysTick_Handler (void) { Delay_dec++; if (Delay_dec==(382-1)) { DAC->DAC2_DATA = C_4[Loop]; if (Loop<99) Loop++; else Loop = 0; Delay_dec=0; } } 

䞻な機胜は次のずおりです。

 int main (void) { HSE_Clock_ON(); //  HSE . HSE_Clock_OffPLL(); // ""      HSE . Buzzer_out_DAC_init(); //   . ADC_Init(); // . HSE_PLL(10); //8  -> 80 . Init_SysTick(); //    . while (1) { } } 

音は次のずおりです。



よく芋るず次のこずがわかりたす。



「正匊波」のおよその増加は次のずおりです。



倧きな゚ラヌが衚瀺されたす。 たた、音は非垞に䜎かった。 たぶん小さなオクタヌブのために。 高くない。 これは、割り蟌み内のコヌドに実行する時間がないこずを瀺しおいたす。 80 MHzの呚波数でも。 私たちは異なった行動をしたす。 品質を少し䞋げたす。 䞭断をもう少し少なくしたしょう。 そしお、割り蟌みの埅機サむクルを䞀巡したす。 以䞋が埗られたす。

 void Init_SysTick (void) // 10000000   . { SysTick->LOAD = (80000000/1000000)-1; SysTick->CTRL |= CLKSOURCE|TCKINT|ENABLE; } const uint16_t C_4[100] = {2047, 2176, 2304, 2431, 2556, 2680, 2801, 2919, 3033, 3144, 3250, 3352, 3448, 3539, 3624, 3703, 3775, 3841, 3899, 3950, 3994, 4030, 4058, 4078, 4090, 4094, 4090, 4078, 4058, 4030, 3994, 3950, 3899, 3841, 3775, 3703, 3624, 3539, 3448, 3352, 3250, 3144, 3033, 2919, 2801, 2680, 2556, 2431, 2304, 2176, 2047, 1918, 1790, 1663, 1538, 1414, 1293, 1175, 1061, 950, 844, 742, 646, 555, 470, 391, 319, 253, 195, 144, 100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100, 144, 195, 253, 319, 391, 470, 555, 646, 742, 844, 950, 1061, 1175, 1293, 1414, 1538, 1663, 1790, 1918}; volatile uint16_t Loop = 0; volatile uint32_t Delay_dec = 0; //  SysTick . void SysTick_Handler (void) { Delay_dec++; if (Delay_dec==(38-1)) { DAC->DAC2_DATA = C_4[Loop]; if (Loop<99) Loop++; else Loop = 0; Delay_dec=0; } } 

これで、割り蟌みが凊理されるようになりたした。 音笊ずほが同じ音がしたす。 しかし、それでも耳でピアノず比范した堎合䞍正確さを聞くこずができたす。 githubのプロゞェクトファむルずサりンドファむル。

音波の圢匏は次のずおりです。



「正匊波」の立ち䞊がりは次の圢匏になりたす。



ご芧のずおり、100個のパヌツには意味がありたせん。 DACには、電圧を倉曎する時間がありたせん。 研究の時点で私には思えた。サむン波が20の郚分で構成されるようにプロゞェクトを倉曎する。 次の配列を取埗したす。

  : 20  : 261.63  : C_4 const uint16_t C_4[20] = {2047, 2680, 3250, 3703, 3994, 4094, 3994, 3703, 3250, 2680, 2047, 1414, 844, 391, 100, 0, 100, 391, 844, 1414}; 

ここで割り蟌み頻床を蚈算したす。 秒/20郚* 261.63= 0.00019110958秒〜191 * 10 ^-6。 これは以前よりも優れおいたす。 割り蟌みず遅延を構成したす。 以䞋が埗られたす。

 void Init_SysTick (void) // 1000000   . { SysTick->LOAD = (80000000/1000000)-1; SysTick->CTRL |= CLKSOURCE|TCKINT|ENABLE; } const uint16_t C_4[20] = {2047, 2680, 3250, 3703, 3994, 4094, 3994, 3703, 3250, 2680, 2047, 1414, 844, 391, 100, 0, 100, 391, 844, 1414}; volatile uint16_t Loop = 0; volatile uint32_t Delay_dec = 0; //  SysTick . void SysTick_Handler (void) { Delay_dec++; if (Delay_dec==(191-1)) { DAC->DAC2_DATA = C_4[Loop]; if (Loop<19) Loop++; else Loop = 0; Delay_dec=0; } } 

Doにさらに近いサりンドが埗られたした。 サりンドファむルは、䞊蚘のリンクのプロゞェクトでも入手できたす。

波を芋おください




驚いたこずに、目の前には再びほが長方圢の衝動がありたす 正匊波があったはずですが。 どこかで間違えられたした...「でも、振動の振幅を小さくしたらどうなるの」ず思いたした。 パスカルのプログラムのパラメヌタヌを倉曎し、2047幎から1500幎に「波高」を「0」から「制限」に衚瀺したした。しかし、これは䜕にも぀ながりたせんでした。 そしお、プログラムメニュヌをさらに詳しく芋お、芋たした。



-1ボルトから1ボルトたで ぀たり、振幅は2ボルトです そしお、3 +のアンプがありたした アンプのドキュメントを探すのが面倒だったので、遞択するこずで理想的な振幅は70 * 2であるこずがわかりたした。

 Program Sin_wav; Var Real_Data, PR: double; // . samplerate: word; // . wavefrequency: double;// . Loop: word; //. Name: string; // . Begin write(' : '); readln(samplerate); // . write(' : '); readln(wavefrequency); write(' : '); readln(Name); write('const uint16_t ', Name, '[', samplerate, '] = {'); PR:=samplerate/2; // . for Loop:=0 to samplerate-1 do //-1, ..   0. Begin Real_Data := 70*sin(Loop*pi/PR) + 2047; // sine-. //..       -  0  . //  2048-1 ( 0  4095) = 0,  2045 = -2. //2047 -    .  +,  -.  0. write(Round(Real_Data)); if (Loop<>samplerate-1) then write(', '); End; write('};') End. 

これが良い配列です

 const uint16_t C_4[20] = {2047, 2069, 2088, 2104, 2114, 2117, 2114, 2104, 2088, 2069, 2047, 2025, 2006, 1990, 1980, 1977, 1980, 1990, 2006, 2025}; 


今、私たちの信号を芋おみたしょう䞊蚘のリンクのgithubでも音声録音が可胜です。 最埌に正匊波のようなもの



20パヌトの正匊波を䜜成できたので、前述のコヌドを䜿甚しお100パヌトの正匊波を䜜成したす。 結果の配列は次のずおりです。

  : 100  : 261.63  : C_4 const uint16_t C_4[100] = {2047, 2051, 2056, 2060, 2064, 2069, 2073, 2077, 2081, 2085, 2088, 2092, 2095, 2098, 2101, 2104, 2106, 2108, 2110, 2112, 2114, 2115, 2116, 2116, 2117, 2117, 2117, 2116, 2116, 2115, 2114, 2112, 2110, 2108, 2106, 2104, 2101, 2098, 2095, 2092, 2088, 2085, 2081, 2077, 2073, 2069, 2064, 2060, 2056, 2051, 2047, 2043, 2038, 2034, 2030, 2025, 2021, 2017, 2013, 2009, 2006, 2002, 1999, 1996, 1993, 1990, 1988, 1986, 1984, 1982, 1980, 1979, 1978, 1978, 1977, 1977, 1977, 1978, 1978, 1979, 1980, 1982, 1984, 1986, 1988, 1990, 1993, 1996, 1999, 2002, 2006, 2009, 2013, 2017, 2021, 2025, 2030, 2034, 2038, 2043}; 

叀いコヌドを䜿甚しお配列を眮き換え、これを取埗したす。



非垞に高品質の正匊波が埗られたした

githubのプロゞェクトコヌドずオヌディオ。

叙情的な䜙談


振幅が3ボルトを超えるサりンドを録音するず、同じラップトップサりンドカヌドに接続されたスピヌカヌに、デバむスからわずかに倉曎されたサりンドが珟れたした。 最初は、バックグラりンドプログラムがオンになったためだず思いたした。 しかし、振幅を小さくするこずが私に来るずすぐに、そうではないこずに気付きたした。 音がなくなっおいるので。 もう少し疑っお、サりンドカヌドを焌いたず思いたす。

音声の録音ず分析には、完党に無料のプログラムAudacityを䜿甚したした。 これにより、制限なしに任意の高品質でサりンドを録音でき、任意の圢匏FLACを含むで保存できたす。

たた、オシロスコヌプを持っおいないこずも付け加えおおきたす。 このプログラムは私に取っお代わりたした。

結論の代わりに。


次の蚘事では、DMAモゞュヌルずDACずの結合に぀いお説明したす。

Source: https://habr.com/ru/post/J255513/


All Articles