STM32的PWM和DAC练习
发布日期:2021-11-03 09:33:24
浏览次数:3
分类:技术文章
本文共 4153 字,大约阅读时间需要 13 分钟。
STM32的PWM和DAC练习
一、 用STM32F103输出一路PWM波形
1、STM32F1 PWM介绍
STM32F1除了基本定时器TIM6和TIM7,其他定时器都可以产生PWM输出 。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出 。而通用定时器也能同时产生多达 4路的 PWM 输出,这些在定时器中断 章节中已经介绍过。 PWM的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号 ,信号频率是由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。 2、PWM输出pwm.c 1 #include "pwm.h" 2 3 /******************************************************************************* 4 * 函 数 名 : TIM3_CH1_PWM_Init 5 * 函数功能 : TIM3通道1 PWM初始化函数 6 * 输 入 : per:重装载值 7 psc:分频系数 8 * 输 出 : 无 9 *******************************************************************************/10 void TIM3_CH1_PWM_Init(u16 per,u16 psc)11 { 12 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;13 TIM_OCInitTypeDef TIM_OCInitStructure;14 GPIO_InitTypeDef GPIO_InitStructure;15 16 /* 开启时钟 */17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);18 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);19 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO使能20 21 /* 配置GPIO的模式和IO口 */22 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;23 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;24 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出25 GPIO_Init(GPIOC,&GPIO_InitStructure);26 27 GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射28 29 TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值30 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数31 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;32 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式33 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);34 35 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;36 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;37 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;38 TIM_OC1Init(TIM3,&TIM_OCInitStructure); //输出比较通道1初始化39 40 TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器41 TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器42 43 TIM_Cmd(TIM3,ENABLE); //使能定时器44 45 }
main.c 1 #include "system.h" 2 #include "SysTick.h" 3 #include "led.h" 4 #include "pwm.h" 5 6 int main() 7 { 8 u16 i=0; 9 u8 fx=0;10 SysTick_Init(72);11 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组12 LED_Init();13 TIM3_CH1_PWM_Init(500,72-1); //频率是2Kh14 15 while(1)16 { 17 18 if(fx==0)19 { 20 i++;21 if(i==300)22 { 23 fx=1;24 }25 }26 else27 { 28 i--;29 if(i==0)30 { 31 fx=0;32 }33 }34 TIM_SetCompare1(TIM3,i); //i值最大可以取499,因为ARR最大值是499.35 delay_ms(10); 36 }37 }
3、结果
二、用STM32F103的DAC功能输出一个周期2khz的正弦波
1、DAC简介
DAC为数字模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与ADC相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由DAC输岀电压模拟信号,该电压模拟信号常常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。 STM32具有片上DAC外设,它的分辨率可配置为8位或12位的数字输入信号,具有两个DAC输出通道,这两个通道互不影响,每个通道都可以使用DMA功能,都具有出错检测能力,可外部触发。 2、输出一个周期2khz的正弦波 通过计算可以得到,一共需要3600个采样点。计算机只能够识别一个一个的点,所以需要先对正弦波进行采样,取出一定的点放到数组中,再去执行输出代码。这里采用Matlab进行采样点的获取。首先我们找到野火配套资料里的 38-DAC—输出正弦波 工程文件,将其打开,找到如下文件,用matlab打开
修改后代码如下
%用于产生正弦数据表,输出到文件dac_sinWave.c 文件中,复制到c语言数组即可n = 2*pi/3600 : 2*pi/3600 : 2*pi %分成3600等份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:32 if r(i) > 4095 %限制数据最大不超过4095 r(i) = 4095endend dlmwrite('dac_sinWave.c',r); %把数据写入到文件,方便添加到stm32工程中plot(n,r,'.') %把这些点画出来
修改之后我们运行该脚本,便会生成3600个取样点,这些点会自动保存到之前的c文件中,复制这些取样点。
打开 DAC-输出正弦波 的工程keil文件,将复制的全部粘贴到 uint16_t Sine12bit 数组中,然后对main函数进行编译生成hex文件。
结果三、将一段数字音频歌曲数据转换为模拟音频波形输出
1、首先打开 Adobe Audition CS6软件,在里面选择一首歌曲打开,得到如下界面
2、截取一小段,生成一个wav文件并保存 3、用UltraEdit软件打开这个wav文件 CTRL+A 鼠标右键,选择,十六进制复制,选定视图,新建文件,粘贴 CTRL+A 鼠标右键,选择范围,输入起始的行号和列号,确定就选中了整个需要的内容 4、打开 notepad++ 软件,将以上复制的内容粘贴进去,然后 alt+c ,在其中插入 ,0x 生成十六进制文件,然后将文本复制进uint16_t Sine12bit[]数组中去,并删掉中括号里面的数据。 将生成的hex文件烧录到板子中去,打开示波器便可观察到我们截取音乐片段的模拟音频波形转载地址:https://blog.csdn.net/weixin_51118019/article/details/112134135 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月25日 14时47分22秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
nginx 反向代理,动静态请求分离,proxy_cache缓存及缓存清除
2019-04-27
nginx 的proxy_cache才是王道
2019-04-27
Nginx proxy_cache 使用示例
2019-04-27
Nginx源代码分析 - 日志处理
2019-04-27
使Apache实现gzip压缩
2019-04-27
Memcached在大型网站中应用
2019-04-27
Hadoop简要介绍
2019-04-27
squid中的X-Cache和X-Cache-Lookup的意义
2019-04-27
squid 优化指南
2019-04-27
编程方式刷新Squid缓存服务器的五种方法
2019-04-27
centos vnc配置笔记
2019-04-27
Linux服务器网络开发模型
2019-04-27
nginx虚拟目录设置 alias 和 root
2019-04-27
理解http响应头中的Date和Age
2019-04-27
四层和七层负载均衡的区别
2019-04-27
设置Squid Cache_mem大小
2019-04-27
squid日志文件太大,怎样处理?
2019-04-27
让Squid 显示本地时间
2019-04-27
linux mysql 命令 大全
2019-04-27
清除Squid缓存的小工具
2019-04-27