stm32 DA 数模转换

stm32并不是所有的型号都有DAC功能,只有stm32f103xC/D/E系列 才有DAC转换功能。由于库函数手册中没有相关说明,所以只能通过在MDK提供的相关库文件 stm32f10x_dac.c 中找到相应的DAC函数,做了一番尝试。
    折腾了一天,实现了DAC的转换和三角波的输出。我使用的是 stm32rct6的芯片,有两个DAC通道,在PA4和PA5两个引脚上。
 
    DAC的库函数配置相关参数说明:
void DAC_Configuration(void)
{
	DAC_InitTypeDef	DAC_InitStructure; 

 	DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software; 	         //软件触发,不使用定时器 或者外部中断等触发
  	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;   //不产生三角波(DAC_Wave_Triangle) 或者 噪声波(DAC_Wave_Noise)
  	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; 	  //提高驱动能力可以打开缓冲
  	DAC_Init(DAC_Channel_1, &DAC_InitStructure); 

       DAC_DMACmd(DAC_Channel_1, DISABLE);		//不使用DMA
	DAC_Cmd(DAC_Channel_1, ENABLE);

}
     DAC_InitStructure.DAC_Trigger :触发方式。可选的外部触发源一共有八个。
            六个是定时器触发:TIM2,TIM4,TIM5,TIM6,TIM7和TIM8。           
            剩下两个分别是:EXTI线路9和软件触发。
 
     DAC_InitStructure.DAC_WaveGeneration:波形发生器。STM32内部集成了两个幅度可调的波形发生器,可以产生三角波(DAC_Wave_Triangle)和噪声波(DAC_Wave_Noise)。如果我们使用自定义的缓冲区输出波形,就不需要配置这个参数或者使其为DAC_WaveGeneration_None.
 
    DAC_InitStructure.DAC_OutputBuffer:即是否使用输出缓存。输出缓存的功能主要用来减小输出阻抗,是STM32的DAC无需外部运放就可以直接驱动负载。
 
相关参数在stm32f10x_dac.h中可以找到。
 
这里实现:
  •     设置DAC输出固定电压
  •     设置DAC输出三角波形
 

stm32 DA 数模转换代码:
#include "stm32f10x.h"
#include "stdio.h"

#define  DAC_TEST_1 1  		//设置DAC输出固定电压
#define  DAC_TEST_2 0    		//设置DAC输出三角波形

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void DAC_Configuration(void);
void TIM_Configuration(void);

void Delay(u32 us);

int main(void)
{
  	RCC_Configuration();
	USART_Configuration();
  	GPIO_Configuration();
	DAC_Configuration();

#if DAC_TEST_1 

	DAC_SetChannel1Data(DAC_Align_12b_R, 4095);		//刷新DA值,数据右对齐 取值范围 0~ 4095 	
													//板子上接的参考电压时3.3v 所以4095时为3.3v   
	DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);   //软件触发,DA值更新

	printf("\r\n The Value is : %d \r\n",DAC_GetDataOutputValue(DAC_Channel_1));  //读取DAC引脚输出的值

#elif DAC_TEST_2

   	TIM_Configuration();

#endif

	while(1); 

}


void DAC_Configuration(void)
{
	DAC_InitTypeDef	DAC_InitStructure; 

#if DAC_TEST_1 

 	DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software; 			  //软件触发,不使用定时器 或者外部中断等触发
  	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;   //不产生三角波(DAC_Wave_Triangle) 或者 噪声波(DAC_Wave_Noise)
  	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; 	  //提高驱动能力可以打开缓冲
  	DAC_Init(DAC_Channel_1, &DAC_InitStructure); 

#elif DAC_TEST_2 

	DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;	//选择定时器2作外部触发源
  	DAC_InitStructure.DAC_WaveGeneration =DAC_Wave_Triangle;   //产生三角波
	DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047; //三角波的高为2047  最高可以为4095 		
  	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; 	  //无输出缓冲 提高驱动能力可以打开缓冲
  	DAC_Init(DAC_Channel_1, &DAC_InitStructure); 

#endif

	DAC_DMACmd(DAC_Channel_1, DISABLE);		//不使用DMA

	DAC_Cmd(DAC_Channel_1, ENABLE);

}


void TIM_Configuration(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

    TIM_TimeBaseStructure.TIM_Period = 72;          //初装值 72 每秒产生1 000 000次更新
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0;      
    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);     
      
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出
	
   	TIM_Cmd(TIM2, ENABLE);
}


void Delay(u32 us)		 //vu32 1us一次
{
	u32 time=100*us/7;		 
	while(--time);			 
}

  
void GPIO_Configuration(void)
{
  	GPIO_InitTypeDef GPIO_InitStructure;

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 
		
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 
}


void RCC_Configuration(void)
{
	/* 定义枚举类型变量 HSEStartUpStatus */
	ErrorStatus HSEStartUpStatus;

  	/* 复位系统时钟设置*/
  	RCC_DeInit();
  	/* 开启HSE*/
  	RCC_HSEConfig(RCC_HSE_ON);
  	/* 等待HSE起振并稳定*/
  	HSEStartUpStatus = RCC_WaitForHSEStartUp();
	/* 判断HSE起是否振成功,是则进入if()内部 */
  	if(HSEStartUpStatus == SUCCESS)
  	{
    	/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
    	RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    	/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
    	RCC_PCLK2Config(RCC_HCLK_Div1); 
    	/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
    	RCC_PCLK1Config(RCC_HCLK_Div2);
    	/* 设置FLASH延时周期数为2 */
    	FLASH_SetLatency(FLASH_Latency_2);
    	/* 使能FLASH预取缓存 */
    	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    	/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
    	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    	/* 使能PLL */ 
    	RCC_PLLCmd(ENABLE);
    	/* 等待PLL输出稳定 */
    	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    	/* 选择SYSCLK时钟源为PLL */
    	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    	/* 等待PLL成为SYSCLK时钟源 */
    	while(RCC_GetSYSCLKSource() != 0x08);
  	} 
  	/* 打开APB2总线上的GPIOA时钟*/
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1, ENABLE);

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC|RCC_APB1Periph_TIM2 , ENABLE);
		
}

 
void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;

	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                      
	USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART1 , &USART_ClockInitStructure);

	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	USART_Init(USART1,&USART_InitStructure);

 	USART_Cmd(USART1,ENABLE);
}


int fputc(int ch,FILE *f)
{
	USART_SendData(USART1,(u8) ch);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
	return ch;
}
 
 我的板子上stm32输出三角波的效果不是很好,可能是板子的原因。这里使用詹小七同学的程序调试图片  
 感谢詹小七同学的调试 符合标准的三角波形 效果如下:
 
dac.jpg
  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值