嵌入式学习⑩——STM的PWM和DAC
STM的PWM和DAC
目录
- STM的PWM和DAC
- 一、STM32F103输出PWM
- 1.STM32F1 PWM介绍
- 2.源码示例
- 3.进行配置
- 二、STM32实现DAC输出
- 1.DAC的基本介绍
- 2.制作一段正弦波并用示波器观看
- ① 使用Adobe Audition CS6制作正弦波
- ② 使用Ultraedit与nodepad++处理音频
- 3.将一段数字音频歌曲数据转换为模拟音频波形输出
- ① 使用Au处理音频
- ② 处理音频
一、STM32F103输出PWM
本部分参考自博客:(stm32f103学习总结)—stm32 PMW输出实验
PWM 是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调制,简称脉宽调制。它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其控制简单、灵活和动态响应好等优点而成为电力电子技术最广泛应用的控制方式。
其实我们也可以这样理解,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
1.STM32F1 PWM介绍
STM32F1除了基本定时器TIM6和TIM7,其他定时器都可以产生PWM输出 。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出 。而通用定时器也能同时产生多达 4路的 PWM 输出,这些在定时器中断 章节中已经介绍过。 PWM的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号 ,信号频率是由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。
PWM输出比较模式总共有8种,具体由寄存器 CCMRx 的位 OCxM[2:0] 配置。我们这里只讲解最常用的两种PWM输出模式:PWM1和PWM2,其他几 种模式可以参考《STM32F10x中文参考手册》13、14、15定时器章节。
PWM1和PWM2这两种模式用法差不多,区别之处就是输出电平的极性不 同。
2.源码示例
main.c
#include "stm32f10x.h"
#include "./dac/bsp_dac.h"int main(void){/*初始化DAC,开始DAC转换*/DAC_Mode_Init();while(1); }
bsp_dac.c
#include "./dac/bsp_dac.h"//正弦波单个周期的点数
#define POINT_NUM 32/* 波形数据 ---------------------------------------------------------*/
const uint16_t Sine12bit[POINT_NUM] = {2048 , 2460 , 2856 , 3218 , 3532 , 3786 , 3969 , 4072 ,4093 , 4031 , 3887 , 3668 , 3382 , 3042 , 2661 , 2255 , 1841 , 1435 , 1054 , 714 , 428 , 209 , 65 , 3 ,24 , 127 , 310 , 564 , 878 , 1240 , 1636 , 2048
};uint32_t DualSine12bit[POINT_NUM];static void DAC_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef DAC_InitStructure;/*使能GPIOA时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /*使能DAC时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);/* DA的GPIOÅ配置,模拟输入*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);/*配置DAC通道1*/DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; //使用TIM2作为触发源DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //不使用波形发生器DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //DAC输出缓冲DAC_Init(DAC_Channel_1, &DAC_InitStructure);/*配置DAC通道2*/DAC_Init(DAC_Channel_2, &DAC_InitStructure);/*使能通道1由PA4输出*/DAC_Cmd(DAC_Channel_1, ENABLE);/*使能通道2由PA5输出*/DAC_Cmd(DAC_Channel_2, ENABLE);/*使能DAC的DMA请求*/DAC_DMACmd(DAC_Channel_2, ENABLE);
}static void DAC_TIM_Config(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/*使能TIMz时钟,TIM2CLK为72M*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);/*TIM2基本定时器配置*/// TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = (20-1); //定时周期20 TIM_TimeBaseStructure.TIM_Prescaler = 0x0; //预分频,不分频 72M / (0+1) = 72MTIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频系数TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/*配置TIM2触发源*/TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);/*使能TIM2*/TIM_Cmd(TIM2, ENABLE);}static void DAC_DMA_Config(void)
{ DMA_InitTypeDef DMA_InitStructure;/*使能DMA2时钟*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);/*配置DMA2*/DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_ADDRESS; //外设数据地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit ; //内存数据地址 DualSine12bitDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向内存至外设DMA_InitStructure.DMA_BufferSize = POINT_NUM; //缓存大小为POINT_NUM字节 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设数据地址固定DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存数据地址自增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据以字为单位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //内存数据以字为单位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高DMA通道优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存至内存模式DMA_Init(DMA2_Channel4, &DMA_InitStructure);/*使能DMA2-14通道*/DMA_Cmd(DMA2_Channel4, ENABLE);
}void DAC_Mode_Init(void)
{uint32_t Idx = 0; DAC_Config();DAC_TIM_Config(); /*填充正弦波形数据,双通道右对齐
*/for (Idx = 0; Idx < POINT_NUM; Idx++){DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);}DAC_DMA_Config();
}
3.进行配置
点击魔术棒
进行模拟配置 Use Simulator
进行调试
进入调试页面
点击进行波形配置
点击Setup
可以进行颜色等的设置 ↑
点击进行运行 ↓
可以看到出现波形
通过鼠标滚轮可以对疏密显示进行调节
实现PWM波形
二、STM32实现DAC输出
1.DAC的基本介绍
本部分参考自博客: 【STM32】DAC基本原理、寄存器、库函数(DAC一般步骤)
DAC的基本定义
Digital-to-Analog Converter的缩写。指数/模转换器或者数字/模拟转换器。是指将离散的数字信号转换为连续变量的模拟信号的器件。
典型的数字模拟转换器将表示一定比例电压值的数字信号转换为模拟信号。
STM32的DAC模块是12位数字输入,电压输出型的DAC。DAC的主要特征
2个DAC转换器:每个转换器对应1个输出通道;
8位或者12位单调输出;
12位模式下数据左对齐或者右对齐;
同步更新功能;
噪声波形生成;
三角波形生成;
双DAC通道同时或者分别转换;
每个通道都有DMA功能;
外部触发转换;
输入参考电压VREF+。DAC的工作框图
DAC转换
不能直接对寄存器DAC_DORx写入数据,任何输出到DAC通道x的数据都必须写入DAC_DHRx寄存器(数据实际写入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD、或者DAC_DHR12RD寄存器)。如果没有选中硬件触发(寄存器DAC_CR1的TENx位置0),存入寄存器DAC_DHRx的数据会在一个APB1时钟周期后自动传至寄存器DAC_DORx;
如果选中硬件触发(寄存器DAC_CR1的TENx位置1),数据传输在触发发生以后3个APB1时钟周期后完成。
一旦数据从DAC_DHRx寄存器装入DAC_DORx寄存器,在经过时间tSETTLING之后,输出即有效,这段时间的长短依电源电压和模拟输出负载的不同会有所变化。
2.制作一段正弦波并用示波器观看
① 使用Adobe Audition CS6制作正弦波
首先打开Adobe Audition CS6
新建音频文件
设置参数
点击效果→生成基本音色
生成正弦波
生成正弦波如图
保存为wav文件
可以看到生成了wav文件
② 使用Ultraedit与nodepad++处理音频
打开Ultraedit
点击导入wav文件
Ctrl+A全选,选择16进制复制所选视图
粘贴到另一个新建文件中
右击设置选择范围
设置一个合适的范围
将文件用nodepad++打开
设置列块编辑
将每一列都插入0x
以txt格式保存在记事本中
然后把得到的代码复制到野火的官方模板DAC输出中。删掉const uint8_t Sine12bit[]
函数括号里的参数
3.将一段数字音频歌曲数据转换为模拟音频波形输出
① 使用Au处理音频
打开Au
用Au打开音频
用鼠标拖动红线,右键点击选中区域,选择存储区域为
保存文件,设置采样频率为8000,单声道,16位
② 处理音频
此步骤与上一部分一致
嵌入式学习⑩——STM的PWM和DAC相关推荐
- STM的PWM与DAC学习
文章目录 任务要求 PWM应用 例程编写 DAC应用 例程编写 总结 任务要求 本人所用STM32为野火家F103指南者 烧录用具ST-LINK 代码编写为KILE5 音频软件为AU 用STM32F1 ...
- 嵌入式学习——使用定时器输出PWM波形,实现 LED呼吸灯的效果
嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 目录 嵌入式学习--使用定时器输出PWM波形,实现 LED呼吸灯的效果 1. 任务要求 2 PWM波介绍, 2.1 什么是PWM(Pu ...
- STM32 嵌入式学习入门(4)——PWM原理
STM32 嵌入式学习入门(4)--PWM原理 本文先对STM32F103的通用定时器作一简单介绍,然后详细介绍通用定时器的一个应用--输出PWM波形的原理.整个文章以介绍"怎么用" ...
- 嵌入式实验(四):用STM32输出PWM波形/DAC功能完成波形输出
0 实验目标 用STM32F103输出一路PWM波形,建议采用定时器方法.野火和网上大多数资源采用此方法,有完整源码.用示波器观察输出波形. 用STM32F103的DAC功能完成以下波形输出,用示波器 ...
- 嵌入式学习笔记——基于Cortex-M的单片机介绍
基于Cortex-M的单片机介绍 前言 1生产厂商及其产品线 1.1ARM单片机的产品线 1.2命名规则 作业1 2习单片机的资料准备 2.1STM32开发所需手册 2.1.1芯片的数据手册 芯片基本 ...
- 嵌入式学习笔记——ADC模数转换器
ADC模数转换器 前言 ADC介绍 ADC概述 ADC的数量 ADC的特性 ADC框图 芯片外部框图 芯片内部框图 转换部分框图 状态输出部分 条件触发框图 寄存器介绍 编程思路 模式选择 规则通道的 ...
- linux嵌入式系统开发心得,嵌入式学习牛人心得
都说嵌入式学习难,难于上青天,其实不然,无论学习什么,只要找对了一个好的学习方法,往往会事半功倍.下面我摘自于一个嵌入式前辈,说说他的学习经验.本文引用地址:http://www.eepw.com.c ...
- 嵌入式学习笔记——STM32的USART通信概述
文章目录 前言 常用通信协议分类及其特征介绍 通信协议 通信协议分类 1.同步异步通信 2.全双工/半双工/单工 3.现场总线/板级总线 4. 串行/并行通信 5. 有线通信.无线通信 STM32通信 ...
- 补充嵌入式后期的开发~~分享一下自己的嵌入式学习经验~~也纪念一下即将逝去的青春
自己的嵌入式学习经验~~也纪念一下即将逝去的青春 大一听说嵌入式很有挑战性,菜鸟也想挑战一下下,就开始了我的学习之旅,但是后来发现上了操作系统的arm完全没有自己想象的那么简单,简单的led程序都不会 ...
最新文章
- 成功将BlogEngine 1.5 升级到了BlogEngine 2.0
- (C++)1029 旧键盘
- 【SQL Server学习笔记】变更数据捕获(Change Data Capture)
- 10 个常用的软件架构模式
- SQL生成日期维度(到小时)
- el表达式 多条件判断
- 【数字信号调制】基于matlab GUI QPSK调制+解调【含Matlab源码 646期】
- Android View之布局加载流程
- 手机端网页切图之间出现空白的问题
- redis 命令大全
- ST-Link v2 下载 出现target dll has been cancelled 的错误的解决方法
- R语言关联分析之啤酒和尿布
- mysql rownum写法_mysql应用之类似oracle rownum写法
- 2021年惠来一中高考成绩查询入口,2021年广东高考体检报告结果查询时间及查询网址入口...
- java——OOA,OOD,OOP
- SCI论文写作的学习与总结
- 【资源分享】一周整理的,这是价值10W的32个Python项目!
- Linux虚机 下给用户调整安装JDK版本
- 基于Java开发一套完整的区块链系统(附源码)
- 导数几何意义应用思维导图【试编辑】