今回はTIM3の更新でDMAトリガです
まずTIM3の初期化
TIM_InitStructure.TIM_Period = 1500 - 1;
TIM_InitStructure.TIM_Prescaler = 0;
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_InitStructure);
TIM_Cmd(TIM3, ENABLE);
今回は72MHzで48kHzを作りたいのでカウンタは1500 分周は無し
これで72000000/1500/1=48000Hzが作れる
なお、タイマ割り込みは使わず、ただの分周器として使いたいだけなのでNVICの初期化は不要
次にDMAの初期化
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(DAC_BASE + 0x00000008 + 0x00000004);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&DAC_Buff[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 480;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3, ENABLE);
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
DMAの転送元はuint16_t配列のDAC_Buffを 転送先はDMA1の12bit左詰めレジスタを指定
(DACはDAC1->ODRみたいに指定できないのが面倒)
基本的に普通の初期化方法と同じ
今回はぐるぐるとバッファの中身を出力させたいのでCircularモード
そしてM2MはDisableに
DMAの転送トリガはDMA_M2M or ペリフェラルトリガなので、M2MがEnaの場合はどんどん出力されていく
そしてDMA_Cmdの後にTIM_DMACmdでタイマとタイミングを指定する
タイマとトリガとDMAチャネルの組み合わせは決まっているので注意
組み合わせはRM0008のDMAの説明に書いてある
例えばSPI1はDMA1_ch2がRX DMA1_ch3がTXになっているが、TIM2更新もDMA1_ch2に割り当てられている
予めうまく組み合わせを考えておかないと、修正で面倒なことになる
TIMでタイミングを作ってDMA転送は結構簡単に使える感じ
ただ今回はDACとかいろいろの組み合わせで正常動作していないように見えてしまったためにややこしいことになった。。
注意点として、DMAとTIMを組み合わせてもあまり高速な転送はできない せいぜい6MHzくらい
DACはTIMでいいけど、ADCは注意が必要
ADCを使う場合はADCのトリガをTIMにして、DMAのトリガをADCにする
ちょっとフクザツだけどパズルみたいで面白い
ちゃんと作れれば
0 件のコメント:
コメントを投稿