Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216272
  • 博文数量: 52
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-06 09:31
文章分类

全部博文(52)

文章存档

2015年(1)

2014年(44)

2013年(7)

我的朋友

分类: 嵌入式

2014-05-30 11:05:35

stm32并不是所有的型号都有DAC功能,只有stm32f103xC/D/E系列 才有DAC转换功能。由于库函数手册中没有相关说明,所以只能通过在MDK提供的相关库文件 stm32f10x_dac.c 中找到相应的DAC函数,做了一番尝试。
    折腾了一天,实现了DAC的转换和三角波的输出。我使用的是 stm32rct6的芯片,有两个DAC通道,在PA4和PA5两个引脚上。
 
    DAC的库函数配置相关参数说明:
01 void DAC_Configuration(void)
02 {
03     DAC_InitTypeDef DAC_InitStructure;
04  
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);
09  
10        DAC_DMACmd(DAC_Channel_1, DISABLE);       //不使用DMA
11     DAC_Cmd(DAC_Channel_1, ENABLE);
12  
13 }
     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 数模转换代码:
001 #include "stm32f10x.h"
002 #include "stdio.h"
003  
004 #define  DAC_TEST_1 1       //设置DAC输出固定电压
005 #define  DAC_TEST_2 0           //设置DAC输出三角波形
006  
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);
012  
013 void Delay(u32 us);
014  
015 int main(void)
016 {
017     RCC_Configuration();
018     USART_Configuration();
019     GPIO_Configuration();
020     DAC_Configuration();
021  
022 #if DAC_TEST_1
023  
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值更新
027  
028     printf("\r\n The Value is : %d \r\n",DAC_GetDataOutputValue(DAC_Channel_1));  //读取DAC引脚输出的值
029  
030 #elif DAC_TEST_2
031  
032     TIM_Configuration();
033  
034 #endif
035  
036     while(1);
037  
038 }
039  
040  
041 void DAC_Configuration(void)
042 {
043     DAC_InitTypeDef DAC_InitStructure;
044  
045 #if DAC_TEST_1
046  
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);
051  
052 #elif DAC_TEST_2
053  
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);
059  
060 #endif
061  
062     DAC_DMACmd(DAC_Channel_1, DISABLE);     //不使用DMA
063  
064     DAC_Cmd(DAC_Channel_1, ENABLE);
065  
066 }
067  
068  
069 void TIM_Configuration(void)
070 {
071     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
072  
073     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
074  
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);    
080        
081     TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出
082      
083     TIM_Cmd(TIM2, ENABLE);
084 }
085  
086  
087 void Delay(u32 us)       //vu32 1us一次
088 {
089     u32 time=100*us/7;      
090     while(--time);          
091 }
092  
093    
094 void GPIO_Configuration(void)
095 {
096     GPIO_InitTypeDef GPIO_InitStructure;
097  
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);
102          
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);
107  
108     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
109     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          
110     GPIO_Init(GPIOA , &GPIO_InitStructure);
111 }
112  
113  
114 void RCC_Configuration(void)
115 {
116     /* 定义枚举类型变量 HSEStartUpStatus */
117     ErrorStatus HSEStartUpStatus;
118  
119     /* 复位系统时钟设置*/
120     RCC_DeInit();
121     /* 开启HSE*/
122     RCC_HSEConfig(RCC_HSE_ON);
123     /* 等待HSE起振并稳定*/
124     HSEStartUpStatus = RCC_WaitForHSEStartUp();
125     /* 判断HSE起是否振成功,是则进入if()内部 */
126     if(HSEStartUpStatus == SUCCESS)
127     {
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);
134         /* 设置FLASH延时周期数为2 */
135         FLASH_SetLatency(FLASH_Latency_2);
136         /* 使能FLASH预取缓存 */
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);
140         /* 使能PLL */
141         RCC_PLLCmd(ENABLE);
142         /* 等待PLL输出稳定 */
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);
148     }
149     /* 打开APB2总线上的GPIOA时钟*/
150     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1, ENABLE);
151  
152     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC|RCC_APB1Periph_TIM2 , ENABLE);
153          
154 }
155  
156   
157 void USART_Configuration(void)
158 {
159     USART_InitTypeDef USART_InitStructure;
160     USART_ClockInitTypeDef USART_ClockInitStructure;
161  
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);
167  
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);
175  
176     USART_Cmd(USART1,ENABLE);
177 }
178  
179  
180 int fputc(int ch,FILE *f)
181 {
182     USART_SendData(USART1,(u8) ch);
183     while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
184     return ch;
185 }
 
 我的板子上stm32输出三角波的效果不是很好,可能是板子的原因。这里使用詹小七同学的程序调试图片  
 感谢詹小七同学的调试 符合标准的三角波形 效果如下:
 
dac.jpg
阅读(3120) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~