PWM DAC其实跟DAC是两码事,DAC是STM32的一个功能,可以直接输出(0~3.3V)。而PWM DAC是定时器TIM的PWM功能间接实现输出模拟量,实际端口输出的是(0或3.3V),只不过应用RC滤波将电压稳定在(0~3.3V之间)。在对输出精度不高的时候可以用该方式。
该实验是TIM PWM的拓展。当用作DAC时需要滤波,阿波罗采用二阶RC滤波,而RC(电阻电容)是跟PWM的频率有关系的。
之前的TIM PWM实验是实现呼吸灯效果,用的是90分频,因为TIM的时钟为90MHZ,分频后的周期为1us,PWM自动重装载值为500,向上计数,如果比较值是250,那么就是250us输出0,250us输出1。
那么这个实验是用256分频,也是根据90M/256=351.5KHZ来确定的RC。
那为什么要用256分频呢?其实用200、300、400都可以,只不过为了规范,我们设计此次DAC采用8位精度,也就是256。TIM最大支持16位的,但是分辨率越高,分频后的频率越低,周期越长。所以用8位还是比较好的。
如何理解PWM呢,就好像是一个灯泡,他的额定电压是自动重装载值,低于比较值他就灭,高于比较值他就亮,虽然电压从0到自动装载值匀速变化,灯泡也亮灭转换,但当速度快时,人眼就看不出来亮灭了,我们只能看到他是柔和的光不亮不暗。(比较值/自动重装载值) 就是你想让他亮的程度。
更何况应用TIM的PWM的DAC加上了RC滤波,电平变化就很稳定了。
prescaler分频系数:前面我们介绍到用256,八位的分辨率,减一是因为范围由(0~65535),八位的自然是255
counter mode :向上计数
period自动重装载值:若想重装载值为256,则这里应设置为256-1(下图写错了);
pulse比较值:他的作用是跟TIM_count相比较。
CH polarity极性:TIM_count < pulse时,CH PWM输出设置的极性(本例为HIGH),
TIM_count > pulse时,CH PWM输出与设置相反的极性(本例为LOW)
gpio mode:模拟量推挽输出
pull-up/pull-down:不用上拉下拉
speed:低速就够了
//第一步,初始化TIM9
MX_TIM9_Init();
//第二步,打开PWM
HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);
//控制占空比方法(库函数法)推荐,能用
//设置TIM9通道2的占空比
//compare:比较值
void User_SetTIM9Compare2(uint32_t compare)
{
TIM_OC_InitTypeDef sConfigOC;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = compare;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim9, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);
}
//控制占空比方法(寄存器法)不推荐,能用
void User_SetTIM9Compare2(uint32_t compare)
{
TIM9->CCR2=compare;
}
可以看出TIM的PWM的DAC并不准确,用阿波罗源程序也是这个现象。并且上下跳动±0.02V,追求准确的需求还是不要用这种方式比较好。
举例说明:TIM的OCPolarity为low;pulse为50;period为100时
若TIM_COUNT < 50时,则输出极性为low;
若TIM_COUNT > 50时,则输出极性为high;
所以若设置pulse 为100时,则TIM_COUNT总 < pulse ,总是输出为low;
反之设置pulse为0时,则TIM_COUNT总 > pulse ,总是输出为high;
period若想为100,则应写为100-1,分频系数也一样,应-1.
这里的坑还蛮多,希望大家注意,这很重要。