0 实验目标
- 用STM32F103输出一路PWM波形,建议采用定时器方法。野火和网上大多数资源采用此方法,有完整源码。用示波器观察输出波形。
- 用STM32F103的DAC功能完成以下波形输出,用示波器观察波形,并用蜂鸣器或手机耳机收听输出声音效果、感受歌曲的音质差异。
(1)输出一个周期2khz的正弦波(循环)。此波形驱动作用至蜂鸣器或喇叭,会呈现一个“滴…”的单音;
(2)将一段数字音频歌曲数据转换为模拟音频波形输出(循环)。
1 PWM的生成
- PWM简介
PWM:Pulse Width Modulation,即脉冲宽度调制,简称脉宽调制。
它是利用微处理器的数字输出来对模拟电路进行控 制的一种非常有效的技术,其控制简单、灵活和动态响应好等优点而成为电力电子技术最广泛应用的控制方式。 PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个 具体模拟信号的电平进行编码。
STM32F1除了基本定时器TIM6和TIM7,其他定时器都可以产生PWM输出 。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出 。而通用定时器也能同时产生多达 4路的 PWM 输出。这里我使用的是网上原子的例程,使用的是TIM3(通用计时器),而由于没有示波器的原因,使用的keil的仿真,没有使用硬件,所以过程比较简单,也不会遇到硬件输出时的一些干扰。
(1)keil代码
int main(void)
{
u16 led0pwmval=0;
u8 dir=1;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组优先级
uart_init(115200); //串口初始化115200
LED_Init(); //LED端口初始化
TIM3_PWM_Init(200,0); //不分频,pwm频率=72000000/900=80Khz
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare2(TIM3,led0pwmval);
}
}
(2)仿真
- 设置需要观察的端口,这里选PB5
- 运行
- 点击运行右边的停止
(3)代码分析
从实验流程可以看出,由例程代码,我们无需什么操作,就能简单的得出仿真波形,在对实验代码进行分析后,发现这个实验最关键的步骤在于TIM3_PWM_Init(,);这个函数定义了PWM的输出端口,以及占空比等PWM配置。
在这个函数所在的timer.c中,
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
这个函数将将TIM3_CH2输出到了PB5,让我们能在PB5的端口观察到PWM输出。
(例程是观察硬件上PB5所连接的led的亮度)
void TIM3_PWM_Init(u16 arr,u16 psc)
- PSC是预分频系数,设置为0时候,默认不分频,也就是如果内部时钟是72Mhz,那么输出的TIM就是72Mhz(103ZET6是72M)。
- ARR是重装载值,也就是最大计数值。
最大计数值ARR为0的时候就是默认的每秒发射72M次的脉冲,也就是每次脉冲记一次数,计数完成清零。当这个值为1的时候,每发射两次连续计两个数,计数完成清零。当ARR为2的时候,每发射3次连续计两个数,每次计数到最大值之后把这个计数清零。 - CRR设置占空比,按照计数值里面的数值,比如最大计数值也就是最大重装载值ARR为99,CRR为50时候,占空比为50/(ARR+1)=50/100=1/2。
在例程函数里,没有设置crr所以也无法改变占空比。
2 DAC波形输出
- DAC
(参考stm32官方手册的 DAC模块)
Digital-to-Analog-Converter 指数/模转换器或者数字/模拟转换器。是指将离散的数字信号转换为连续变量的模拟信号的器件。
典型的数字模拟转换器将表示一定比例电压值的数字信号转换为模拟信号。
数据格式
DAC 可以使用以下三种整型格式的数据:8 位右对齐、12 位右对齐以及 12 位左对齐。12 位值的范围在 0x000 到 0xFFF 之间,其中 0x000 为最小值,而 0xFFF 为最大值。
WAV 文件格式
.WAV 文件格式是存储多媒体文件使用的资源交换文件格式 (RIFF) 规范中的一种。RIFF 文
件以一个文件头开始,然后是一系列的数据块。.WAV 文件通常就是一个 RIFF 文件,内含
一个“WAVE”数据块,该数据块由以下两个子数据块组成:
- 指定数据格式的 fmt 子数据块
- 包含实际采样数据的 data 子数据块
WAVE 文件格式的开始是 RIFF 头:它指示文件长度。
然后,fmt 块描述采样格式,其中包含如下信息:波形音频的格式:(PCM/…),通道数(单声道/
立体声),采样率(每秒的采样数:例如,22050)以及采样数据大小(例如,8 位 /16 位)。
最后,数据块包含采样数据。
DAC实现音频播放流程:
(1)生成需要的wav文件
- Audition是一款功能强大的音频编辑工具 ,可以轻松的生成我们实验需要wav文件。
- 根据实验要求,我们需要生成一个采样8khz,量化16bit,单通道,时长为7.5秒的标准正弦音频,用上述方法来输出模拟的波形,看是否能还原为之前的正弦波。用于验证代码是否正确。
- 新建一个wav文件
- 设置采样频率8000,声道为单声道,位深度为16
- 生成基本音
- 修改频率与时长
- 完成
(2)使用Ultraedit与nodepad++将音频文件转化为源码
UltraEdit-32是一bai套极棒的文字、Hex、ASCII码编辑器,可以取代du记事本,zhi内建英文单字检查dao、C++及VB指令突显,可同时编辑多个文件,而且zhuan即使开启很大的文件速度也不会慢。其并且附有HTMLTag颜色显示、搜寻替换以及无限制的还原功能;一般大家常会用其来修改EXE或DLL文件。需使用WinZip解压。
在这次实验,我们只是利用它打开wav文件的源代码。
- 打开ultraedit
- 打开.wav文件(也可直接拖动)
- 右键-》选择范围 - 粘贴到另一个文本文档,保存
- 用nodepad++打开
- 将每一列都插入0x
(3)将这串字符复制到程序中,运行查看结果
3 将一段数字音频歌曲数据转换为模拟音频波形输出
(1) 使用Au处理音频
- 打开一首下载好的音乐
- 选择音频范围(10s)
通过设置修改参数,然后保存
(2)使用Ultraedit与nodepad++将音频文件转化为源码
此部分与2中相同,只要2中正弦波能恢复,这个也没有问题
4 小结
这次实验缺少示波器验证,所以看起来不是很完整,但是我也从中学到了PWM及DAC的相关知识,以及实现音频转换的流程