【STM32】PWM DAC基本原理(实验:PWM实现DAC)

发布者:DreamySerenity最新更新时间:2019-03-12 来源: eefocus关键字:STM32  PWM  DAC 手机看文章 扫描二维码
随时随地手机看文章

虽然STM32F103ZET6具有内部DAC,但是也仅仅只有两条DAC通道,并且STM32还有其他的很多型号是没有DAC的。通常情况下,采用专用的D/A芯片来实现,但是这样就会带来成本的增加。


不过STM32所有的芯片都有PWM输出,并且PWM输出通道很多,资源丰富。因此,我们可以使用PWM+简单的RC滤波来实现DAC的输出从而节省成本。


PWM DAC

PWM DAC的构成原理

PWM本质上其实就是是一种周期一定,而高低电平占空比可调的方波。实际电路的典型PWM波形,如下图所示:



针对PWM的波形进行以下分析:


高电平阶段:计数器当前值从0-CCRx阶段(总时间=CCRx*每两个计数之间的间隔时间);

低电平阶段:计数器当前值从CCRx-ARR-1阶段(总时间=(ARR-1-CCRx)*每两个计数之间的间隔时间)。

如果PWM内容如果不太懂,可以参考链接:【STM32】通用定时器的PWM输出(实例:PWM输出)。


根据PWM的波形,可以用分段函数来进行表示:



其中:T是STM32中计数脉冲的基本周期,也就是STM32定时器的计数频率的倒数;N是PWM波一个周期的计数脉冲个数,也就是STM32的ARR-1的值;n是PWM波一个周期中高电平的计数脉冲个数,也就是STM32的CCRx的值;VH和VL分别是PWM波的高低电平电压值;k为谐波次数;t为时间。


我们将分段函数①式展开成傅里叶级数,得到公式②:



从②式可以看出,式中第1个方括弧为直流分量,第2项为1次谐波分量,第3项为大于1次的高次谐波分量。


式②中的直流分量与n成线性关系,并随着n从0到N,直流分量从VL到VL+VH之间变化。而STM32的DAC功能也就是电压输出,这正是电压输出的DAC所需要的。


因此,如果能把式②中除直流分量外的谐波过滤掉,则可以得到从PWM波到电压输出DAC的转换,即:PWM波可以通过一个低通滤波器进行解调。式②中的第2项的幅度和相角与n有关,频率为1/(NT),其实就是PWM的输出频率。该频率是设计低通滤波器的依据。如果能把1次谐波很好过滤掉,则高次谐波就应该基本不存在了。


PWM DAC的具体实现

通过上面的了解,我们可以得到PWM DAC的分辨率,计算公式如下:分辨率=log2(N)


这里假设n的最小变化为1,当N=256的时候,分辨率就是8位。而STM32的定时器都是16位的,可以很容易得到更高的分辨率,分辨率越高,速度就越慢。不过我们在本章要设计的DAC分辨率为8位。


在8位分辨条件下,我们一般要求1次谐波对输出电压的影响不要超过1个位的精度,也就是3.3/256=0.01289V。假设VH为3.3V,VL为0V,那么一次谐波的最大值是2*3.3/π=2.1V,这就要求我们的RC滤波电路提供至少-20lg(2.1/0.01289)=-44dB的衰减。


STM32的定时器最快的计数频率是72Mhz,8为分辨率的时候,PWM频率为72M/256=281.25Khz。如果是1阶RC滤波,则要求截止频率为1.77Khz,如果为2阶RC滤波,则要求截止频率为22.34Khz。


二阶RC滤波截止频率计算公式为:f=1/2πRC


以上公式要求R55=R56=R,C63=C64=C(R55*C63=R56*C64=RC)。根据这个公式,我们计算出图25.1.2的截止频率为:33.8Khz超过了22.34Khz,这个和我们前面提到的要求有点出入,原因是该电路我们还需要用作PWM DAC音频输出,而音频信号带宽是22.05Khz,为了让音频信号能够通过该低通滤波,同时为了标准化参数选取,所以确定了这样的参数。实测精度在0.5LSB以内。


PWM DAC实例

硬件连接

单片机:STM32F103ZET6

硬件资源:指示灯DS0,WK_UP和KEY1按键,ADC,PWM DAC

具体的硬件连接的图如下所示:



STM32控制程序

//设置输出电压

//vol:0~330,代表0~3.3V

void PWM_DAC_Set(u16 vol)

{

float temp=vol;

temp/=100;

temp=temp*256/3.3;

TIM_SetCompare1(TIM1,temp);

}

 int main(void)

 {  

u16 adcx;

float temp;

  u8 t=0;  

u16 pwmval=0;

u8 key;

delay_init();     //延时函数初始化   

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

KEY_Init();   //KEY初始化

  LED_Init();      //LED端口初始化

usmart_dev.init(72); //初始化USMART

LCD_Init(); //LCD初始化

  Adc_Init();   //ADC初始化

TIM1_PWM_Init(255,0); //TIM1 PWM初始化, Fpwm=72M/256=281.25Khz.

  TIM_SetCompare1(TIM1,100);//初始值为0

     

 

  POINT_COLOR=RED;//设置字体为红色 

LCD_ShowString(60,50,200,16,16,"WarShip STM32");

LCD_ShowString(60,70,200,16,16,"PWM DAC TEST");

LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(60,110,200,16,16,"2015/1/15");

LCD_ShowString(60,130,200,16,16,"WK_UP:+  KEY1:-");

//显示提示信息       

POINT_COLOR=BLUE;//设置字体为蓝色

LCD_ShowString(60,150,200,16,16,"PWM VAL:");       

LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V");       

LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");


TIM_SetCompare1(TIM1,pwmval);//初始值           

while(1)

{

t++;

key=KEY_Scan(0);   

if(key==WKUP_PRES)

{  

if(pwmval<250)pwmval+=10;

TIM_SetCompare1(TIM1,pwmval); //输出

}else if(key==KEY1_PRES)

{

if(pwmval>10)pwmval-=10;

else pwmval=0;

TIM_SetCompare1(TIM1,pwmval); //输出

}  

if(t==10||key==KEY1_PRES||key==WKUP_PRES) //WKUP/KEY1按下了,或者定时时间到了

{   

adcx=TIM_GetCapture1(TIM1);

LCD_ShowxNum(124,150,adcx,4,16,0);      //显示DAC寄存器值

temp=(float)adcx*(3.3/256); //得到DAC电压值

adcx=temp;

  LCD_ShowxNum(124,170,temp,1,16,0);      //显示电压值整数部分

  temp-=adcx;

temp*=1000;

LCD_ShowxNum(140,170,temp,3,16,0x80); //显示电压值的小数部分

  adcx=Get_Adc_Average(ADC_Channel_1,20);  //得到ADC转换值   

temp=(float)adcx*(3.3/4096); //得到ADC电压值

adcx=temp;

  LCD_ShowxNum(124,190,temp,1,16,0);      //显示电压值整数部分

  temp-=adcx;

temp*=1000;

LCD_ShowxNum(140,190,temp,3,16,0x80); //显示电压值的小数部分

t=0;

LED0=!LED0;    

}     

delay_ms(10);

 

}

 }


关键字:STM32  PWM  DAC 引用地址:【STM32】PWM DAC基本原理(实验:PWM实现DAC)

上一篇:【STM32】DMA基本原理、寄存器、库函数(DMA一般步骤)
下一篇:【STM32】DAC基本原理、寄存器、库函数(DAC一般步骤)

推荐阅读最新更新时间:2024-03-16 16:25

用于反激式适配器的多功能PWM控制器FAN6754
当你把几乎任何小型计算或消费电子设备插入电源插座时,便不难发现手中的插头大部分都连接到外部电源(EPS)。EPS是所有小型电子设备工作的必不可少的部分,单单在美国,就有多达15亿个在使用中 (据业界估计,在全球则超过30亿个)。   EPS的核心是多功能PWM控制器集成电路(IC)(如飞兆半导体的FAN6754)以及功率 MOSFET,它们联合工作,为负载高效分配能量,并监控电路以保护系统。所有元器件都被集成在一个精简的封装中,与过去那种看起来老旧笨重的电源成了强烈对比。   PWM控制器可被视为电源的大脑。它监控反馈数据并调整占空比,以调节开关模式电源(SMPS)的输出电压,帮助系统满足所有相关节能标准。   这种绿色
[电源管理]
STM32的堆栈(Heap&Stack)空间
最近做的一个项目遇到一个很莫名的错误,程序运行到某一部分时便会卡死,分析后,感觉在逻辑上并无错误,但是就是会卡死,而且不是偶然。 后来在网上查找资料怀疑是内存溢出,然后调试发现是两个函数中的的局部变量申请的内存空间太大,所以错误应该是栈溢出了。将这两个变量使用malloc申请堆段空间完美解决。 下面是对STM32的堆栈(Heap&Stack)小结: 内存分配空间 内核保护区 栈段 堆段 数据区 代码区 代码区 :静态区 常量(const) 函数代码逻辑 数据区:静态区 全局变量 局部变量+static 堆段:动态区,管理者是程序员 malloc申请的空间 栈段:动态区,管理每个子函数的空间,管理者是
[单片机]
<font color='red'>STM32</font>的堆栈(Heap&Stack)空间
关于STM32的待机唤醒功能
本文我们来学习下STM32的待机唤醒功能。要实现的功能是:系统运行时 D1 指示灯闪烁,5 秒后进入待机模式,D1 指示灯熄灭,同时串口 printf输出相关提示信息,可通过 K_UP 按键实现唤醒。学习本内容可以参考《STM32F10x中文参考手册》-4 电源控制器(PWR)章节。 STM32 低功耗模式介绍 很多单片机具有低功耗模式,比如 MSP430、STM8L等。我们的STM32也不例外,相关文章:STM32低功耗模式。默认情况下,系统复位或上电复位后,微控制器进入运行模式。在运行模式下,HCLK 为 CPU 提供时钟,并执行程序代码。当 CPU 不需继续运行(例如等待外部事件)时,可以利用多种低功耗模式来节省功耗。用
[单片机]
关于<font color='red'>STM32</font>的待机唤醒功能
深入理解STM32之储存器和总线架构1(基于STM32F411)
本文转载自http://blog.csdn.net/charmingsun/article/details/52258419 官方文档: STM32F411 参考手册 STM32F411 数据手册 Cortex™-M4F 编程手册 STM32 微控制器系统存储器自举模式应用笔记 STM32™ 自举程序中使用的 USART 协议 ARM Cortex™-M Programming Guide to Memory Barrier Instructions 一、系统架构 主系统由 32 位多层 AHB 总线矩阵构成,可实现以下部分的互连: 有关AHB总线和APB总线的更多信息请参考博文: 浅析AMBA规范以及AMBA
[单片机]
解决STM32在MDK-ARM(KEIL)编译时出现 已停止工作
若是关闭对话框还可继续编译,只是到最后linking时显示一个error,提示 ..OBJXXX.axf: error: L6002U: Could not open file ..objXXX.o: No such file or directory ..OBJtest.axf - 1 Error(s), 0 Warning(s). 从网上查到很多相同问题,但是回答者都是简简单单说几句是什么原因就走了...这就是大神的通病吧,忙活自己的事去了... 解决: 1、右键我的电脑-管理-本地用户和组-用户 把里面你的中文用户名改成英文。 2、右键我的电脑-属性 右下-计算机名称、域和工作组设置-更改设置 改成
[单片机]
解决<font color='red'>STM32</font>在MDK-ARM(KEIL)编译时出现 已停止工作
STM32的ADC系统的功能特性
一、STM32F1和F4的区别? 内核不同:F1是Cortex-M3内核,F4是Cortex-M4内核; 主频不同:F1主频72MHz,F4主频168MHz; 浮点运算:F1无浮点运算单位,F4有; 功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等; 内存大小:F1内部SRAM最大64K,F4有192K(112+64+16)。 二、介绍以下STM32启动过程? 通过Boot引脚设定,寻找初始地址 初始化栈指针 __initial_sp 指向复位程序 Reset_Hander 设置异常中断 HardFault_Handler 设置系统时钟 SystemInit 调用C库函数 _ma
[单片机]
<font color='red'>STM32</font>的ADC系统的功能特性
比较精简的stm32编码器程序
01.#define ROTATE_A PAin(2) 02.#define ROTATE_B PAin(3) 03.s16 DATA=0; 04. 05.void EXti2_IRQHandler(void) 06.{ 07. IF(EXTI_GetITStatus(EXTI_Line2) != RESET) 08. { 09. if(ROTATE_A!=ROTATE_B) 10. { 11. DATA++; 12. } 13. else DATA--; 14. EXTI_ClearITPendingBit(EXTI_Line2); 15. }
[单片机]
比较精简的<font color='red'>stm32</font>编码器程序
基于A3967SLB的步进电机细分驱动系统设计
步进电机精度高,惯性小,在不失步的情况下没有步距误差积累,特别适用于数字控制的定位系统。传统的细分驱动电路由细分环行分配器、放大器和合成器等部分组成。这种电路应用复杂,灵活性差。本文利用A3967SLB作为步进电机微控芯片,简化了步进电机的控制实现。由于单片机资源没有PC丰富,人机界面也没有PC友好,因此,本文采用了主从式结构,即PC用于管理,单片机用于执行。 由A3967SLB构成步进电机的驱动部分 A3967SLB是美国Allegro公司生产的PWM恒流控制微步距驱动二相步进电机专用驱动器。它的工作电压可达30V,驱动电流达750mA,一个A3967SLB即可驱动一台二相步进电机,可实现8细分驱动。芯片内部的PWM电流控制电
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved