搜索
bottom↓
回复: 158

用51实现的真正和弦音乐

  [复制链接]

出0入0汤圆

发表于 2015-6-24 14:56:09 | 显示全部楼层 |阅读模式
一直想用单片机来产生和弦音乐,不用太复杂,有和弦效果就行,但网上100%的单片机产生音乐都是假和弦,基本都是单调的7个调加上时间控制,难听。
直到我听到这个:




这个是真的和弦,效果非常好,无奈联系不上作者,只有HEX文件,用的STC12C5A60S2单片机。我自行下载测试也是和录音的相同效果。
STC12C5A系统自行反编译明显出错,只好花钱网上找人反编译,反编译出的汇编代码编译出来的和原来的HEX文件效果一致,到这一步已经有希望了。

但问题来了....我已经忘记汇编了,寄存器一多就乱,只好花了些时间把数组提取出来,放上论坛,有精力的莫友可以一起帮把汇率转成C的。
汇率代码不多,就只有100行左右寄存器多的我看不过来。
能转成C语言也是一件好事,毕竟这是目前的最好效果了。

本帖子中包含更多资源

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

x

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2015-6-24 14:58:38 | 显示全部楼层
测试电路也简单

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2015-6-24 15:05:59 | 显示全部楼层
这个厉害,值得借鉴。

出0入0汤圆

发表于 2015-6-24 15:08:56 | 显示全部楼层
听了下,确实牛叉。现在产品中还是用到滴滴的蜂鸣器,要是能改成和弦提示音,就有点儿高大上了。

出0入93汤圆

发表于 2015-6-24 15:11:11 | 显示全部楼层
听了听效果不错

出0入0汤圆

发表于 2015-6-24 15:18:22 | 显示全部楼层
刚玩51时这个东西就是我的梦想啊。

出10入113汤圆

发表于 2015-6-24 15:23:10 | 显示全部楼层
看了程序,等于波表了。

出0入0汤圆

发表于 2015-6-24 15:25:39 | 显示全部楼层
对于51单片机这个效果非常好了

出0入0汤圆

 楼主| 发表于 2015-6-24 15:27:49 | 显示全部楼层
lans0625 发表于 2015-6-24 15:18
刚玩51时这个东西就是我的梦想啊。

梦想就在眼前啊

出0入10汤圆

发表于 2015-6-24 15:30:17 | 显示全部楼层
关注一下,看看怎么实现,以前只会单调声音

出0入0汤圆

发表于 2015-6-24 15:31:21 | 显示全部楼层

好多年前的了,现在都不玩单片机了。

出0入0汤圆

发表于 2015-6-24 15:41:03 | 显示全部楼层
本帖最后由 sbk100 于 2015-6-24 15:42 编辑

牛逼啊 顶一个!里面的汇编是源程序还是嵌入的汇编呢?

出0入0汤圆

 楼主| 发表于 2015-6-24 15:45:09 | 显示全部楼层
sbk100 发表于 2015-6-24 15:41
牛逼啊 顶一个!里面的汇编是源程序还是嵌入的汇编呢?

汇编是源程序,别外的C是我自己建的没添加进工程

出0入0汤圆

发表于 2015-6-24 16:37:45 | 显示全部楼层
里面的数组怎么用音乐转换出来呢?

出0入0汤圆

发表于 2015-6-24 16:43:14 | 显示全部楼层
这功能不错,MARK先

出5入14汤圆

发表于 2015-6-24 16:44:40 | 显示全部楼层
哇靠,这个实在太 NB 了!

出5入10汤圆

发表于 2015-6-24 16:45:51 | 显示全部楼层
这个真是牛!

出0入0汤圆

发表于 2015-6-24 16:55:25 | 显示全部楼层
就是用PWM实现DA的方法。
声音数据其实就是单声道的WAV
只要有足够的ROM存WAV数据,就可以播放音乐

出0入0汤圆

 楼主| 发表于 2015-6-24 16:58:24 | 显示全部楼层
yy625 发表于 2015-6-24 16:55
就是用PWM实现DA的方法。
声音数据其实就是单声道的WAV
只要有足够的ROM存WAV数据,就可以播放音乐 ...

你想简单了

出0入0汤圆

 楼主| 发表于 2015-6-24 16:58:55 | 显示全部楼层
用PWM播放WAV反而简单

出0入0汤圆

发表于 2015-6-24 17:40:03 | 显示全部楼层
只好花钱网上找人反编译,
----------------
这个你就破费了

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2015-6-24 18:03:15 | 显示全部楼层
wkman 发表于 2015-6-24 17:40
只好花钱网上找人反编译,
----------------
这个你就破费了  ...

这个只能编译标准的51系列吧,像这些1T的外设多了的会出错

出0入0汤圆

发表于 2015-6-24 18:13:55 | 显示全部楼层
能用Proteus仿真出效果吗?

出0入0汤圆

发表于 2015-6-24 19:22:00 来自手机 | 显示全部楼层
可惜我不知道真和弦和假和弦本质区别是什么,一个单片机同时产生两个假和弦楼主会不?然后叠加应该就是你要的真和弦了。你看到的都是软件延时做的假和弦,所以觉得这个很牛。

出0入0汤圆

发表于 2015-6-24 19:24:14 来自手机 | 显示全部楼层
关键字    DTMF     双音多频

出0入0汤圆

发表于 2015-6-24 19:38:46 | 显示全部楼层
听效果不是简单的双音频啊,有些长音结尾音量是逐渐衰减的,这个不是普通的PWM能做出来的,猜测可能用了SPWM这样的PWM调制,肯定函数做幅度衰减运算控制

出0入0汤圆

发表于 2015-6-24 19:42:08 | 显示全部楼层
这个人真的很牛~~~~~~~~~~~

出10入0汤圆

发表于 2015-6-24 19:45:00 来自手机 | 显示全部楼层
嘿嘿,mark!!

出200入0汤圆

发表于 2015-6-24 19:55:42 来自手机 | 显示全部楼层
收藏,期待C的程序出来

出0入0汤圆

发表于 2015-6-24 20:02:16 | 显示全部楼层
顶你.加油,一定要搞定啊.大家一起研究下.

出0入0汤圆

发表于 2015-6-24 20:02:30 | 显示全部楼层
同时调PWM的周期和占空比,应该能做出这种效果,关键是码表

出0入0汤圆

发表于 2015-6-24 21:54:54 | 显示全部楼层
很多年以前,咋坛子里有一个类似的帖子,是有c语言源码的。电路比这还简单,输出直接pwm无滤波。我还修改到avr上玩过。
你搜搜“和弦”,可能还能搜到。

出0入0汤圆

发表于 2015-6-24 22:10:33 | 显示全部楼层
本帖最后由 xiaoxu191 于 2015-6-24 22:19 编辑

AVR PWM 和弦产生器的来源是这个:
255-Voice PCM Sound Generator

出0入0汤圆

发表于 2015-6-24 22:15:13 | 显示全部楼层
下载学习与研究一下,谢谢Lz

出0入0汤圆

发表于 2015-6-24 22:16:38 | 显示全部楼层
和这个使用STC12C5A60S2 相同之处在于,STC这款通过PCA实现的PWM,也有较高的频率,因此声音会好听一些。一般的AVR时钟频率不够高,所以音质差一些。

还有这个:
Simple SD Audio Player with an 8-pin IC

出0入0汤圆

发表于 2015-6-24 22:20:38 | 显示全部楼层

当然AVR 的官方文档也说了:
AVR131: Using the AVR’s High-speed PWM

出0入0汤圆

 楼主| 发表于 2015-6-24 22:27:07 | 显示全部楼层
xiaoxu191 发表于 2015-6-24 22:16
和这个使用STC12C5A60S2 相同之处在于,STC这款通过PCA实现的PWM,也有较高的频率,因此声音会好听一些。一 ...

不,不是PWM播放WAV方式的,你看数据大小就知道了,播放WAV的话你存储空间够吗? 8K的采样率单片机那种存储你能播放多久?

出0入0汤圆

发表于 2015-6-25 00:36:41 来自手机 | 显示全部楼层
关注中。。。。

出0入0汤圆

发表于 2015-6-25 02:12:44 | 显示全部楼层
算法的核心应该是N(n<8)个不同幅度不同频率的正弦波实时查表计算和叠加。和弦不难,难的是音色。以51的速度,难在用有限的谐波合成好听的音色,如果能用3,5个谐波就能弄出好音色,剩下的事情就比较好办了。我估计旋律音是有音色的,而伴奏和弦音是没有音色的。不知道哪里有乐器音色的谐波成分表,可以简化一下谐波试试,看能不能弄出个也还好听的音色来。

出0入0汤圆

发表于 2015-6-25 08:16:04 | 显示全部楼层
学习谢谢!!!

出0入0汤圆

发表于 2015-6-25 08:16:53 | 显示全部楼层
来学习学习。。。。。。。。

出0入0汤圆

发表于 2015-6-25 08:20:43 | 显示全部楼层
洗衣机上的铃声就是这个吧,哪位高手能用C语言搞一下就太好了

出0入0汤圆

发表于 2015-6-25 09:02:54 | 显示全部楼层
amazing030 发表于 2015-6-24 22:27
不,不是PWM播放WAV方式的,你看数据大小就知道了,播放WAV的话你存储空间够吗? 8K的采样率单片机那种存 ...

是的,完全同意,此处不是用PWM播放WAV。但是发声的原理是一样的,就是用PWM对已经量化的声音数据进行还原,理论依据是香农采样定理(又称奈奎斯特采样定理):为了不失真地恢复模拟信号,采样频率应该不小于模拟信号频谱中最高频率的2倍。 我注意到你的硬件电路中使用了22MHz晶振,而STC12C5A60的PCA生成PWM的频率和其它80512芯片比较高,所以认为和那个AVR(使用Tiny85,Tiny861,内部有高频振荡器供PWM)有相似之处,就是采样(还原)频率较高,音质会比较好。根据使用的GPIO引脚功能和晶振,判断是PWM无疑。

这不是重点。

我听了你帖子里的音频,感觉和玩具(使用语音芯片的和弦功能)比较,并没有更好。只能说,实现多音频的和弦,比单音好听。

值得进一步分析的是:如何编辑出好听的音色?
39楼 teddeng 的观点有启发。



出0入0汤圆

发表于 2015-6-25 09:26:43 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2015-6-25 09:59:09 | 显示全部楼层
有意思,抽空试试

出0入0汤圆

发表于 2015-6-25 10:48:39 | 显示全部楼层
我把数组中的数据按16位绘制成了波形,从波形上看,ADDR_02E0与ADDR_0630较乱,可能是用于产生音色,
其它数组可能是与音源相乘,产生调幅信号.







本帖子中包含更多资源

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

x

出0入12汤圆

发表于 2015-6-25 11:17:24 | 显示全部楼层
这个要关注,多媒体了

出0入0汤圆

发表于 2015-6-25 11:29:08 | 显示全部楼层
怎么听?用当真软件可以吗

出0入0汤圆

发表于 2015-6-25 16:48:44 | 显示全部楼层
真有这么好听么,有空试试

出0入0汤圆

发表于 2015-6-25 18:37:26 | 显示全部楼层
LZ真有耐心, 还原反汇编的代码.....

出0入0汤圆

发表于 2015-6-25 18:48:26 | 显示全部楼层
为毛,这几天下载速度这么揪心呢?下载文件也是坏的

出0入85汤圆

发表于 2015-6-25 19:25:19 | 显示全部楼层
看了反汇编的程序,代码不长,转C应该问题不大

出90入4汤圆

发表于 2015-6-25 21:07:13 | 显示全部楼层
MARK ,有时间研究下,下次不用滴滴滴了。只要实现最简单的 替换 滴滴 ,呵呵

出0入0汤圆

发表于 2015-6-25 22:10:05 | 显示全部楼层
里面哪个hex是原始hex?
用keil v2编译STC12C5A60.asm,得到的hex和下载的hex比较有点不一样。

出0入0汤圆

发表于 2015-6-25 22:20:21 | 显示全部楼层
如果是弄成和弦音,真是高大上。关注中

出0入0汤圆

发表于 2015-6-25 23:13:48 来自手机 | 显示全部楼层
这绝对是一技术贴,期待高手出现。

出0入0汤圆

发表于 2015-6-25 23:41:43 来自手机 | 显示全部楼层
关注 俺也就是做到单音频加强度

出0入0汤圆

发表于 2015-6-26 00:21:51 | 显示全部楼层
这还是比较值得关注的....

出0入0汤圆

发表于 2015-6-26 00:28:15 来自手机 | 显示全部楼层
关注,期待大牛神作。。。

出0入0汤圆

发表于 2015-6-26 01:04:32 | 显示全部楼层
这是PWM播放,网上很多例程吧,我也做出来了,效果还不错。

出0入0汤圆

发表于 2015-6-26 14:48:38 | 显示全部楼层
这个感觉高大上的样子,期待高手

出0入0汤圆

 楼主| 发表于 2015-6-26 17:29:48 | 显示全部楼层
明确几点:
1. 不是PWM播放WAV的方式,看程序里数组大小就知道了,只用了几K可以播放几分钟。还要教我怎么播放WAV的话看我这个帖子:
http://www.amobbs.com/thread-4743480-1-1.html
算是单片机播放WAV的一个极致应用了,而且,是开源的。
2.觉得用定时器代替软件延时就让我觉得NB的请自行听一下录音,并看下程序,没有外挂FLASH。
3.真假和弦,个人说法而已,大家也听的出来这个已经有了多种音乐效果。
4.楼上有网友切到谐波也就是码表的重点了,关键是,码表已经在程序里了,也就是说可以做出来一样音色的其它歌曲。
5.这个程序真的不复杂,要分析的不多,熟悉汇编的都能搞定

出0入0汤圆

 楼主| 发表于 2015-6-26 17:35:11 | 显示全部楼层
而且这个效果比低端的牛屎和弦芯片效果要好,还是很有意义的

出0入0汤圆

发表于 2015-6-26 17:48:02 | 显示全部楼层
继续关注中  

出0入0汤圆

发表于 2015-6-26 17:52:33 | 显示全部楼层
amazing030 发表于 2015-6-26 17:35
而且这个效果比低端的牛屎和弦芯片效果要好,还是很有意义的

有做过SPI flash芯片做字库吗?能否指点一下呢?

出0入0汤圆

发表于 2015-6-26 18:08:12 | 显示全部楼层
收藏了,回家详细看

出0入21汤圆

发表于 2015-6-26 18:45:37 | 显示全部楼层
感觉仅仅懂单片机搞不出这样的效果

出0入0汤圆

发表于 2015-6-26 18:46:42 | 显示全部楼层
amazing030 发表于 2015-6-26 17:29
明确几点:
1. 不是PWM播放WAV的方式,看程序里数组大小就知道了,只用了几K可以播放几分钟。还要教我怎么 ...

能否用C语言实现一个呢??

出0入8汤圆

发表于 2015-6-26 21:49:14 | 显示全部楼层
这个音质,有些带音乐的计算器可以发出来。具体原理不知道,用示波器直接看的话,像是PWM控制音量。好久以前的事情了,记不太清了。后来也没再研究。

出0入0汤圆

发表于 2015-6-27 00:24:55 | 显示全部楼层
amazing030 发表于 2015-6-26 17:29
明确几点:
1. 不是PWM播放WAV的方式,看程序里数组大小就知道了,只用了几K可以播放几分钟。还要教我怎么 ...


大师我错了
原来你是玩WAV长大的。
期待你的成功

出0入0汤圆

 楼主| 发表于 2015-6-27 11:29:59 | 显示全部楼层
http://v.youku.com/v_show/id_XNTY0MzkxMTUy.html

给大家看看一个程序不NB但做出来很NB的东东,不是我做的,想做没那么多精力和余钱啊

出0入0汤圆

发表于 2015-6-27 14:09:05 | 显示全部楼层
  原帖的地址就不贴出来了,大家可以度娘一下。
原作者说的原理是“
1.波形合成,产生基准音高,事先生成一个正弦波形表,查表实现
2.谐波混频,产生几个奇次谐波适量混入基频,改变音色,也可在波形表里直接使用含各次谐波的波形数据,而省略此步骤,但音色效果便不能灵活改变
3.包络调制,产生弹奏型或吹奏型或打击型效果,事先生成各种包络数据,查表,
4.多通道混合,以上123用多个通道分别实现主旋律\伴奏\等,只要单片机速度允许.
5.pwm做da输出,
第1步决定音调,第2和第3步决定音色效果,比如混入适量方波,使用吹奏型包络调制,可产生类似长笛小号萨克斯效果,使用弹奏型包络则有吉他或电吉他效果,如音调较高 则有风铃或八音盒效果.单纯的正弦波声音暗哑无光,必须在正弦波里混入一些谐波或制造一点失真,产生的音色才会丰满,明亮
波形数据在进行运算时要按有符号数处理,最后进行直流偏置,如果按无符号数处理,不做直流偏置,则音符和音符之间有咔哒声”

出0入0汤圆

发表于 2015-6-28 10:43:10 | 显示全部楼层
我们坛里高手就是牛,有你们才精彩,赞一个

出0入0汤圆

发表于 2015-6-28 23:02:49 来自手机 | 显示全部楼层
谁能做出来可太厉害了

出0入0汤圆

发表于 2015-6-28 23:05:07 | 显示全部楼层
牛人啊         

出0入0汤圆

发表于 2015-6-29 09:04:18 | 显示全部楼层
不知道你们要的是不是这个.这是以前收集到的.主要精髓在以下代码里.附件是原程序

/**************************************************************************
   
                                             SOUND PLAY FOR 51MCU
  
                               COPYRIGHT (c)   2005 BY JJJ.
                                       --  ALL RIGHTS RESERVED  --
  
   File Name:       SoundPlay.h
   Author:          Jiang Jian Jun
   Created:         2005/5/16
   Modified:                NO
   Revision:                 1.0
  
*******************************************************************************/

/*说明**************************************************************************
曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0};        末尾:0,0 表示结束(Important)

音高由三位数字组成:
                个位是表示 1~7 这七个音符
                十位是表示音符所在的音区:1-低音,2-中音,3-高音;
                百位表示这个音符是否要升半音: 0-不升,1-升半音。

音长最多由三位数字组成:
                个位表示音符的时值,其对应关系是:
                        |数值(n):  |0 |1 |2 |3 | 4 | 5 | 6
                        |几分音符: |1 |2 |4 |8 |16 |32 |64                 音符=2^n
                十位表示音符的演奏效果(0-2):  0-普通,1-连音,2-顿音
                百位是符点位: 0-无符点,1-有符点

调用演奏子程序的格式
                Play(乐曲名,调号,升降八度,演奏速度);
        |乐曲名           : 要播放的乐曲指针,结尾以(0,0)结束;
        |调号(0-11)       :        是指乐曲升多少个半音演奏;
        |升降八度(1-3)          : 1:降八度, 2:不升不降, 3:升八度;
        |演奏速度(1-12000):        值越大速度越快;

***************************************************************************/
#ifndef __SOUNDPLAY_H_REVISION_FIRST__
#define __SOUNDPLAY_H_REVISION_FIRST__

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

#define SYSTEM_OSC                 12000000        //定义晶振频率12000000HZ
#define SOUND_SPACE         4/5                 //定义普通音符演奏的长度分率,//每4分音符间隔
sbit    BeepIO    =           P3^7;                //定义输出管脚

unsigned int  code FreTab[12]  = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };                                                                   //1~7在频率表中的位置
unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };                                               
unsigned char Sound_Temp_TH0,Sound_Temp_TL0;        //音符定时器初值暂存
unsigned char Sound_Temp_TH1,Sound_Temp_TL1;        //音长定时器初值暂存
//**************************************************************************
void InitialSound(void)
{
        BeepIO = 0;
        Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;        // 计算TL1应装入的初值         (10ms的初装值)
        Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;        // 计算TH1应装入的初值
        TH1 = Sound_Temp_TH1;
        TL1 = Sound_Temp_TL1;
        TMOD  |= 0x11;
        ET0    = 1;
        ET1           = 0;
        TR0           = 0;
        TR1    = 0;
        EA     = 1;
}

void BeepTimer0(void) interrupt 1        //音符发生中断
{
        BeepIO = !BeepIO;
        TH0    = Sound_Temp_TH0;
        TL0    = Sound_Temp_TL0;
}
//**************************************************************************
void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
        unsigned int NewFreTab[12];                //新的频率表
        unsigned char i,j;
        unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
        unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
        for(i=0;i<12;i++)                                 // 根据调号及升降八度来生成新的频率表
        {
                j = i + Signature;
                if(j > 11)
                {
                        j = j-12;
                        NewFreTab[i] = FreTab[j]*2;
                }
                else
                        NewFreTab[i] = FreTab[j];

                if(Octachord == 1)
                        NewFreTab[i]>>=2;
                else if(Octachord == 3)
                        NewFreTab[i]<<=2;
        }                                                                       
       
        SoundLength = 0;
        while(Sound[SoundLength] != 0x00)        //计算歌曲长度
        {
                SoundLength+=2;
        }

        Point = 0;
        Tone   = Sound[Point];       
        Length = Sound[Point+1];                         // 读出第一个音符和它时时值
       
        LDiv0 = 12000/Speed;                                // 算出1分音符的长度(几个10ms)        
        LDiv4 = LDiv0/4;                                         // 算出4分音符的长度
        LDiv4 = LDiv4-LDiv4*SOUND_SPACE;         // 普通音最长间隔标准
        TR0          = 0;
        TR1   = 1;
        while(Point < SoundLength)
        {
                SL=Tone%10;                                                                 //计算出音符
                SM=Tone/10%10;                                                                 //计算出高低音
                SH=Tone/100;                                                                 //计算出是否升半
                CurrentFre = NewFreTab[SignTab[SL-1]+SH];         //查出对应音符的频率        
                if(SL!=0)
                {
                        if (SM==1) CurrentFre >>= 2;                 //低音
                        if (SM==3) CurrentFre <<= 2;                 //高音
                        Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
                        Sound_Temp_TH0 = Temp_T/256;
                        Sound_Temp_TL0 = Temp_T%256;
                        TH0 = Sound_Temp_TH0;  
                        TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿
                }
                SLen=LengthTab[Length%10];         //算出是几分音符
                XG=Length/10%10;                         //算出音符类型(0普通1连音2顿音)
                FD=Length/100;
                LDiv=LDiv0/SLen;                         //算出连音音符演奏的长度(多少个10ms)
                if (FD==1)
                        LDiv=LDiv+LDiv/2;
                if(XG!=1)       
                        if(XG==0)                                 //算出普通音符的演奏长度
                                if (SLen<=4)       
                                        LDiv1=LDiv-LDiv4;
                                else
                                        LDiv1=LDiv*SOUND_SPACE;
                        else
                                LDiv1=LDiv/2;                 //算出顿音的演奏长度
                else
                        LDiv1=LDiv;
                if(SL==0) LDiv1=0;
                        LDiv2=LDiv-LDiv1;                 //算出不发音的长度
                  if (SL!=0)
                {
                        TR0=1;
                        for(i=LDiv1;i>0;i--)         //发规定长度的音
                        {
                                while(TF1==0);
                                TH1 = Sound_Temp_TH1;
                                TL1 = Sound_Temp_TL1;
                                TF1=0;
                        }
                }
                if(LDiv2!=0)
                {
                        TR0=0; BeepIO=0;
                        for(i=LDiv2;i>0;i--)         //音符间的间隔
                        {
                                while(TF1==0);
                                TH1 = Sound_Temp_TH1;
                                TL1 = Sound_Temp_TL1;
                                TF1=0;
                        }
                }
                Point+=2;
                Tone=Sound[Point];
                Length=Sound[Point+1];
        }
        BeepIO = 0;
}
//**************************************************************************
#endif

出0入0汤圆

发表于 2015-6-29 09:10:10 | 显示全部楼层
这个音质有点不行哦,楼主这样也能接受?  我觉得以前坛里曾有的一个贴子里的音质比这个要好些,http://www.amobbs.com/thread-3614256-1-1.html ,里面有C语言源程序和各种讨论。

出0入8汤圆

发表于 2015-6-29 09:37:04 | 显示全部楼层
果然厉害,下来听一下~

出0入0汤圆

 楼主| 发表于 2015-6-29 10:54:04 | 显示全部楼层
hwbrat 发表于 2015-6-29 09:10
这个音质有点不行哦,楼主这样也能接受?  我觉得以前坛里曾有的一个贴子里的音质比这个要好些,http://www ...

哈哈,多谢了,是很不错啊

出0入0汤圆

发表于 2015-6-29 11:07:14 | 显示全部楼层
这个效果挺不错,利害啊!

出0入0汤圆

发表于 2015-6-29 14:53:26 | 显示全部楼层
持续关注中……

出0入0汤圆

 楼主| 发表于 2015-6-30 13:18:05 | 显示全部楼层
hwbrat 发表于 2015-6-29 09:10
这个音质有点不行哦,楼主这样也能接受?  我觉得以前坛里曾有的一个贴子里的音质比这个要好些,http://www ...

的确,这个效果更好啊,但程序里关键的一段还是汇编的,还是用的AVR,我就更头疼了....有没有熟悉汇编的网友帮忙转一下啊

出0入0汤圆

 楼主| 发表于 2015-6-30 13:28:10 | 显示全部楼层
要转的只有100行不到吧,应该有人收空做一下吧

出0入0汤圆

发表于 2015-6-30 14:01:18 | 显示全部楼层
不懂音乐 看看

出0入0汤圆

发表于 2015-6-30 14:20:49 | 显示全部楼层
大牛真是多啊

出0入0汤圆

发表于 2015-6-30 16:46:28 | 显示全部楼层
不懂音乐,听了下,确实不错!
有个想法,把这两首歌的乐谱拿出来对比下是不是能发现什么。。。

出0入0汤圆

发表于 2015-7-1 09:53:32 | 显示全部楼层
以前的收集的。

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2015-7-1 09:57:22 | 显示全部楼层
oktek 发表于 2015-7-1 09:53
以前的收集的。

没有码表一看就是不行的,只是简单的频率发音

出0入0汤圆

 楼主| 发表于 2015-7-1 10:02:01 | 显示全部楼层
唉,就没个人熟悉汇编吗,要转C的语句都不多

出10入23汤圆

发表于 2015-7-1 10:14:08 来自手机 | 显示全部楼层
amazing030 发表于 2015-7-1 10:02
唉,就没个人熟悉汇编吗,要转C的语句都不多

一楼的汇编资料我已经转了一部分了,剩下的还在慢慢啃

出0入0汤圆

 楼主| 发表于 2015-7-1 10:18:38 | 显示全部楼层
zouzhichao 发表于 2015-7-1 10:14
一楼的汇编资料我已经转了一部分了,剩下的还在慢慢啃

哈哈,不错。79楼提到的这个效果好像更好,你可以听一下,只是中断部分是汇编,用的AVR,汇编部分有注释的

http://www.amobbs.com/thread-3614256-1-1.html

出0入0汤圆

发表于 2015-7-1 10:19:01 | 显示全部楼层
这个只能用STC12C5A60S2试听吗?手上只有STC的别的MCU.

出10入23汤圆

发表于 2015-7-1 10:19:45 来自手机 | 显示全部楼层
amazing030 发表于 2015-7-1 10:18
哈哈,不错。79楼提到的这个效果好像更好,你可以听一下,只是中断部分是汇编,用的AVR,汇编部分有注释 ...

谢谢提供资料

出10入23汤圆

发表于 2015-7-1 10:22:04 来自手机 | 显示全部楼层
amazing030 发表于 2015-7-1 10:18
哈哈,不错。79楼提到的这个效果好像更好,你可以听一下,只是中断部分是汇编,用的AVR,汇编部分有注释 ...

中午我把分析的资料整理一下发上来交流一下

出0入0汤圆

 楼主| 发表于 2015-7-1 10:28:57 | 显示全部楼层
wintelboy 发表于 2015-7-1 10:19
这个只能用STC12C5A60S2试听吗?手上只有STC的别的MCU.

你要看下那个个寄存器是不是一样的

出0入0汤圆

 楼主| 发表于 2015-7-1 10:29:27 | 显示全部楼层
这是79楼地址里的效果
http://d1.amobbs.com/bbs_upload782111/files_19/ourdev_487499.txt

出10入23汤圆

发表于 2015-7-1 12:54:42 | 显示全部楼层
amazing030 发表于 2015-7-1 10:02
唉,就没个人熟悉汇编吗,要转C的语句都不多

程序流程估计你已经弄出来了,我就写写小小的细节吧。
程序中多次用到LCALL Q0DF9,想必这个Q0DF9是个数学计算函数,那就先把它读明白。
Q0DF9:
        MOV   A,R3                         ;0DF9   EB
        MOV   B,R7                         ;0DFA   8F F0
        MUL   AB                           ;0DFC   A4
        ;BA = R3*R7
        ;乘法指令,结果B为高8位,A为低8位
       
        MOV   R4,B                         ;0DFD   AC F0
        MOV   R5,A                         ;0DFF   FD
        ;R4R5 = R3*R7
        ;将B和A挪至R4R5
       
        MOV   A,R3                         ;0E00   EB
        MOV   B,R6                         ;0E01   8E F0
        MUL   AB                           ;0E03   A4
        ;BA = R3*R6
        ;乘法指令,结果B为高8位,A为低8位
       
        ADD   A,R4                         ;0E04   2C
        MOV   R4,A                         ;0E05   FC
        ;R4 = R4 + A
        ;注意这个时候可能有进位
        CLR   A                            ;0E06   E4
        ADDC  A,B                          ;0E07   35 F0
        ;B = B + 进位,实质上这是8位单片机做16/32位整数加法的常用代码
        MOV   R3,A                         ;0E09   FB
        ;将A挪至R3
        ;R3R4R5 = R3*R7 + (R3*R6 << 8)
        ;这一步一定要琢磨明白,下面的代码跟这个类似
       
        MOV   A,R2                         ;0E0A   EA
        MOV   B,R7                         ;0E0B   8F F0
        MUL   AB                           ;0E0D   A4
        ;BA = R2*R7
        ;这个就不啰嗦了,同上分析
       
        ADD   A,R4                         ;0E0E   2C
        MOV   R4,A                         ;0E0F   FC
        MOV   A,R3                         ;0E10   EB
        ADDC  A,B                          ;0E11   35 F0
        MOV   R3,A                         ;0E13   FB
        ;R3R4 = R3R4 + BA
        ;R3R4R5 = R3*R7 + ((R3*R6 + R2*R7) << 8)
        ;这个就不啰嗦了,同上分析
       
        CLR   A                            ;0E14   E4
        RLC   A                            ;0E15   33左移一位
        ;A = CY
        ;这两行代码就是为了取出上次加法运算的进位码,为后面更高位的运算做铺垫
       
        XCH   A,R2                         ;0E16   CA
        ;交换A和R2,相当于几个MOV
        MOV   B,R6                         ;0E17   8E F0
        MUL   AB                           ;0E19   A4
        ;R2R3R4R5 = R3*R7 + ((R3*R6 + R2*R7) << 8)
        ;BA = R2*R6
        ;这个就不啰嗦了,同上分析
       
        ADD   A,R3                         ;0E1A   2B
        MOV   R3,A                         ;0E1B   FB
        MOV   A,R2                         ;0E1C   EA
        ADDC  A,B                          ;0E1D   35 F0
        MOV   R2,A                         ;0E1F   FA
        ;R2R3 = R2R3 + BA
        ;R2R3R4R5 = R3*R7 + ((R3*R6 + R2*R7) << 8) + (R2*R6 << 16);
        ;这个就不啰嗦了,同上分析
        ;至此,整个函数的功能很明白了,至于用C重写,那简单得很了
        RET                                ;0E20   22

出10入23汤圆

发表于 2015-7-1 12:59:45 | 显示全部楼层
amazing030 发表于 2015-7-1 10:02
唉,就没个人熟悉汇编吗,要转C的语句都不多

Q0DE4和Q0175都是初始化定时器的代码,这个更简单,转换成C也分分钟的事,就不写了

出0入0汤圆

发表于 2015-7-1 13:20:48 | 显示全部楼层
很不错啊,上次做了一个PWM输出时,杂音很大。

出50入10汤圆

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

本版积分规则

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

GMT+8, 2024-4-26 14:04

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

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