STM32F103VCT6自帶兩個12位DAC,DAC的轉(zhuǎn)換速度一直沒有查到,網(wǎng)上有人說是1MHZ的頻率,那就是1us了。ADC的轉(zhuǎn)換時間在56MHZ工作頻率下為1us,在72MHZ工作頻率下為1.17us。如果AD和DA有對稱關(guān)系的話,那么很可能跟ADC的時間相同。(僅作分析用!)
DAC于我,有兩個用途:輸出波形和輸出固定電壓。先來說說前者的配置。
第一個參數(shù):觸發(fā)方式,DAC_InitStructure.DAC_Trigger??蛇x的外部觸發(fā)源一共有八個。六個是定時器觸發(fā):TIM2,TIM4,TIM5,TIM6,TIM7和TIM8。剩下兩個分別是:EXTI線路9和軟件觸發(fā)。如果采用定時器觸發(fā)的話,就還要再編寫相應(yīng)的定時器函數(shù),這個倒不是很復(fù)雜,和定時器的編寫方式類似。如:DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;//選擇定時器6作外部觸發(fā)源
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0x85;
TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
}
輸出信號頻率計算:假設(shè)輸出一個6個點的鋸齒波波形,則其頻率為:(72MHZ/(0x85+1))*6=89.552KHZ.注意:如果prescaler不為0,則時鐘還要再除以(prescaler+1)
第二個參數(shù):DAC_InitStructure.DAC_WaveGeneration。顧名思義:波形發(fā)生器。STM32內(nèi)部集成了兩個幅度可調(diào)的波形發(fā)生器,可以產(chǎn)生三角波和噪聲波。如果我們使用自定義的緩沖區(qū)的話,就不需要配置這個參數(shù)或者使其為DAC_WaveGeneration_None,但為了避免別人誤以為你忘了配置這個參數(shù),所以還是多寫一句吧,養(yǎng)成好的習(xí)慣。
第三個參數(shù):DAC_InitStructure.DAC_OutputBuffer,即是否使用輸出緩存。輸出緩存的功能主要用來減小輸出阻抗,是STM32的DAC無需外部運放就可以直接驅(qū)動負(fù)載。這里一般設(shè)置成DAC_OutputBuffer_Disable,即關(guān)閉外部緩存。這是為保險起見,萬一驅(qū)動能力不夠強(qiáng)(本人也沒試過@_@),那調(diào)試的時間就又多了一些。
參數(shù)的配置就這么多了,算得上STM32中最簡單的外設(shè)配置之一了!
一般來說,用DAC輸出波形,傳輸?shù)臄?shù)據(jù)比較多,所以采用DMA傳輸可以節(jié)省CPU的開支。所以在調(diào)用DAC_DMACmd(DAC_Channel_1, ENABLE);函數(shù)后別忘了配置DMA函數(shù)。詳細(xì)的配置說明就不寫了,這里把代碼貼出來:
void DMA_Configuration(void)
{
DMA_InitTypeDefDMA_InitStructure;
DMA_DeInit(DMA2_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&FIR_OutPutValueTab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 200;
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_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA2_Channel3, ENABLE);
DMA_ITConfig(DMA2_Channel3,DMA_IT_TC,ENABLE);
}
注意紅色字體寫的那行代碼,當(dāng)我們傳輸多個數(shù)據(jù)時,需要將其設(shè)置為連續(xù)轉(zhuǎn)換!其余就不贅述了。
接下來談?wù)凞AC固定電壓的配置。
STM32的DAC固定電壓配置和上面的波形輸出配置相似,不同的地方在于它要多調(diào)用一個函數(shù):DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);這樣才會輸出固定的電平。
具體配置如下:
void DAC_VOLTAGE_Configuration(void)
{
DAC_InitTypeDefDAC_InitStructure;
DAC_DeInit();
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
//
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);
}
配置完成后,調(diào)用DAC_SetChannel1Data(DAC_Align_12b_R,4000);函數(shù)就可以發(fā)送數(shù)據(jù)了!!極其方便。比起5615,0832之流不知簡便了多少!有兩點要注意:1、該函數(shù)的第一個參數(shù)DAC_Align_12b_R不可依據(jù)設(shè)置ADC外設(shè)地址的方式重寫這個地址,因為這個參數(shù)是不帶基址的,而我們重寫地址后一半會把基址算進(jìn)去,這樣就不對了!(筆者就曾經(jīng)卡在這里!看來凡事不可先入為主,否則問題遲早會發(fā)生。)2、每次改變發(fā)送數(shù)據(jù)時,要同時調(diào)用以下兩個函數(shù):
DAC_SetChannel1Data(DAC_Align_12b_R,4000);
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);
至于為什么,我的理解是:因為DAC改變數(shù)據(jù)后并不會立即寫入寄存器,需要一次更新,由于不是通過定時器觸發(fā)來更新,因此就只能通過調(diào)用函數(shù)的方法來更新。
以上僅是本人結(jié)合《STM32F10xx參考手冊》和編程經(jīng)驗寫的心得,錯漏疏失在所難免,歡迎讀者批評指正,不勝感激!