搜索
bottom↓
回复: 116

【求助】PWM转DA输出WAV音频的一个小程序

  [复制链接]

出0入17汤圆

发表于 2012-4-27 20:24:49 | 显示全部楼层 |阅读模式
本帖最后由 wicy001 于 2012-4-28 13:45 编辑

利用STC90C516RD+实现PWM输出WAV格式的音频,这是一个非常简单的程序

说明:1.此单片机没有集成PWM,需要使用定时器实现
         2.播放wav音频的格式为8bit,8Khz 单声道,大小<60K,放在程序存储器中。
         3.晶振需要 8Khz*(2^8bit)*12T=24.576Mhz,如果烧写使用6T方式,晶振可减半。
         4.端口接耳机,耳机另一端接+5V,这样声音听着会大一些。

问题:
       输出有噪音,噪音非常尖锐,而且声音很大,比声音信号要大。请各位大侠看看,问题出在哪,应该怎么解决?

-----------
声音尖锐,频率应该很高,试着加一个RC低通,但效果不明显。

---------------为方便大家快速阅读,将帖子相关内容整理如下-------------
图1:RC电路


图2:经过RC电路仿真波形      【如何去掉图中的尖刺?】


图3:未经RC电路前端口的仿真波形  【斜坡受RC影响,正常。如果不加RC电路,输出是平的】



/*************************程序****************************/
#include <reg52.h>   //MCU为STC89/STC90
#include "sound.h"    //wav格式数据

sbit BEEP = P0^0;         //耳机一端接在P0.0脚上,一端接+5V
unsigned int counter,wavedataL;
unsigned char currentdata,nextdata,i;




void sys_start()
{

    TMOD|= 0x02;  //T0,自动重装模式
        TH0 = currentdata;
        TL0 = currentdata;


    ET0 = 1;
        EA  = 1;       

        TR0 = 1;
        BEEP=0;
}



main()
{
  unsigned int tmp;

  tmp=sound[0x29];                           //从wav文件中取,数据长度。数据长度应该是4个字节,
  tmp=tmp<<8;
  wavedataL=tmp+sound[0x28];  //由于wav存在片内flash中,文件大小有限制,数据长度用int型足够表示了。

  counter=0x2c;          //wav文件第一个数据
  
  currentdata=sound[counter];       
  nextdata=sound[counter];

  //以上数字请参考wav格式说明

  sys_start();


  while(1)
  {
   
        if(counter>wavedataL)                //反复重播
                 {
                         counter=0x2c;      
                 }

        if(BEEP) TH0=0xFF-currentdata;
        else TH0=currentdata;

   }


}

/*************************************/

void Timer0int(void) interrupt 1    //定时器0中断
{
   
       
        BEEP=~BEEP;

        if(BEEP)
        {

                counter++;
                nextdata=sound[counter];

        }
        else
        currentdata=nextdata;
}


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入17汤圆

 楼主| 发表于 2012-4-27 20:26:23 | 显示全部楼层
自己沙发

出0入0汤圆

发表于 2012-4-27 21:39:20 | 显示全部楼层
PWM频率要足够高,最好40K左右,
STC90C516RD 无硬件PWM,又速度慢(6T)定时器模拟PWM频率不高也不方便,
可以使用电阻网络搭建DA转换器电路,这样大大提高CPU效率,
详见:小玩意,单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-4-27 21:46:09 | 显示全部楼层
声音尖锐,频率应该很高,试着加一个RC低通,但效果不明显。

出0入17汤圆

 楼主| 发表于 2012-4-27 22:26:24 | 显示全部楼层
TO BXAK

PWM频率要足够高,最好40K左右----------------
当然高一些好,我用的是24.576MHz的晶振,可以满足播放我程序中的声音文件。
(这个声音文件的模拟输出点没有接近0v,和5V的极限值,都在2.5V左右,程序处理起来完全满足。)


可以使用电阻网络搭建DA转换器电路,这样大大提高CPU效率,
---------------------------------
嗯,以前做过使用DA芯片。但是这里就是想用一下PWM方式的。


声音可以清晰的听出来,就是背景噪音太大,这个噪音一直持续,分贝很高。

出0入17汤圆

 楼主| 发表于 2012-4-27 22:28:33 | 显示全部楼层
那段声音是转CS里的一个wav文件, “OK,let‘s go”

出0入0汤圆

发表于 2012-4-27 22:36:50 | 显示全部楼层
楼主 这个可不可以通过单片机读取PWM,然后在LCD显示出音频的频谱呢?

可否给个简单的思路呢?

出0入0汤圆

发表于 2012-4-27 23:03:45 | 显示全部楼层
这个PWM值是已知的.....WAV数据就是PWM(DA)值,并不是通常意义上的频谱

出0入0汤圆

发表于 2012-4-28 08:52:10 | 显示全部楼层
有尖波干扰吧

出0入17汤圆

 楼主| 发表于 2012-4-28 09:28:06 | 显示全部楼层
512826028 发表于 2012-4-27 22:36
楼主 这个可不可以通过单片机读取PWM,然后在LCD显示出音频的频谱呢?

可否给个简单的思路呢? ...

楼主 这个可不可以通过单片机读取PWM,然后在LCD显示出音频的频谱呢?

可否给个简单的思路呢?

--------------------------------------------------



这个不是读PWM,而直接读wav文件,对wav数据进行数学变化,可以分析频谱。这个算法用单片机实现不了,DSP或许可以。

出0入0汤圆

发表于 2012-4-28 09:29:59 | 显示全部楼层
滤波电路是不是不到位?
发电路来看看!

出0入17汤圆

 楼主| 发表于 2012-4-28 10:10:16 | 显示全部楼层
RC电路附上

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2012-4-28 13:19:39 | 显示全部楼层
wicy001 发表于 2012-4-28 10:10
RC电路附上

端口输出的PWM经过RC前后的仿真波形。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2012-4-28 13:25:10 | 显示全部楼层
如何去掉图一中的尖刺?

出0入0汤圆

发表于 2012-4-28 17:15:00 | 显示全部楼层
wicy001 发表于 2012-4-28 13:25
如何去掉图一中的尖刺?

请问你是否有 Proteus 范例?另外你的Proteus是第几版本?

出0入17汤圆

 楼主| 发表于 2012-4-28 20:07:31 | 显示全部楼层
mobile01 发表于 2012-4-28 17:15
请问你是否有 Proteus 范例?另外你的Proteus是第几版本?

有范例,proteus V7.5

出0入0汤圆

发表于 2012-4-28 21:48:20 | 显示全部楼层
wicy001 发表于 2012-4-28 20:07
有范例,proteus V7.5

你说的是proteus内部范例吗?但是找不到?

出0入17汤圆

 楼主| 发表于 2012-4-28 22:15:51 | 显示全部楼层
我以为你说是poteus自己内部的sample。

附件是范例。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-4-29 00:04:02 | 显示全部楼层
原来我用51做过类似的实验,也是噪声大,我用收音机的音频变压器做低通效果好一些.

出0入17汤圆

 楼主| 发表于 2012-4-29 15:14:53 | 显示全部楼层
if_else 发表于 2012-4-29 00:04
原来我用51做过类似的实验,也是噪声大,我用收音机的音频变压器做低通效果好一些. ...

用音频变压器能到什么程度? 我感觉音频变压器主要用来变换音频信号电压的,滤波效果不应该很强。

我现在用RC电路,一方面起到滤波作用,另一方面由于加入电阻,使信号变弱了,整体的效果是声音和背景噪声信号强度都削弱了,使背景噪声变得不那么刺耳而已,但是滤波效果不明显,背景噪声依然存在。

出0入17汤圆

 楼主| 发表于 2012-4-29 16:00:59 | 显示全部楼层
今天尝试从电路和软件上看看能否消除毛刺
1.软件调试时,在中断判读BEEP,始终不能进入counter++语句,counter不变化。查stc数据手册,问题可能是由于刚给BEEP(P0.0)端口赋值,而端口还没有变化,就读端口,造成误差。这样另加了一个bit变量,与BEEP同步,调试通过。

2.硬件上,不再采用直接加5V的接法,变为上拉电阻方式,使其有公共接地端,以尽量减少噪音。

做完改动后,还是有背景噪声,比以前有一点点的提高。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-4-30 12:38:07 | 显示全部楼层
干脆用da的了
用pwm很费cpu时间

出0入17汤圆

 楼主| 发表于 2012-5-1 09:36:10 | 显示全部楼层
xwkm 发表于 2012-4-30 12:38
干脆用da的了
用pwm很费cpu时间

纯定时器做的PWM确实费时间,带PCA,PWM的还是可以用一用的。

出0入0汤圆

发表于 2012-5-1 13:36:37 | 显示全部楼层
不懂,但是感兴趣,关注!

出0入0汤圆

发表于 2012-5-1 16:25:26 | 显示全部楼层
刚做了个实验,用c8051f340做pwm模拟da输出wav,刚开始pwm在6k的时候高频噪声很大,试着提高单片机时钟到12M,增加延时,这时候的声音效果特别好,不是几乎听不到噪声,是一点噪声也没有,但是pwm频率就不能测出了,我示波器是5MHz的,五一结束去测下频率

结论是什么呢,pwm模拟音频da,完全可行!

出0入17汤圆

 楼主| 发表于 2012-5-1 18:04:30 | 显示全部楼层
weixinal 发表于 2012-5-1 16:25
刚做了个实验,用c8051f340做pwm模拟da输出wav,刚开始pwm在6k的时候高频噪声很大,试着提高单片机时钟到12 ...

期待。
直接用C8051F做一出来,分享一下,看看效果如何。

出0入0汤圆

发表于 2012-5-1 20:40:02 | 显示全部楼层
正在处理,稍后上传吧

出0入0汤圆

发表于 2012-5-1 20:45:39 | 显示全部楼层
http://www.tudou.com/programs/view/7ZCNyB-Hbw4/

出0入0汤圆

发表于 2012-5-1 20:47:02 | 显示全部楼层
本帖最后由 weixinal 于 2012-5-1 20:48 编辑

应该是这样贴视频吧,试下
http://www.tudou.com/v/7ZCNyB-Hbw4/&rpid=12538900&resourceId=12538900_04_05_99/v.swf

出0入17汤圆

 楼主| 发表于 2012-5-2 07:50:58 | 显示全部楼层
weixinal 发表于 2012-5-1 20:47
应该是这样贴视频吧,试下

声音效果很好,谢谢分享。

请问,MCU端口是直接与小音箱相连的吗?还是中间加了什么? 视频中看不太清楚。

出0入0汤圆

发表于 2012-5-2 08:14:20 | 显示全部楼层
PWM频率8KHz,太低了,至少得大于20K,你把定时器设为1T模式试试

出0入0汤圆

发表于 2012-5-2 09:18:00 | 显示全部楼层
楼主的问题解决了没

出0入17汤圆

 楼主| 发表于 2012-5-2 09:23:44 | 显示全部楼层
chess01 发表于 2012-5-2 08:14
PWM频率8KHz,太低了,至少得大于20K,你把定时器设为1T模式试试

嗯。STC90/89不支持1T,最大支持6T,我可以试一下。

播放8KHz的wav,按理说接着8Khz输出是可以的。

出0入17汤圆

 楼主| 发表于 2012-5-2 09:28:26 | 显示全部楼层
yanglong5918 发表于 2012-5-2 09:18
楼主的问题解决了没

根据楼上几位所讲的,应该是PWM输出频率的问题。

PWM的频率越高,尖刺就会越窄,频率达到一定程度,尖刺可以近似消除,这样就听不出背景噪音了。

出0入0汤圆

发表于 2012-5-2 15:35:27 | 显示全部楼层
直接接小音箱的输入端,音响内部有功放的,我自己是用耳机试验的,为了让大家听清楚才接音响的,今天实测频率47k,wicy001说的没错,频率达到一定数值,尖刺可以消除

出0入17汤圆

 楼主| 发表于 2012-5-2 15:51:44 | 显示全部楼层
weixinal 发表于 2012-5-2 15:35
直接接小音箱的输入端,音响内部有功放的,我自己是用耳机试验的,为了让大家听清楚才接音响的,今天实测频 ...

你太给力了,全靠你的测试了。

出0入0汤圆

发表于 2012-5-2 16:03:31 | 显示全部楼层
wicy001 发表于 2012-5-2 15:51
你太给力了,全靠你的测试了。

最近在做这方面的东西,学校实验室也有示波器,比较方便

出0入17汤圆

 楼主| 发表于 2012-5-2 21:16:42 | 显示全部楼层
我用STC90C516RD+,24.576晶振,6T模式,可以在一个采样时间内输出2次,即PWM频率为16KHz,可以消去尖锐的背景噪音,同时加上RC低通滤波,音效还是可以的。

出0入0汤圆

发表于 2012-5-3 11:13:59 | 显示全部楼层
我用STC12C5A60S2实验成功,11.0592晶振,定时器0频率18K,PWM输出频率21K,音质很好…
PS:为什么接上TDA2003,2003会非常烫,昨天搞挂2片了

出0入17汤圆

 楼主| 发表于 2012-5-3 11:51:04 | 显示全部楼层
yanglong5918 发表于 2012-5-3 11:13
我用STC12C5A60S2实验成功,11.0592晶振,定时器0频率18K,PWM输出频率21K,音质很好…
PS:为什么接上TDA2 ...

贴个电路图上来,分析一下。

出0入0汤圆

发表于 2012-5-3 12:05:04 | 显示全部楼层
pwm出来经过低通滤波再进功放吧,也可能功放电路有问题,试着接入正常音频信号源试下

出0入0汤圆

发表于 2012-11-8 15:51:38 | 显示全部楼层
兄弟啊,能不能把你做的那个STC单片机播放WAV的资料程序发给我啊,小弟现在在做这些方面的东西.急需这方面的资料.    15215193@qq.com                      先谢谢啦

出0入17汤圆

 楼主| 发表于 2012-11-8 16:10:51 | 显示全部楼层
mfkqtd 发表于 2012-11-8 15:51
兄弟啊,能不能把你做的那个STC单片机播放WAV的资料程序发给我啊,小弟现在在做这些方面的东西.急需这方面的 ...

程序都在楼主位贴出来了。

而且还打了个包提供下载,其他也就没什么了。

出0入0汤圆

发表于 2012-11-26 15:01:34 | 显示全部楼层
有几个问题:
1.低通滤波的参数,阻容值怎么确定
2.当PWM很高,比如44K以上了,2个相邻的音差距较大的时候,RC会不会使音频失真?
3.WAV的值是8位还是16位的,如果是8位的那么用16位的PWM就得传给高8位寄存器了
4.一个44K的WAV文件,用44K的PWM,是不是取一个WAV的值进行一次PWM转换,再取下一个进行一次转换。每个值只转换一次?
  如果用88K的PWM进行2次输出会不会音质好点?

出0入17汤圆

 楼主| 发表于 2012-11-26 21:49:09 | 显示全部楼层
wuyiduan 发表于 2012-11-26 15:01
有几个问题:
1.低通滤波的参数,阻容值怎么确定
2.当PWM很高,比如44K以上了,2个相邻的音差距较大的时候 ...


1.低通滤波器的参数:
通常人声和乐器的频率在4kH以内(我查的最高是女高音为3.6Khz),截止频率可以设为f=4K=1/(2πRC)
R取值1-10K之间,计算出C的值。
RC网络本身就不是精准的网络,不必强求RC的值,从音效上,听不出多大的差别。
其实只要不是直流,各个频率经过RC时,幅度都会有衰减。在截止频率时,幅度衰减到原来的0.7而已。


2.这种RC肯定有失真的。RC的作用主要是DA变换,顺便过滤一部分杂音。

3.可以看WAV文件格式标准,有8位wav和16位wav。无论那种,WAV的数据都是以字节的形式存储的,16Bit是低字节在前,高字节在后。

4.PWM的频率越高过滤的效果越好,但是44K与88K的效果差别多少,没做过实验,就不知道了。
  我个人分析:如果截止频率设在4K,一般情况PWM超16K以后的效果可能就不是很明显了。再加上人耳接收频率最大20K,所以44K足够了。

出0入0汤圆

发表于 2012-11-28 16:34:50 | 显示全部楼层
不知道是什么原理  如果能详细讲解一下 就好了  

出0入0汤圆

发表于 2012-11-28 21:44:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-11-29 08:42:41 | 显示全部楼层
PWM频率就是音频文件的采样频率,那么只靠8位的PWM的占空比等效出256种电压值就能表示出大千世界这么多种声音?
比如高音低音,节拍,每个字的发音...
我们所说的高音是指什么?模拟的频率高?
节拍是不是音速的快慢?

出0入17汤圆

 楼主| 发表于 2012-11-29 10:07:17 | 显示全部楼层
wuyiduan 发表于 2012-11-29 08:42
PWM频率就是音频文件的采样频率,那么只靠8位的PWM的占空比等效出256种电压值就能表示出大千世界这么多种声 ...


音频信号是一段模拟信号(包含音高,节拍),对这段音频采样就可以得到数字信号。

如果以8KHz的频率,8位的精度(256种电压)采样后,按照wav的格式存储起来,就是我们平时播放的wav文件了。

我们知道采样频率越快,采样精度越高,那么文件的音质就越好。当频率和精度达到一定程度时,人耳就分辨不出来了。

44khz,16位精度已经达到CD的音质了,基本上也就可以了。

我们用PWM播放文件,就是按照采样的频率,采样的精度将数字文件还原成模拟音频。

所以在播放时,你不需要考虑节拍,音高的问题。

我们所说的高音,就是模拟音频的高音。

出0入0汤圆

发表于 2012-11-29 10:10:38 | 显示全部楼层
谢谢解惑

出0入0汤圆

发表于 2012-11-29 10:12:06 | 显示全部楼层
另外能不能讨论一下,低通滤波和声音放大的电路
最好是能不用运放,就用电阻电容三极管这类的便宜的器件
呵呵

出0入17汤圆

 楼主| 发表于 2012-11-29 11:04:27 | 显示全部楼层
wuyiduan 发表于 2012-11-29 10:12
另外能不能讨论一下,低通滤波和声音放大的电路
最好是能不用运放,就用电阻电容三极管这类的便宜的器件
呵 ...

呵呵,这个玩不了。

出0入0汤圆

发表于 2012-12-5 10:23:32 | 显示全部楼层
先收集,回头再看。。。

出0入0汤圆

发表于 2012-12-7 20:37:53 | 显示全部楼层
今天用洞洞板做了一个
STM8S103F3,16M内部RC
PWM频率62500,经过2K电阻驱动三极管,5V接喇叭再到三极管集电极,射极到地,用示波器看了脉冲有尖峰,用个1N4007续流就好点了。三极管深度饱和。用你的WAV数据,每个播放8次,杂音倒是没听到什么,就是有2个问题:
1.声音很小,好像有点含糊。用个纸杯贴在纸杯底部声音能在3M处听到,不过环境要安静
2.喇叭播了十几分钟就有点热了,不是很烫的那种,就是有点温度,电流210MA


受限于MCU的容量,采样频率肯定上不去,要么加外部存储,要不用串口一边下一边放


还有个问题:把PWM做DA转换的电路应该叫积分电路更贴切吧

出0入0汤圆

发表于 2012-12-7 20:39:03 | 显示全部楼层
wicy001 发表于 2012-11-29 11:04
呵呵,这个玩不了。

今天用洞洞板做了一个
STM8S103F3,16M内部RC
PWM频率62500,经过2K电阻驱动三极管,5V接喇叭再到三极管集电极,射极到地,用示波器看了脉冲有尖峰,用个1N4007续流就好点了。三极管深度饱和。用你的WAV数据,每个播放8次,杂音倒是没听到什么,就是有2个问题:
1.声音很小,好像有点含糊。用个纸杯贴在纸杯底部声音能在3M处听到,不过环境要安静
2.喇叭播了十几分钟就有点热了,不是很烫的那种,就是有点温度,电流210MA


受限于MCU的容量,采样频率肯定上不去,要么加外部存储,要不用串口一边下一边放


还有个问题:把PWM做DA转换的电路应该叫积分电路更贴切吧

出0入17汤圆

 楼主| 发表于 2012-12-8 08:35:37 | 显示全部楼层
喇叭的驱动不足,导致声音很小。

常见的喇叭都1-2W,正常工作起来,声音是很大的。但是你的喇叭功率已经达到5V*210A>1W了,声音不应该像你说的那么小。
你在确认一下:
1.5V的电压是否全部加在了喇叭上? 中间是否有电阻分压了?
2.喇叭的功率是多大,如果远大于1W,声音会小
3.确定一下三级管的参数,通常用的9013,9014最大驱动0.5W的设备。

出0入17汤圆

 楼主| 发表于 2012-12-8 09:17:57 | 显示全部楼层
电流210M比较正常。如果按照2W喇叭算,工作电流可达2W/5V=400ma,1W喇叭是200ma。

你可以改变一下电路,加上电容,看看效果。

出0入0汤圆

发表于 2012-12-10 17:35:53 | 显示全部楼层
支持楼主

出0入0汤圆

发表于 2012-12-12 16:34:59 | 显示全部楼层
wuyiduan 发表于 2012-12-7 20:37
今天用洞洞板做了一个
STM8S103F3,16M内部RC
PWM频率62500,经过2K电阻驱动三极管,5V接喇叭再到三极管集 ...

不能用直流驱动。你要用电容耦合过去来驱动喇叭。

出0入0汤圆

发表于 2012-12-13 10:58:39 | 显示全部楼层
本帖最后由 wuyiduan 于 2012-12-13 11:27 编辑
wicy001 发表于 2012-12-8 08:35
喇叭的驱动不足,导致声音很小。

常见的喇叭都1-2W,正常工作起来,声音是很大的。但是你的喇叭功率已经达 ...


8欧 0.5W,直径3CM的喇叭
三极管8050
没用电阻分压限流
在喇叭上并了一个104和一个105和一个续流二极管4007,不加二极管会有很高的尖峰
按照喇叭的参数计算,电压2V就可以了
看了三极管CE电压波形是三角波,1.2~5V,振幅是3.8V
喇叭两端的波形也是三角波,0.3~3.5V,振幅3.2V
单片机输出波形是方波0~5V

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2012-12-13 11:42:36 | 显示全部楼层
wuyiduan 发表于 2012-12-13 10:58
8欧 0.5W,直径3CM的喇叭
三极管8050
没用电阻分压限流

现在的效果如何?


从喇叭的参数来看,以前喇叭过载了,所以会发热。

出0入0汤圆

发表于 2012-12-13 11:54:13 | 显示全部楼层
电路一直没改动
直流源显示的电流还是220MA
声音也很小,照样发热

出0入17汤圆

 楼主| 发表于 2012-12-13 12:09:04 | 显示全部楼层
wuyiduan 发表于 2012-12-13 11:54
电路一直没改动
直流源显示的电流还是220MA
声音也很小,照样发热

我画了个图,现在传不上去。  吃完饭再试试。

出0入0汤圆

发表于 2012-12-13 12:49:45 | 显示全部楼层
我的KK: 1 9 0 5 5 7 5 1 1

出0入17汤圆

 楼主| 发表于 2012-12-13 13:04:43 | 显示全部楼层
wuyiduan 发表于 2012-12-13 12:49
我的KK: 1 9 0 5 5 7 5 1 1




上拉的阻值建议初始1K,根据效果增大或减小,最小值要保证不能烧了三极管
电容一定要大容量的,推荐100uf以上(这个是用来增加驱动力的)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2012-12-13 13:06:38 | 显示全部楼层
上面的电路没有经过测试, 你实验出结果,说明一下。

出0入17汤圆

 楼主| 发表于 2012-12-13 13:07:43 | 显示全部楼层
R2用电位器调节最适合了。

出0入0汤圆

发表于 2012-12-13 15:22:33 | 显示全部楼层
不错 挺妙的!

出0入0汤圆

发表于 2012-12-15 19:05:26 | 显示全部楼层
改接后听不见
可能是焊接的问题

出0入0汤圆

发表于 2012-12-15 19:05:53 | 显示全部楼层
也有可能是电流大部分走三极管了

出0入0汤圆

发表于 2012-12-15 19:06:52 | 显示全部楼层
这种方式是不是不适合驱动喇叭,真不知道外面儿童玩具车上的喇叭怎么驱动的

出0入17汤圆

 楼主| 发表于 2012-12-16 11:33:56 | 显示全部楼层
wuyiduan 发表于 2012-12-15 19:06
这种方式是不是不适合驱动喇叭,真不知道外面儿童玩具车上的喇叭怎么驱动的 ...

我以前拆过玩具,就是三极管驱动的。

把我那个电路中,电容和喇叭串联,再试试。 电容的正极接三极管C端

出0入0汤圆

发表于 2012-12-16 22:40:23 | 显示全部楼层
这个电路能否驱动8欧1W或者0.5W的喇叭,音量是否可以满足童车级别,就是很多便利店门口放着给儿童做着一边摇一边唱歌的那种。

出0入17汤圆

 楼主| 发表于 2012-12-17 08:15:41 | 显示全部楼层
wuyiduan 发表于 2012-12-16 22:40
这个电路能否驱动8欧1W或者0.5W的喇叭,音量是否可以满足童车级别,就是很多便利店门口放着给儿童做着一边 ...

有些玩具是用蜂鸣器来做的,蜂鸣器比较容易驱动,几十毫安就可以,缺点就是声音不够圆润。

驱动1W喇叭,三极管可以实现。或者直接用个UNL2003。

出0入0汤圆

发表于 2012-12-17 14:59:01 | 显示全部楼层
今天把并在喇叭上的电容去掉,声音更响点
把电容串进去只能是如果用极性电容没声音,用无极限的22UF的有点小声音
呵呵
明天买个大点的喇叭

出0入0汤圆

发表于 2012-12-17 15:00:45 | 显示全部楼层
我拆开一个玩具0.58W8 欧的喇叭,那叫一个响啊,整个房间的人都受不了
用了一个音频功放
型号忘记了

出0入17汤圆

 楼主| 发表于 2012-12-18 08:49:17 | 显示全部楼层
wuyiduan 发表于 2012-12-17 14:59
今天把并在喇叭上的电容去掉,声音更响点
把电容串进去只能是如果用极性电容没声音,用无极限的22UF的有点 ...

嗯。现在有声就好。

但是对于你最初的电路,电流也很大,为什么没有声音呢?一直没想通呀。不知道现在有声的时候电流是多大?

出0入17汤圆

 楼主| 发表于 2012-12-18 09:06:22 | 显示全部楼层
wuyiduan 发表于 2012-12-17 15:00
我拆开一个玩具0.58W8 欧的喇叭,那叫一个响啊,整个房间的人都受不了
用了一个音频功放
型号忘记了

这与喇叭的设计也有很大关系。不同的厂家,做出来的也不一样,有的喇叭就是很响。

至于功放你可以先试试TDA2822M,TDA2030A 。 这是入门级的。

出0入0汤圆

发表于 2012-12-18 09:44:40 | 显示全部楼层
楼主的问题多看看视频就懂的
单片机学习视频免费下载地址:http://item.taobao.com/item.htm? ... &id=21688772847

出0入0汤圆

发表于 2013-3-19 20:57:42 | 显示全部楼层
wicy001 发表于 2012-4-27 20:26
自己沙发

楼主你好,小弟有两句看不懂,希望你能给指点一下               

if(BEEP)
{
   TH0=0xFF-currentdata;//这里为什么要0xFF-currentdata?               
else
{
   TH0=currentdata;
}

出0入17汤圆

 楼主| 发表于 2013-3-19 21:39:34 | 显示全部楼层
国防大学 发表于 2013-3-19 20:57
楼主你好,小弟有两句看不懂,希望你能给指点一下               

if(BEEP)

单片机每计数0-127,就是一个PWM周期。
WAV中的音频数据currentdata代表一个PWM周期内高电平的计数值(也就是高电平的时间),那么0XFF-currentdata代表低电平的计数值(也就是低电平时间)。

刚才想到,这样会不会高电平多计一个数,低电平少计一个数。

出0入0汤圆

发表于 2013-3-20 15:40:39 | 显示全部楼层
wicy001 发表于 2013-3-19 21:39
单片机每计数0-127,就是一个PWM周期。
WAV中的音频数据currentdata代表一个PWM周期内高电平的计数值(也 ...

谢谢楼主!
我现在想用stc12c5a60s2的硬PWM做PWM转DA输出WAV音频实验,看了stc12c5a60s2的datasheet,上面说CCAP0L,CCAP0H,是控制PWM0的占空比的。我将PWM频率设成43.2Khz,将WAV音频数据直接赋给CCAP0L和CCAP0H,楼主帮忙看看我这个程序可行不?

#include "stc12xxx_reg.h"
#include "sound.h"

unsigned int counter,wavedataL;
unsigned char currentdata,nextdata,i;
unsigned int tmp;

void PWM_Init(void)
{
        CMOD = 0x80;//将PWM时钟源设成系统时钟11.0592MHZ,即PWM时钟频率为11.0592/256=43.2khz
        CCON = 0x00;
        CCAPM0 = 0x42; //8位PWM输出,无中断
}

void main(void)
{
        tmp=sound[0x29];                           //从wav文件中取,数据长度。数据长度应该是4个字节,
        tmp=tmp<<8;
        wavedataL=tmp+sound[0x28];  //由于wav存在片内flash中,文件大小有限制,数据长度用int型足够表示了。
       
        counter=0x2c;          //wav文件第一个数据
       
//        currentdata=sound[counter];       
//        nextdata=sound[counter];
        PWM_Init();

        CR = 1;

        while(1)
        {
                CCAP0L = sound[counter];
                CCAP0H = sound[counter];
                counter++;

                if(counter>wavedataL)                //反复重播
                {
                         counter=0x2c;      
                }
        }       
}

这个东西我搞了大半年了,直到看到楼主的帖子才有点头绪,望楼主能帮帮忙,小弟在这谢谢了

出0入17汤圆

 楼主| 发表于 2013-3-20 17:58:08 | 显示全部楼层
国防大学 发表于 2013-3-20 15:40
谢谢楼主!
我现在想用stc12c5a60s2的硬PWM做PWM转DA输出WAV音频实验,看了stc12c5a60s2的datasheet,上 ...

我以前做的有。给你一个参考下吧

keil4版本的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2013-3-20 18:10:48 | 显示全部楼层
while(1)
        {
                CCAP0L = sound[counter];
                CCAP0H = sound[counter];
                counter++;
               ……
               ……
                }
你在while中,用上counter++ ,一个时钟counter加一次,会是什么效果? 你参考我的程序,再理解一下PWM吧

出0入0汤圆

发表于 2013-3-21 08:39:14 | 显示全部楼层
wicy001 发表于 2013-3-20 18:10
while(1)
        {
                CCAP0L = sound[counter];

真是太谢谢楼主了!看了楼主的程序恍然大悟,以后还要像楼主多学习,昨天仔细研究了楼主的程序,然后自己又写了 个,竟然可以了!真是太神奇了,谢谢楼主!

出0入17汤圆

 楼主| 发表于 2013-3-21 11:38:31 | 显示全部楼层
国防大学 发表于 2013-3-21 08:39
真是太谢谢楼主了!看了楼主的程序恍然大悟,以后还要像楼主多学习,昨天仔细研究了楼主的程序,然后自己 ...

很高兴,能够帮到你。

出0入0汤圆

发表于 2013-3-21 18:51:06 | 显示全部楼层
wicy001 发表于 2012-5-2 09:23
嗯。STC90/89不支持1T,最大支持6T,我可以试一下。

播放8KHz的wav,按理说接着8Khz输出是可以的。 ...

8K的WAVE文件是指采样率8K。而不是载波频率8K.对于这种东西载波频率得弄到人耳听不到的频率,比如说8K至少得32k的PWM.44K至少得100k的PWM。

出0入0汤圆

发表于 2013-4-28 16:57:35 | 显示全部楼层
wicy001 发表于 2012-5-2 09:23
嗯。STC90/89不支持1T,最大支持6T,我可以试一下。

播放8KHz的wav,按理说接着8Khz输出是可以的。 ...

播放8KHZ的WAV,如果PWM超过了8Khz,那播放出来的 声音不是被加快播放了??就是说话变快了

出0入0汤圆

发表于 2013-4-29 02:00:46 | 显示全部楼层
lr120363092 发表于 2013-4-28 16:57
播放8KHZ的WAV,如果PWM超过了8Khz,那播放出来的 声音不是被加快播放了??就是说话变快了 ...

PWM只是载波而已。
8kHz的WAVE指的是对占空比,或者说有效功率的改变量是8K次。对载波频率没有要求。对于8K的WAVE的话,20K的PWM载波是起步价(注意某些人,比如我能听到23k左右的声音,那种尖锐的令人头疼的声音,在这个PWM输出的下面要接个RC滤波。中心频点在4K左右就可以了)。
如果你要播放 CD音质的WAVE的话。对不起,PWM载波频率至少要100k。这个就别软件模拟了。老实用硬件PWM吧。

出0入17汤圆

 楼主| 发表于 2013-4-29 07:56:54 | 显示全部楼层
lr120363092 发表于 2013-4-28 16:57
播放8KHZ的WAV,如果PWM超过了8Khz,那播放出来的 声音不是被加快播放了??就是说话变快了 ...

8Khz的wav,如果PWM也是8K,那就是每个PWM的周期播放一个WAV数据,播放出来的WAV就是8Khz,正常语速

如果PWM是16K,WAV数据需要要PWM连续播放2次,再播放下一数据,这样播放出来WAV也是8Khz,正常语速,如果一个PWM周期仍播放一个WAV,语速就会快一倍。


人耳听得的范围在20K以内,所以PWM频率超过20K,基本上就听不到杂音(主要指PWM自身的杂音),效果还是可以的。如果对音效要求高,则可以提高PWM频率。

出0入17汤圆

 楼主| 发表于 2013-6-13 19:15:26 | 显示全部楼层
gamethink 发表于 2013-6-13 14:27
请教LZ,WAV记录的音频数据是有分正/负的,比如8位,究竟如何和PWM的0-255关联起来? ...

你好,WAV中的数据代表了电压的高低(电压的高低由PWM控制),进而表示为喇叭震动的振幅。

所以:正负数据,与0-255线性对应即可。

出0入0汤圆

发表于 2013-6-14 09:21:47 | 显示全部楼层
RC滤波改为LC滤波。
效果会好一些。电感可选用33uH,对地电容用0.47uF左右。可以适当增加电感来改变低通频率。

出0入0汤圆

发表于 2013-6-15 12:17:38 | 显示全部楼层
我用LMF4L120试了下,效果差的很,有很明显的尖噪音,我直接用IO驱动蜂鸣器,接音响效果好点,但噪声依然很大
50M/256 等效约200k的DA

void BeepLevelSet(int level);

#define VOICE_TIMER                         SYSCTL_PERIPH_TIMER2
#define VOICE_TIMER_BASE        TIMER2_BASE
#define VOICE_GPIO_PIN_CFG      GPIO_PB0_T2CCP0
#define VOICE_GPIO_PIN          GPIO_PIN_0
#define VOICE_GPIO_PERIPH       SYSCTL_PERIPH_GPIOB
#define VOICE_GPIO_BASE                  GPIO_PORTB_BASE

static unsigned int BufferPosMax=0;
static unsigned char *WaveBufferStart=0;

void IntTimer5HandlerA(void)
{
        static unsigned int BufferPos;
        HWREG(TIMER5_BASE + TIMER_O_ICR)   = 0x01;
        if(0==WaveBufferStart){
                BufferPos=0;
                return;
        }
        BeepLevelSet(WaveBufferStart[BufferPos]);
        BufferPos++;
        if(BufferPos>=BufferPosMax){
                BufferPos=0;
                WaveBufferStart=0;
        }
        return;
}
void BeepInit(void)
{
    //
    // Enable the GPIO Port and Timer for each LED
    //
        SysCtlPeripheralEnable(VOICE_GPIO_PERIPH);
        SysCtlPeripheralEnable(VOICE_TIMER);
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0);
    //
    // Configure each timer for output mode
    //
        HWREG(VOICE_TIMER_BASE + TIMER_O_CTL)   = 0x00;
    HWREG(VOICE_TIMER_BASE + TIMER_O_CFG)   = 0x04;
    HWREG(VOICE_TIMER_BASE + TIMER_O_TAMR)  = 0x0A;
    HWREG(VOICE_TIMER_BASE + TIMER_O_TAILR) = 0xFF;

    //
    // Invert the output signals.
    //
    HWREG(VOICE_TIMER_BASE + TIMER_O_CTL)   |= 0x40;
    //
    // Enable timers to begin counting
    //
    TimerEnable(VOICE_TIMER_BASE, TIMER_A);
    //
    // Reconfigure each LED's GPIO pad for timer control
    //
    GPIOPinConfigure(VOICE_GPIO_PIN_CFG);
    GPIOPinTypeTimer(VOICE_GPIO_BASE, VOICE_GPIO_PIN);
    GPIOPadConfigSet(VOICE_GPIO_BASE, VOICE_GPIO_PIN, GPIO_STRENGTH_2MA,
                     GPIO_PIN_TYPE_STD);

    BeepLevelSet(0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);
        HWREG(TIMER5_BASE + TIMER_O_CTL)   = 0x00;
    HWREG(TIMER5_BASE + TIMER_O_CFG)   = 0x04;
    HWREG(TIMER5_BASE + TIMER_O_TAMR)  = 0x02;
    HWREG(TIMER5_BASE + TIMER_O_TAILR) = 0x186A; //8000
    TimerMatchSet(TIMER5_BASE,TIMER_A,2);
    TimerEnable(TIMER5_BASE, TIMER_A);
    TimerIntEnable(TIMER5_BASE,TIMER_TIMA_TIMEOUT);//TIMER_TIMA_MATCH //TIMER_TIMA_TIMEOUT
    IntEnable(INT_TIMER5A);
}

void BeepLevelSet(int level)
{
        TimerMatchSet(VOICE_TIMER_BASE,TIMER_A,level);
}

void TestWaveOut(void)
{
        BufferPosMax=sizeof(wave_data);
        WaveBufferStart=(unsigned char*)wave_data;
}

出0入17汤圆

 楼主| 发表于 2013-6-16 08:25:00 | 显示全部楼层
vbvc6 发表于 2013-6-15 12:17
我用LMF4L120试了下,效果差的很,有很明显的尖噪音,我直接用IO驱动蜂鸣器,接音响效果好点,但噪声依然很大
50 ...

LMF4L120是什么MCU?程序看不懂。

根据经验,不加滤波,播放wav,音质也是很清晰的。 导致噪音的原因有最主要的就是PWM频率,其次是程序处理,有时一点小失误,会造成添加或漏掉数据等情况,肯定也有噪音。最后,音乐输出,是必须接喇叭或耳机的,蜂鸣器是不行的。

出0入0汤圆

发表于 2013-6-16 10:37:23 | 显示全部楼层
2003要用交流耦合

出0入0汤圆

发表于 2013-6-16 12:44:52 | 显示全部楼层
wicy001 发表于 2013-6-16 08:25
LMF4L120是什么MCU?程序看不懂。

根据经验,不加滤波,播放wav,音质也是很清晰的。 导致噪音的原因有最 ...

写错了,是LM4F120,TI的cortex-M4单片机,PWM频率,应该很高了,用音箱试过,效果是好些,但也有明显的噪音,同样的WAV,用脑放就没噪声,8K*8bit

出0入17汤圆

 楼主| 发表于 2013-6-16 15:15:17 | 显示全部楼层
vbvc6 发表于 2013-6-16 12:44
写错了,是LM4F120,TI的cortex-M4单片机,PWM频率,应该很高了,用音箱试过,效果是好些,但也有明显的噪音,同 ...

对于8bit 8hz的数据来说,IO端口要将每个数据PWM输24.4次才可以(可以粗略的输出24次)。你是否是这样输出的?


出0入0汤圆

发表于 2013-6-16 15:23:02 | 显示全部楼层
为什么是24.4次? 有什么算法?请明示下,谢谢

现在每个数据,输出次数,为 50M/256/8000=24次

出0入0汤圆

发表于 2013-6-16 15:28:57 | 显示全部楼层
知道了,计算器没设置好,只有整数了
50M/256/8000=24.41次
不过,这个是硬件PWM,代码只是以8K的速率给它发一个占空比的数据而已

出0入17汤圆

 楼主| 发表于 2013-6-16 16:40:36 | 显示全部楼层
vbvc6 发表于 2013-6-16 15:28
知道了,计算器没设置好,只有整数了
50M/256/8000=24.41次
不过,这个是硬件PWM,代码只是以8K的速率给它发一 ...



你仔细对比一下两者的差别。 如果只以8K的频率发送脉冲,虽然你的端口是50M,端口输出的PWM的频率也只有8k(这种情况就是我原本帖子里求助的情况,PWM频率太低了)。
如果PWM频率是8K*24的话,那么每T=1/8K的时间里,应该发送24个脉冲才对。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 19:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表