关闭

stm32 DA 数模转换

416人阅读 评论(0) 收藏 举报
分类:
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
0
0
查看评论

STM32的DAC数模转换详解(STM32神舟IV号-库函数版)程序,亲测能用

  • 2017-11-27 21:18
  • 497KB
  • 下载

基于STM32F103的 PID算法 ,内部AD和DA实现。

  • 2014-07-22 11:20
  • 621KB
  • 下载

cortex_m3_stm32嵌入式学习笔记(十八):DAC实验(数模转换)

STM32 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。 DAC可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。 DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。 DAC 模块有 2 个输出通道,每个通道都有单独的转换器。...
  • qq_16255321
  • qq_16255321
  • 2015-01-25 16:55
  • 3613

51单片机STC89C52 DA数模转换

CSDA BIT P3.2 WRR BIT P3.6 WELA BIT P2.7 DULA BIT P2.6 ORG 0000H LOOP0: MOV P0,#0FFH ;关数码管显示 SETB WELA CLR WELA CLR DULA SETB CSDA SETB W...
  • zhoukouguren
  • zhoukouguren
  • 2013-11-11 22:59
  • 2148

STM32 DMA及其DAM与DA实现正弦波生成

DMA有什么用?        直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 有多少个DMA资源?     ...
  • hongkangwl
  • hongkangwl
  • 2013-11-06 15:43
  • 4751

STM32数模转换-DAC_DMA

DAC—数模转换器 DAC即是数模转换器,就是将数字量转换成模拟量,原理什么的大家应该都懂,直接跳入如何使用: STM32的DAC使用起来非常简单,首先将连接DAC通道的GPIO引脚配置为模拟状态,然后初始化DAC,一共只有四个参数需要初始化,其中最重要的是触发源:这个参数的作用是,每来一个触...
  • Wind4study
  • Wind4study
  • 2016-11-27 19:53
  • 965

数模转换原理

数模转换和模数转换原理
  • chungle2011
  • chungle2011
  • 2014-11-17 14:31
  • 520

模数转换(A/D)与数模转换(D/A)

单片机是一个典型的数字系统,数字系统只能呢个对输入的数字信号进行处理,其输出信号也是数字的。但工业或者生活中的很多量都是模拟量,这些模拟量可以通过传感器变成与之对应的电压、电流等模拟量。为了实现数字系统对这些电模拟量的测量,运算和控制,就需要一个模拟量和数字量之间的相互转化的过程。 A...
  • cmh477660693
  • cmh477660693
  • 2016-04-10 20:05
  • 6041

数模转换(ADC)的应用笔记(1)

数模转换(ADC)的应用笔记 智能时代,数字信号已体现在我们生活的方方面面,A/D,D/A是重要的基础。智能手机触摸信号需要转换为数字信号才能分辨触摸位置、数字去抖;打电话或者麦克风需要将模拟声信号转换为数字信号以便存储回放、语音识别;移动通信到4G时代,速率已经达到了300Mbps,手机和基站之...
  • u011609697
  • u011609697
  • 2015-03-30 15:26
  • 1090

ADDA数模转换——PCF8591

#include <reg52.h> #include <intrins.h> #define MAIN_Fosc 11059200UL //宏定义主时钟HZ #define PCF8591_ADDR 0x90 //PCF8591地址 #de...
  • xidoxu
  • xidoxu
  • 2015-08-15 16:53
  • 645
    最新评论
    个人资料
    • 访问:71546次
    • 积分:215
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:111篇
    • 译文:1篇
    • 评论:3条