stm32并不是所有的型号都有DAC功能,只有stm32f103xC/D/E系列 才有DAC转换功能。由于库函数手册中没有相关说明,所以只能通过在MDK提供的相关库文件 stm32f10x_dac.c 中找到相应的DAC函数,做了一番尝试。
折腾了一天,实现了DAC的转换和三角波的输出。我使用的是 stm32rct6的芯片,有两个DAC通道,在PA4和PA5两个引脚上。
DAC的库函数配置相关参数说明:
01
|
void DAC_Configuration(void)
|
03
|
DAC_InitTypeDef DAC_InitStructure;
|
05
|
DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software; //软件触发,不使用定时器 或者外部中断等触发
|
06
|
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不产生三角波(DAC_Wave_Triangle) 或者 噪声波(DAC_Wave_Noise)
|
07
|
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //提高驱动能力可以打开缓冲
|
08
|
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
|
10
|
DAC_DMACmd(DAC_Channel_1, DISABLE); //不使用DMA
|
11
|
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中可以找到。
这里实现:
stm32 DA 数模转换代码:
001
|
#include "stm32f10x.h"
|
004
|
#define DAC_TEST_1 1 //设置DAC输出固定电压
|
005
|
#define DAC_TEST_2 0 //设置DAC输出三角波形
|
007
|
void RCC_Configuration(void);
|
008
|
void GPIO_Configuration(void);
|
009
|
void USART_Configuration(void);
|
010
|
void DAC_Configuration(void);
|
011
|
void TIM_Configuration(void);
|
018
|
USART_Configuration();
|
019
|
GPIO_Configuration();
|
024
|
DAC_SetChannel1Data(DAC_Align_12b_R, 4095); //刷新DA值,数据右对齐 取值范围 0~ 4095
|
025
|
//板子上接的参考电压时3.3v 所以4095时为3.3v
|
026
|
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE); //软件触发,DA值更新
|
028
|
printf("\r\n The Value is : %d \r\n",DAC_GetDataOutputValue(DAC_Channel_1)); //读取DAC引脚输出的值
|
041
|
void DAC_Configuration(void)
|
043
|
DAC_InitTypeDef DAC_InitStructure;
|
047
|
DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software; //软件触发,不使用定时器 或者外部中断等触发
|
048
|
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不产生三角波(DAC_Wave_Triangle) 或者 噪声波(DAC_Wave_Noise)
|
049
|
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //提高驱动能力可以打开缓冲
|
050
|
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
|
054
|
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; //选择定时器2作外部触发源
|
055
|
DAC_InitStructure.DAC_WaveGeneration =DAC_Wave_Triangle; //产生三角波
|
056
|
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047; //三角波的高为2047 最高可以为4095
|
057
|
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //无输出缓冲 提高驱动能力可以打开缓冲
|
058
|
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
|
062
|
DAC_DMACmd(DAC_Channel_1, DISABLE); //不使用DMA
|
064
|
DAC_Cmd(DAC_Channel_1, ENABLE);
|
069
|
void TIM_Configuration(void)
|
071
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
073
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
075
|
TIM_TimeBaseStructure.TIM_Period = 72; //初装值 72 每秒产生1 000 000次更新
|
076
|
TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
|
077
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
|
078
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
079
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
081
|
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出
|
083
|
TIM_Cmd(TIM2, ENABLE);
|
087
|
void Delay(u32 us) //vu32 1us一次
|
094
|
void GPIO_Configuration(void)
|
096
|
GPIO_InitTypeDef GPIO_InitStructure;
|
098
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
099
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
100
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
101
|
GPIO_Init(GPIOA , &GPIO_InitStructure);
|
103
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
104
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
105
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
106
|
GPIO_Init(GPIOA , &GPIO_InitStructure);
|
108
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
109
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
110
|
GPIO_Init(GPIOA , &GPIO_InitStructure);
|
114
|
void RCC_Configuration(void)
|
116
|
/* 定义枚举类型变量 HSEStartUpStatus */
|
117
|
ErrorStatus HSEStartUpStatus;
|
122
|
RCC_HSEConfig(RCC_HSE_ON);
|
124
|
HSEStartUpStatus = RCC_WaitForHSEStartUp();
|
125
|
/* 判断HSE起是否振成功,是则进入if()内部 */
|
126
|
if(HSEStartUpStatus == SUCCESS)
|
128
|
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
|
129
|
RCC_HCLKConfig(RCC_SYSCLK_Div1);
|
130
|
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
|
131
|
RCC_PCLK2Config(RCC_HCLK_Div1);
|
132
|
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
|
133
|
RCC_PCLK1Config(RCC_HCLK_Div2);
|
135
|
FLASH_SetLatency(FLASH_Latency_2);
|
137
|
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
|
138
|
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
|
139
|
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
|
143
|
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
|
144
|
/* 选择SYSCLK时钟源为PLL */
|
145
|
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
146
|
/* 等待PLL成为SYSCLK时钟源 */
|
147
|
while(RCC_GetSYSCLKSource() != 0x08);
|
149
|
/* 打开APB2总线上的GPIOA时钟*/
|
150
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1, ENABLE);
|
152
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC|RCC_APB1Periph_TIM2 , ENABLE);
|
157
|
void USART_Configuration(void)
|
159
|
USART_InitTypeDef USART_InitStructure;
|
160
|
USART_ClockInitTypeDef USART_ClockInitStructure;
|
162
|
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
|
163
|
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
|
164
|
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
|
165
|
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
|
166
|
USART_ClockInit(USART1 , &USART_ClockInitStructure);
|
168
|
USART_InitStructure.USART_BaudRate = 9600;
|
169
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
170
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
171
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
172
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
173
|
USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
|
174
|
USART_Init(USART1,&USART_InitStructure);
|
176
|
USART_Cmd(USART1,ENABLE);
|
180
|
int fputc(int ch,FILE *f)
|
182
|
USART_SendData(USART1,(u8) ch);
|
183
|
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
|
我的板子上stm32输出三角波的效果不是很好,可能是板子的原因。这里使用詹小七同学的程序调试图片
感谢詹小七同学的调试 符合标准的三角波形 效果如下:
阅读(3199) | 评论(0) | 转发(0) |