有人使用STM32G431芯片做DAC應用,具體來說就是通過DMA將數據從指定內存傳送給DAC數據寄存器,并由定時器觸發DAC轉換。他發現總是沒法實現該功能。這里簡單介紹下相關實現過程,并做些提醒。這里要演示的基本功能就是讓DAM將內存數據周期性傳輸給DAC數據寄存器,最后輸出一路正弦波。
結合STM32G4芯片的特性,這里可以有兩種實現方式。
第一種,DMA的請求來自于DAC1的轉換事件。第二種,DMA的請求來自于定時器事件,下面用到的是定時器的更新事件。這里就兩種實現方式的配置及相關用戶代碼簡單介紹下,以供參考。
我們先看第一種方式,即DMA請求來自DAC轉換事件,定時器3觸發DAC的轉換。
使用CubeMx進行配置,主要配置如下:
完成配置后生成初始代碼,再添加下面代碼即可驗證測試:
#define Tpai (2*3.14159)
uint32_t PData[200],Dac_data;
uint16_t i;
for (i=0;i《200;i++)
{
PData[i]=
(uint32_t ) (2000*(sin((Tpai/200)*i))+2000);
} //prepare data for DAC
HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0], 200,DAC_ALIGN_12B_R);
__HAL_TIM_ENABLE(&htim3);
上面配置的DMA傳輸方向是從內存到外設,目的和源的訪問寬度都是32位WORD. 當然也可以是內存訪問寬度為16位的半字,外設訪問寬度為32位字。即DMA的配置像下面這樣也是可以的。
其它配置不動,代碼稍微改動和整理下即可。參見下面代碼:
Uint16_t PData[200],Dac_data;
#define Tpai (2*3.14159)
uint16_t i;
for (i=0;i《200;i++)
{
PData[i]=
(uint16_t )(2000*(sin((Tpai/200)*i))+2000);
} //prepare data for DAC
SET_BIT(hdac1.Instance-》CR,DAC_CR_DMAEN1);
HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
HAL_Delay(2);
HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1-》DHR12R1, 200);
__HAL_TIM_ENABLE(&htim3);
第一種方式就介紹到這里,再來看看第二種實現方式,即TIMER更新事件作為DMA請求源,同時作為DAC轉換觸發源。
基于CubeMx配置,主要調整下DMA配置,其它配置基本不動。
主要是DMA請求事件變了,其它配置跟第一種模式基本一樣。
配置完成后生成初始化代碼,再添加下面用戶代碼:
#define Tpai (2*3.14159)
uint16_t PData[200], Dac_data;
uint16_t i;
for (i=0;i《200;i++)
{
PData[i]=
(uint16_t )(2000*(sin((Tpai/200)*i))+2000);
}
HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
HAL_Delay(3);
HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1-》DHR12R1, 200);
__HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
__HAL_TIM_ENABLE(&htim3);
這里要提醒一點,G4系列的DAC1的數據保持寄存器可以一次放2個通道的數據,在使用DMA傳輸時,即使只用到1個通道,DMA對它的訪問也要遵循WORD對齊,不然你可能會遇到麻煩。
如果說,我們不使用DMA做數據傳輸,只是手動給DAC喂數據,那如何實現上述效果呢?這時我們可以使用軟件觸發DAC的傳輸,手動給DAC的數據保持寄存器賦值,參考配置及實現代碼如下:
相關用戶代碼如下:
#define Tpai (2*3.14159)
uint16_t PData[200],Dac_data;
uint16_t i;
for (i=0;i《200;i++)
{
PData[i]=
(uint16_t)(2000*(sin((Tpai/200)*i))+2000);
}
HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );
HAL_Delay(3);
while(1)
{
for(i=0;i《200;i++)
{
DAC1-》DHR12R1= PData[i];
SET_BIT(hdac1.Instance-》SWTRIGR,DAC_SWTRIGR_SWTRIG1);
HAL_Delay(5);
Dac_data = DAC1-》DOR1;//for debug
}
}
總之,不論使用哪種方式,都可以實現我們所期望的結果,即輸出如下正弦波。
好,關于STM32G4的DAC應用就簡單介紹到這里,STM32G4系列的模擬外設豐富而強大,此處算是拋磚引玉。這里做些分享也是為了讓其他有需要的人少走彎路,加速開發進程。【文中代碼都很簡短、直觀,就沒做注釋說明了。還有個客觀原因就是在微信公眾號里排版也很費勁,字符不太好對齊。若有需要交流的可以后臺留言。】
編輯:jq
-
dac
+關注
關注
43文章
2226瀏覽量
190442 -
STM32
+關注
關注
2258文章
10828瀏覽量
352509 -
定時器
+關注
關注
23文章
3218瀏覽量
113697
原文標題:基于STM32G4芯片的DAC應用示例
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論