DAC數模轉換:將數字信號轉換成模擬信號
特性:2個DAC轉換器每個都擁有一個轉換通道
8位或12位單調輸出(8位右對齊;12位左對齊右對齊)
雙ADC通道同時或者分別轉換
外部觸發中斷
- ?電壓源
- 控制部分(外部觸發3個APB1;不使用1個APB1)
- 外部觸發
- 輸出:DAC1-PA4;DAC2-PA5
軟件設計流程:
- 使能端口以及DAC時鐘;設置引腳為模擬輸入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC時鐘GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模擬量輸入
- 初始化DAC,設置DAC工作模式(觸發選擇;DAC波形發生;屏蔽\幅值選擇器;DAC輸出)
typedef struct
{uint32_t DAC_Trigger; /*!< 指定所選DAC通道的外部觸發源此參數可以是 @ref DAC_trigger_selection 中的一個值 */uint32_t DAC_WaveGeneration; /*!< 指定是否生成DAC通道的噪聲波或三角波,或不生成任何波形此參數可以是 @ref DAC_wave_generation 中的一個值 */uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< 指定噪聲波生成的LFSR掩碼或DAC通道的三角波最大生成幅度此參數可以是 @ref DAC_lfsrunmask_triangleamplitude 中的一個值 */uint32_t DAC_OutputBuffer; /*!< 指定是否啟用或禁用DAC通道的輸出緩沖器此參數可以是 @ref DAC_output_buffer 中的一個值 */
}DAC_InitTypeDef;
- 使能DAC輸出通道
DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
- 設置DAC輸出值
/*** @brief 設置DAC通道1的轉換數據* @param DAC_Align: 指定數據對齊方式* 該參數可以是 @ref DAC_data_align 中的一個值,例如:* - DAC_Align_8b_R: 8位右對齊* - DAC_Align_12b_L: 12位左對齊* - DAC_Align_12b_R: 12位右對齊* @param Data: 要轉換的數字值* - 對于8位右對齊,有效范圍為0~255(0x00~0xFF)* - 對于12位右對齊,有效范圍為0~4095(0x000~0xFFF)* - 對于12位左對齊,有效范圍同樣為0~4095,但數據需左移4位* @retval 無* @note 寫入的數據將在下次觸發事件(如軟件觸發或定時器觸發)時轉換為模擬電壓* 轉換后的電壓值 = (Data / 滿量程值) × VREF+* 例如,對于12位DAC且VREF+=3.3V,Data=2048對應電壓1.65V*/
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
代碼如下:
#include "dac.h"/*******************************************************************************
* 函 數 名 : DAC1_Init
* 函數功能 : DAC1初始化函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void DAC1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef DAC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC時鐘GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//DAC_1GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模擬量輸入GPIO_Init(GPIOA,&GPIO_InitStructure);DAC_InitStructure.DAC_Trigger=DAC_Trigger_None; //不使用觸發功能 TEN1=0DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形發生DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值設置DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1輸出緩存關閉 BOFF1=1DAC_Init(DAC_Channel_1,&DAC_InitStructure); //初始化DAC通道1DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右對齊數據格式設置DAC值DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1}
主函數代碼:(按鍵按下,DAC寫入轉換值)
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "key.h"
#include "dac.h"/*******************************************************************************
* 函 數 名 : main
* 函數功能 : 主函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
int main()
{u8 i=0;u8 key;int dac_value=0;u16 dacval;float dac_vol;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷優先級分組 分2組LED_Init();USART1_Init(115200);KEY_Init();DAC1_Init();while(1){key=KEY_Scan(0);//單次按下if(key==KEY_UP_PRESS){dac_value+=400;if(dac_value>=4000){dac_value=4095;}DAC_SetChannel1Data(DAC_Align_12b_R,dac_value);//寫入4095}else if(key==KEY1_PRESS){dac_value-=400; if(dac_value<=0){dac_value=0;}DAC_SetChannel1Data(DAC_Align_12b_R,dac_value); }i++;if(i%20==0){LED1=!LED1;}if(i%50==0){dacval=DAC_GetDataOutputValue(DAC_Channel_1);dac_vol=(float)dacval*(3.3/4096);printf("輸出DAC電壓值為:%.2fV\r\n",dac_vol);}delay_ms(10); }
}