第二十七章 PWM DAC实验
[mw_shl_code=c,true]1.硬件平台:正点原子探索者STM32F407开发板
2.软件平台:MDK5.1
3.固件库版本:V1.4.0
[/mw_shl_code]
上一章,我们介绍了
STM32F4自带
DAC模块的使用,但有时候,可能两个
DAC不够用,此时,我们可以通过
PWM+RC滤波来实一个
PWM DAC。本章我们将向大家介绍如何使用
STM32F4的
PWM来设计一个
DAC。我们将使用按键(或
USMART)控制
STM32F4的
PWM输出,从而控制
PWM
DAC的输出电压,通过
ADC1的通道
5采集
PWM DAC的输出电压,并在
LCD模块上面显示
ADC获取到的电压值以及
PWM DAC的设定输出电压值等信息。本章将分为如下几个部分:
27.1 PWM DAC简介
27.2 硬件设计
27.3 软件设计
27.4 下载验证
27.1
PWM DAC简介
有时候,
STM32F4自带的
2路
DAC可能不够用,需要多路
DAC,外扩
DAC成本又会高不少。此时,我们可以利用
STM32F4的
PWM+简单的
RC滤波来实现
DAC输出,从而节省成本。
在精度要求不是很高的时候,
PWM+RC滤波的
DAC输出方式,是一种非常廉价的解决方案。
PWM本质上其实就是是一种周期一定,而高低电平占空比可调的方波。实际电路的典型
PWM波形,如图
27.1.1所示:
图
27.1.1 实际电路典型
PWM波形
图
27.1.1的
PWM波形可以用分段函数表示为式①:
其中:
T是单片机中计数脉冲的基本周期,也就是
STM32F4定时器的计数频率的倒数。
N是
PWM波一个周期的计数脉冲个数,也就是
STM32F4的
ARR-1的值。
n是
PWM波一个周期中高电平的计数脉冲个数,也就是
STM32F4的
CCRx的值。
VH和
VL分别是
PWM波的高低电平电压值,
k为谐波次数,
t为时间。我们将①式展开成傅里叶级数,得到公式②:
从②式可以看出,式中第
1个方括弧为直流分量,第
2项为
1次谐波分量,第
3项为大于
1次的高次谐波分量。式②中的直流分量与
n成线性关系,并随着
n从
0到
N,直流分量从
VL到
VL+VH之间变化。这正是电压输出的
DAC所需要的。因此,如果能把式②中除直流分量外的谐波过滤掉,则可以得到从
PWM波到电压输出
DAC的转换,即:
PWM波可以通过一个低通滤波器进行解调。式②中的第
2项的幅度和相角与
n有关,频率为
1/(
NT),其实就是
PWM的输出频率。该频率是设计低通滤波器的依据。如果能把
1次谐波很好过滤
掉,则高次谐波就应该基本不存在了。
通过上面的了解,我们可以得到
PWM
DAC的分辨率,计算公式如下:
分辨率
=log2(
N)
这里假设
n的最小变化为
1,当
N=256的时候,分辨率就是
8位。而
STM32F4的定时器大部分都是
16位的(
TIM2和
TIM5是
32位),可以很容易得到更高的分辨率,分辨率越高,速度就越慢。不过我们在本章要设计的
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的衰减。
STM32F4的定时器最快的计数频率是
168Mhz,某些定时器只能到
84M,所以我们以
84M频率为例介绍,
8为分辨率的时候,
PWM频率为
84M/256=328.125Khz。如果是
1阶
RC滤波,则要求截止频率
2.07Khz,如果为
2阶
RC滤波,则要求截止频率为
26.14Khz。
探索者
STM32F4开发板的
PWM DAC输出采用二阶
RC滤波,该部分原理图如图
27.1.2所示:
图
27.1.2 PWM DAC二阶
RC滤波原理图
二阶
RC滤波截止频率计算公式为:
f=1/2π
RC
以上公式要求
R28*C37=R29*C38=RC。根据这个公式,我们计算出图
27.1.2的截止频率为:
33.8Khz超过了
26.14Khz,这个和我们前面提到的要求有点出入,原因是该电路我们还需要用作
PWM DAC音频输出,而音频信号带宽是
22.05Khz,为了让音频信号能够通过该低通滤波,同时为了标准化参数选取,所以确定了这样的参数。实测精度在
0.5LSB左右。
PWM DAC的原理部分,就为大家介绍到这里。
27.2 硬件设计
本章用到的硬件资源有:
1) 指示灯
DS0
2) KEY_UP和
KEY1按键
3) 串口
4) TFTLCD模块
5) ADC
6) PWM DAC
本章,我们使用
STM32F4的
TIM9_CH2(PA3)输出
PWM,经过二阶
RC滤波后,转换为直流输出,实现
PWM DAC。同上一章一样,我们通过
ADC1的通道
5(
PA5)读取
PWM DAC的输出,并在
LCD模块上显示相关数值,通过按键和
USMART控制
PWM DAC的输出值。我们需要用到
ADC采集
DAC的输出电压,所以需要在硬件上将
PWM DAC和
ADC短接起来,
PWM
DAC部分原理图如图
27.2.1所示:
图
27.2.1 PWM DAC原理图
从上图可知
PWM_DAC的连接关系,但是这里有个
特别需要注意的地方:因为
PWM_DAC和
USART2_RX共用了
PA3引脚,所以在做本例程的时候,必须拔了
P9上面
PA3(RX)的跳线帽(左侧跳线帽),否则会影响
PWM转换结果!!!
在硬件上,我们还需要用跳线帽短接多功能端口的
PDC和
ADC,如图
27.2.2所示:
图
27.2.2 硬件连接示意图
27.3 软件设计
打开本章的实验工程可以看到,我们本章并没有增加其他新的库函数文件支持。主要是使用了
adc和定时器相关的库函数支持。因为我们是使用定时器产生
PWM信号作为
PWM DAC的输入信号经过二阶
RC滤波从而产生一定幅度模拟信号,所以我们需要添加定时器相关的库函数支持。在
HARDWARE分组下,我们新建了
pwmdac.c源文件和对应的头文件用来初始化定时器
9的
PWM。接下来我们看看
pwmdac.c源文件内容:
void TIM9_CH2_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef
GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE); //TIM9时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,
ENABLE); //使能
PA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIOA3
GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed
= GPIO_Speed_100MHz; //速度
100MHz
GPIO_InitStructure.GPIO_OType
= GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd
= GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化
PA3
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_TIM9);
//PA3复用位定时器
9 AF3
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
//向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);//初始化定时器
9
//初始化
TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode
= TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState =
TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity
= TIM_OCPolarity_High; //输出极性高
TIM_OCInitStructure.TIM_Pulse=0;
TIM_OC2Init(TIM9,
&TIM_OCInitStructure); //初始化外设
TIM9 OC2
TIM_OC2PreloadConfig(TIM9,
TIM_OCPreload_Enable); //使能预装载寄存器
TIM_ARRPreloadConfig(TIM9,ENABLE);//ARPE使能
TIM_Cmd(TIM9,
ENABLE); //使能
TIM9
}
该函数用来初始化
TIM9_CH2的
PWM输出(
PA3),其原理同之前介绍的
PWM输出一模一样,只是换过一个定时器而已。这里就不细说了。
pwmdac.h头文件内容主要是函数申明,这里不做过多讲解。
接下来我们看看主函数内容:
int main(void)
{
u16
adcx, pwmval=0;
float
temp;
u8 t=0,key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组
2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为
115200
LED_Init(); //初始化
LED
LCD_Init(); //LCD初始化
Adc_Init();
//adc初始化
KEY_Init();
//按键初始化
TIM9_CH2_PWM_Init(255,0);//TIM4
PWM初始化
, Fpwm=168M/256=656.25Khz.
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Explorer
STM32F4");
LCD_ShowString(30,70,200,16,16,"PWM
DAC TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2014/5/6");
LCD_ShowString(30,130,200,16,16,"WK_UP:+ KEY1:-");
POINT_COLOR=BLUE;//设置字体为蓝 {MOD}
LCD_ShowString(30,150,200,16,16,"DAC
VAL:");
LCD_ShowString(30,170,200,16,16,"DAC
VOL:0.000V");
LCD_ShowString(30,190,200,16,16,"ADC
VOL:0.000V");
TIM_SetCompare2(TIM9,pwmval); //初始值
while(1)
{
t++;
key=KEY_Scan(0);
if(key==4)
{
if(pwmval<250)pwmval+=10;
TIM_SetCompare2(TIM9,pwmval); //输出
}else
if(key==2)
{
if(pwmval>10)pwmval-=10;
else
pwmval=0;
TIM_SetCompare2(TIM9,pwmval); //输出
}
if(t==10||key==2||key==4)
//WKUP/KEY1按下了
,或者定时时间到了
{
adcx=TIM_GetCapture2(TIM9);;
LCD_ShowxNum(94,150,adcx,3,16,0); //显示
DAC寄存器值
temp=(float)adcx*(3.3/256);; //得到
DAC电压值
adcx=temp;
LCD_ShowxNum(94,170,temp,1,16,0); //显示电压值整数部分
temp-=adcx; temp*=1000;
LCD_ShowxNum(110,170,temp,3,16,0x80);
//显示电压值的小数部分
adcx=Get_Adc_Average(ADC_Channel_5,20);
//得到
ADC转换值
temp=(float)adcx*(3.3/4096); //得到
ADC电压值
adcx=temp;
LCD_ShowxNum(94,190,temp,1,16,0); //显示电压值整数部分
temp-=adcx; temp*=1000;
LCD_ShowxNum(110,190,temp,3,16,0x80); //显示电压值的小数部分
t=0;
LED0=!LED0;
}
delay_ms(10);
}
}
此部分代码,同上一章的基本一样,先对需要用到的模块进行初始化,然后显示一些提示信息,本章我们通过
KEY_UP和
KEY1(也就是上下键)来实现对
PWM脉宽的控制,经过
RC滤波,最终实现对
DAC输出幅值的控制。按下
KEY_UP增加,按
KEY1减小。同时在
LCD上面显示
TIM4_CCR1寄存器的值、
PWM DAC设计输出电压以及
ADC采集到的实际输出电压。同时
DS0闪烁,提示程序运行状况。
27.4 下载验证
在代码编译成功之后,我们通过下载代码到
ALIENTEK探索者
STM32F4开发板上,可以看到
LCD显示如图
27.4.1所示:
图
27.4.1 PWM DAC实验测试图
同时伴随
DS0的不停闪烁,提示程序在运行。此时,我们通过按
KEY_UP按键,可以看到输出电压增大,按
KEY1则变小。
特别提醒:此时
PA3不能接其他任何外设,如果没有拔了
P9排针上面
PA3的跳线帽,那么
PWM DAC将有很大误差!
实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm
正点原子探索者STM32F407开发板购买地址:http://item.taobao.com/item.htm?id=41855882779
一周热门 更多>