DAC模塊作為CKS32F4xx系列的一個常用外設,可以將數字信號轉換成模擬信號,最高分辨率可達12位,且兩個獨立DAC輸出通道轉換互不影響,各個通道均能使用DMA功能,可由軟硬件觸發。因此,為了實現DAC輸出正弦波,擬采用一定的時間向DAC的數據寄存器寫入數據,隨后進行數模轉換輸出不同的電壓,最后在時間軸上顯示出波形。同時為了不占用CPU資源,配置DMA建立傳輸通道,以便數據快速的從內存搬移到外設。且在DAC初始化時,可以設置成定時器觸發,待定時器溢出就會觸發DAC工作,所以只要修改定時器的定時時間,就可改變正弦波周期。
DAC簡述
①:DAC將VREF+引腳作為參考電壓,在實際使用時將VSSA接地,同時把VREF+和VDDA接3.3V,DAC即可獲得0~3.3V的輸出電壓。
②:數模轉換器以VREF+作為參考電源,將DAC的數據寄存器“DORx”的數字編碼轉換成模擬信號并由右側的“DAC_OUTx”通道輸出。在CKS32有2個這樣的DAC部件,其中PA4對應通道1,PA5對應通道2。
③:控制邏輯可以控制數據寄存器“DORx”加入一些偽噪聲信號或配置產生三角波信號。
④:使用DAC時,數據會被先寫入到DHRx寄存器,隨后DAC會根據觸發配置進行處理,最后將數據傳輸至DORx。DAC的觸發源有三種,分別為:外部中斷源觸發、定時器觸發和軟件控制觸發。
對于單DAC通道x的三種數據格式
8位數據右對齊:
用戶須將數據寫入寄存器DAC_DHR8Rx[7:0]位(實際是存入寄存器DHRx[11:4]位)。
12位數據左對齊:
用戶須將數據寫入寄存器DAC_DHR12Lx[15:4]位(實際是存入寄存器DHRx[11:0]位)。
12位數據右對齊:
用戶須將數據寫入寄存器DAC_DHR12Rx[11:0]位(實際是存入寄存器DHRx[11:0]位)。
數字輸入經過DAC被線性地轉換為模擬電壓輸出,任一DAC通道引腳上的輸出電壓滿足下面的關系:
本案例中選擇DAC的通道1,并采用12位的右對齊方式,通過查閱《CKS32F4xx參考手冊》DAC和DMA章節可知,DAC1對應DMA1控制器通道7數據流5。
總的來說,DAC的輸出是由DORx寄存器直接控制的,而用戶寫的數據是要寫入DHRx寄存器,然后通過DHRx間接操作DORx,最終實現DAC的輸出。
DAC輸出正弦波配置
本文采用DAC1+TIM2+DMA1的方式,通過TIM2觸發DAC1轉換,轉換完成后通過DMA1輸出,主要步驟如下:
①由Matlab計算一個周期的正弦波數組;
②根據一個正弦波周期內點數和所需正弦波頻率確定定時器觸發間隔;
③初始化DAC1輸出管腳和工作模式;
④配置觸發DAC1用的定時器2;
⑤配置DMA1自主搬運正弦波數組。
待上述配置完成后,將PA4引腳接到示波器上,即可顯示正弦波。以下是DAC的詳細配置。
(1)正弦波數組生成
以下代碼用于生成正弦波波形表:
for(i=0;i<100;i++) { ????Sine12bit[i]=2048*sin(1.0*i/(100-?1)*2*PI)+2048; }
從上述函數可以看出,正弦波的幅度被控制在0~4096之間,一個周期被平均分成100份,即100個點代表一個周期的波形,數組Sine12bit里面是100個采樣點。
constuint16_tSine12bit[100]={ 0x0800,0x0881,0x0901,0x0980,0x09FD,0x0A79,0x0AF2,0x0B68,0x0BDA,0x0C49,0x0CB3,0x0D19,0x0D79,0x0DD4,0x0E29,0x0E78,0x0EC0,0x0F02,0x0F3C,0x0F6F,0x0F9B,0x0FBF,0x0FDB,0x0FEF,0x0FFB,0x0FFF,0x0FFB,0x0FEF,0x0FDB,0x0FBF,0x0F9B,0x0F6F,0x0F3C,0x0F02,0x0EC0,0x0E78,0x0E29,0x0DD4,0x0D79,0x0D19,0x0CB3,0x0C49,0x0BDA,0x0B68,0x0AF2,0x0A79,0x09FD,0x0980,0x0901,0x0881,0x0800,0x077F,0x06FF,0x0680,0x0603,0x0587,0x050E,0x0498,0x0426,0x03B7,0x034D,0x02E7,0x0287,0x022C,0x01D7,0x0188,0x0140,0x00FE,0x00C4,0x0091,0x0065,0x0041,0x0025,0x0011,0x0005,0x0001,0x0005,0x0011,0x0025,0x0041,0x0065,0x0091,0x00C4,0x00FE,0x0140,0x0188,0x01D7,0x022C,0x0287,0x02E7,0x034D,0x03B7,0x0426,0x0498,0x050E,0x0587,0x0603,0x0680,0x06FF,0x077F};
(2)GPIO和DAC模式配置
該部分為輸出引腳配置和DAC通道1配置,代碼如下:
voidDAC1_GPIO_Init(void) { GPIO_InitTypeDefGPIO_InitStructure; DAC_InitTypeDefDAC_InitStructure; /*EnableGPIOAclock*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);/*EnableDACclock*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);/*ConfiguretheDACPintoAnalogmode:DAC_OUT1--PA4*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; GPIO_Init(GPIOA, GPIO_InitStructure); /*ConfigureDACChannel_1*/ DAC_InitStructure.DAC_Trigger=DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable;DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;DAC_Init(DAC_Channel_1, DAC_InitStructure); DAC_Cmd(DAC_Channel_1,ENABLE);//EnableDACChannel_1. DAC_DMACmd(DAC_Channel_1,ENABLE);//EnableDACchannel_1DMArequest. }
在DAC1_GPIO_Init函數中,實現了相應GPIO引腳(PA4)的初始化和DAC工作模式配置。其中為了避免寄生的干擾和額外的功耗,應將PA4引腳設置成模擬輸入模式(AIN),如此方可正常工作。
而對DAC工作模式進行配置時,可查看CKS官方提供的DAC_InitTypeDef結構體,該結構體中主要包含了DAC_CR寄存器的各寄存器配置。如下是DAC_InitTypeDef結構體成員簡述:
(a)DAC_Trigger
該成員用于DAC的觸發模式配置,由上文DAC通道框圖可知,共有三種觸發模式,分別是定時器觸發(DAC_Trigger_T2/4/5/6/7/8_TRGO)、軟件觸發(DAC_Trigger_Software)和EXTI_9觸發方式(DAC_Trigger_Ext_IT9)。
(b)DAC_WaveGeneration
該成員可配置輸出偽噪聲和三角波輸出(DAC_WaveGeneration_Noise/Triangle),若使用自定義輸出,應配置為DAC_WaveGeneration_None。
(c)DAC_OutputBuffer
該成員用于控制是否使能DAC的輸出緩沖(DAC_OutputBu?er_Enable/Disable)。若需要直接驅動外部負載,可以使能該成員以減小輸出阻抗。
(d)DAC_LFSRUnmask_TriangleAmplitude
該成員通過控制DAC_CR的MAMP2位設置LFSR寄存器位的數據,即當使用偽噪聲或三角波輸出時要疊加到DHRx的值。若使用偽噪聲輸出時LFSR=0xAAA,這時該結構體成員可賦值為DAC_LFSRUnmask_Bit0~DAC_LFSRUnmask_Bit11_0;若使用三角波輸出時,這時該結構體成員可賦值為DAC_TriangleAmplitude_1~DAC_TriangleAmplitude_4096,可用于設置三角波的最大幅值。
本例中,將DAC通道1配置成定時器TIM2觸發,不使用波形發生器和不使用輸出緩存,不使用輸出緩存是因為CKS32的DAC無需外部運放就可以直接驅動負載,三角波振幅一項雖然本案例沒有用到,可以配置成任意,但此項不可缺,最后調用DAC_Cmd、DAC_DMACmd函數使能DAC通道1和DMA的請求。
(3)定時器配置
該部分是配置觸發DAC的定時器TIM2,通過設定觸發的間隔,從而間接控制正弦波周期,TIM2的工作決定DMA與DAC的工作頻率,代碼如下:
voidTIM2_Init(void) { TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure; /*EnableTimer2clock.*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);/*ConfigureTimer2--ClockFrequencyis84MHz*/ TIM_TimeBaseStructure.TIM_Period=83;TIM_TimeBaseStructure.TIM_Prescaler=0x0; TIM_TimeBaseStructure.TIM_ClockDivision=0x0; TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure);/*ConfigurethetriggersourceforTimer2.*/TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); TIM_Cmd(TIM2,ENABLE);//EnableTimer2. }
前文的DAC已選用TIM2當觸發源,此處TIM2的定時周期被配置為83,向上計數,不分頻。CKS32F4xx系列的主頻是168MHz,TIM2的時鐘是84MHz,所以TIM2的更新頻率是84M/(TIM_Period+1)/(TIM_Prescaler+1),即TIM2每隔1us觸發一次DAC事件,不需要設置中斷,當定時器向上計數至指定值時,產生Update事件,同時觸發DAC把DHRx寄存器的數據轉移到DORx,開始進行轉換。由于正弦波數組是100個采樣點,可得正弦波的輸出頻率為:
(4)DMA配置
該部分主要完成數據的傳輸,代碼如下:
voidDMA_InitForDAC(void) { DMA_InitTypeDefDMA_InitStructure; /*EnableDMA1clock.*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);/*ConfigureDMA1Stream5Channel_7ForDAC1*/ DMA_InitStructure.DMA_Channel=DMA_Channel_7;DMA_InitStructure.DMA_PeripheralBaseAdDMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)Sine12bit;DMA_InitStructure.DMA_DIR=DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize=100; DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; DMA_InitStructure.DMA_Priority=DMA_Priority_High;DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull;DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;DMA_Init(DMA1_Stream5, DMA_InitStructure);DMA_Cmd(DMA1_Stream5,ENABLE);//EnableDMA1Stream5. }
需要注意的是,DAC->DHR12R1對應數據寄存器的地址,正弦波數組Sine12bit對應數據輸入地址,DMA緩存的個數是單個正弦波周期對應的點數,DMA需工作在循環模式,由于正弦波數組Sine12bit定義為16位,那么涉及數據傳輸的變量都要配置成半字16位。經過上述的配置后,定時器TIM2每隔1us就會觸發DMA搬運正弦波數組的一個數據到DAC通道1寄存器進行轉換,每搬運100個數據即一個完整周期后,DMA開始循環,最終循環輸出正弦波。
(5)主函數配置
本例程主函數主要對前文所述函數依次調用,程序編譯下載至開發板,使用示波器測量PA4引腳即可查看輸出10kHz的正弦波形,代碼如下:
intmain(void) { DAC1_GPIO_Init(); TIM2_Init(); DMA_InitForDAC(); while(1); }
來源:中科芯MCU
-
寄存器
+關注
關注
31文章
5336瀏覽量
120230 -
dac
+關注
關注
43文章
2291瀏覽量
190975 -
定時器
+關注
關注
23文章
3246瀏覽量
114719 -
dma
+關注
關注
3文章
560瀏覽量
100544
發布評論請先 登錄
相關推薦
評論