STM32的PWM波形和DAC练习
一、STM32 采用定时器的方法输出 PWM 波形
1.PWM 简述
PWM 简介:
脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或 MOS 管栅极的偏置,来实现晶体管或 MOS 管导通时间的改变,从而实现开关稳压电源输出的改变。
这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。
脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
2.定时器实现 PWM 波形输出
PWM 工作过程
寄存器的值从 0 开始到 ARR 值的过程中:
当其比 CCRx 中的值小的时候,输出低电平(0);
当其值大于 CCRx 值时,输出高电平(1)。
从图中可以看出周期是由 ARR 决定的,跟定时器的时钟有关系,而占空比则跟 CCRx 有关。
PWM 通道
捕获/比较通道的输出部分(通道1):
①CCR1寄存器:捕获/比较值寄存器:设置比较值;
②CCMR1寄存器:OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1或者PWM模式2;
③CCER寄存器:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
④CCER寄存器:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
定时器3的输出通道引脚
TIM3_CH1:PA6,完全重映像PC6
TIM3_CH2:PA7,完全重映像PC7
TIM3_CH3:PB0,完全重映像PC8
TIM3_CH4:PB1,完全重映像PC9
相关配置
捕获/比较模式寄存器1(TIMx_CCMR1):
在PWM输出模式下,确定PWM的模式、使能相应的预装载寄存器等操作。
捕获/比较使能寄存器(TIMx_CCER):
在PWM输出模式下,确定PWM的输出极性和输出使能。
捕获/比较寄存器1(TIMx_CCR1):
在PWM输出模式下,确定比较的值。
3.keil5 实现输出 PWM 波形
定时器TIM1的初始化:
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1,引脚是PA8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
main.c 文件
int main(void)
{
u16 led0pwmval=0;
u8 dir=1;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare1(TIM1,led0pwmval);//设置不同的占空比
}
}
烧录后,可以看到 STM32 板子上的 LED 灯由亮变暗的过程。
利用 keil 仿真查看输出的波形如下:
二、STM32实现DAC功能输出音频波形
1.DAC简介
DAC 为数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与 ADC相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而 ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,由计 算机处理完成后,再由 DAC输出电压模拟信号,该电压模拟信号常常用来驱动某些执行器 件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。
STM32具有片上 DAC外设,它的分辨率可配置为 8位或 12位的数字输入信号,具有两个 DAC 输出通道,这两个通道互不影响,每个通道都可以使用 DMA 功能,都具有出错检测能力,可外部触发。
其功能框图如下:
2.输出周期为2kHz的正弦波
通过如下公式计算出,周期频率位为2kHz大约需要采集1800个点
通过matlab制作正弦波表
n = 2*pi/1800 : 2*pi/1800 : 2*pi %分成1800等份
a = sin(n)+1; %求取sin函数值并向上平移一个单位,消除负数值
a = a * 3.3/2; %调整幅值,使范围限制为0~3.3
r = a* (2.^12) /3.3 %求取dac数值,12位dac LSB = 3.3/2.^12
r = uint16(r); %把double型数据转化成16位整型数据
for i = 1:1800
if r(i) > 4095 %限制数据最大不超过4095
r(i) = 4095
end
end
dlmwrite('dac_sinWave.c',r); %把数据写入到文件,方便添加到stm32工程中
plot(n,r,'.') %把这些点画出来
烧录程序后,示波器显示效果如下
3.音频信号输出
通过 Adobe Audition 截取生成一段音频文件
设置参数,然后导出
通过WavToC工具,将wav音频文件转为c语言代码程序
同样将生成的数据替换工程中的波形数据
烧录程序,通过示波器显示如下