初学单片机的时候不会定时器,刚学了蜂鸣器想搞音乐但调全崩了,研究了半天研究出了一个计算用
while(i--);
的操作搞相对准确的音调;
先说下我计算的过程吧
(本作者单片机也没学多深,文章里肯定会有错误或不准确的请指出,谢谢)
先来一小段代码
#include<reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit beep = P1^5; //蜂鸣器引脚
void delay(uint i){
while(i--);
beep = !beep;//这里设置一个断点
}
void main(){
while(1){
delay(scale[0]);
}
}
先将keil晶振设置为12(我实验板子上的),用keil的调试和断点功能和模拟功能,根据这位大佬的
------------------------------------
------------------------------------
假设表是十分准确的
中 1 DO 频率 523HZ 半周期 0956 微秒
断点设置在
用delay(104);
我们可以测试出(sec)
运行前 0.00133900 运行一次 0.00229400 运行两次 0.00324900
差都为
0.00095500
用delay(104);
我们可以测试出(sec)
运行前 0.00133900 运行一次 0.00229400 运行两次 0.00324900
差都为
0.00095500
和半周期标准值956(伪)差一点点
用delay(105);
我们可以测试出(sec)
运行前 0.00134800 运行一次 0.00231200 运行两次 0.00327600
差都为
0.00096400
所以按照标准值为956的情况下,要想得到准确的延迟956,delay内应该为104+1/9
假设存在一个系数使 delay内 乘 系数 = 半周期
可求得系数约为
9.182497331910353
用 中 2 RE 频率 578 HZ 半周期 0842 微妙
来测试
得到 delay内 为 91.69618781961877 约为 92
带回上面那串代码测试
delay(92);
我们可以测试出(sec)
运行前 0.00123100 运行一次 0.00207800 运行两次 0.00292500
差都为
0.00084700
delay(91);
我们可以测试出(sec)
运行前 0.00122200 运行一次 0.00206000 运行两次 0.00289800
差都为
0.00083800
与标准值接近
根据此操作可以算出如下延时操作时,每个音对应delay内部的数
void delay(uint i){
while(i--);
beep = !beep;//这里设置一个断点
}
以下为根据如上操作计算结果
(不用定时器如果代码不同会导致时间不同,因为运行代码计算会消耗时间,所以建议写的时候自己计算下时间,如果用一下数据请确保delay内部和上面那代码栏内的一样,不然会崩的)
----------------------------------------------------
低 208,185,165,156,139,123,110
中 104,92,83,78,69,62,55,
高 52,46,41,39,35,31,27
----------------------------------------------------
还有种操作根据频率计算的这里就不讲了。
附上根据频率计算系数搞出来的极乐净土及乐谱
(我写的太占空间了,原本是写两只老虎就没用数组写直接硬写,后来改极乐净土肝到一半才觉得有点不对劲。。。。不想浪费劳动成果,就直接硬写下去了,懒得再改用数组再写了)
以下为成品代码
#include<reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit beep = P1^5;
uint scale[] = {108, 102,93,81,77,68,61,54, 51,46,41,38,34,30,27};/中高部分,最前面那个是为了凑数,毕竟每个调对应相应的简谱数字比较好检查,我测试是直接用这里的代码测试出来的,所以数字会有差别,毕竟不用定时器代码不同会占用计算,导致时间不同所以建议写的时候自己计算下时间
uint scalel[] = {204, 204,182,162,153,137,122,108};//低音部分
void delay(uint i){
while(i--);
}
void tone(uchar tone,uchar time,uchar stop){
uint Time = time*12500/scale[tone];
uint Stop = stop * 1250;
while(Time--){
beep = ~beep;
delay(scale[tone]);
}
delay(Stop);
}
void tonel(uchar tone,uchar time,uchar stop){
uint Time = time*12500/scalel[tone];
uint Stop = stop * 1250;
while(Time--){
beep = ~beep;
delay(scalel[tone]);
}
delay(Stop);
}
void main(){
uchar a = 2;
while(1){
//1
tone(3,2,2);
tone(5,2,2);
tone(6,2,20);
tone(5,2,2);
tone(6,2,20);
tone(5,2,2);
tone(6,2,2);
tone(8,2,2);
tone(5,2,2);
tone(6,2,2);
tone(3,2,10);
tone(3,2,2);
tone(5,2,2);
tone(6,2,20);
tone(5,2,2);
tone(6,2,20);
tone(5,2,2);
tone(6,2,2);
tone(10,2,2);
tone(8,2,2);
tone(9,2,2);
tone(6,2,10);
tone(3,2,2);
tone(5,2,2);
//2
tone(6,2,20);
tone(5,2,2);
tone(6,2,20);
tone(5,2,2);
tone(6,2,2);
tone(8,2,2);
tone(5,2,2);
tone(6,2,2);
tone(3,2,2);
tone(5,2,2);
tone(1,2,2);
tone(2,2,2);
tone(3,4,2);
tone(8,4,2);
tone(6,4,2);
tone(10,4,2);
tone(9,2,2);
tone(10,1,2);
tone(9,1,2);
tone(8,2,2);
tone(9,2,2);
tone(6,4,20);
//3
tone(6,4,2);
tone(6,4,2);
tone(6,4,2);
tone(6,1,2);
tone(8,1,2);
tone(9,1,2);
tone(10,1,2);
tone(6,4,2);
tone(6,4,2);
tone(6,2,2);
tone(5,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,4,2);
tone(6,4,2);
tone(6,4,2);
tone(6,1,2);
tone(8,1,2);
tone(9,1,2);
tone(10,1,2);
tone(6,4,2);
tone(6,4,2);
tone(6,2,2);
tone(11,2,2);
tone(11,2,2);
tone(10,2,2);
while(a--){
//4
tone(6,4,2);
tone(6,4,2);
tone(6,4,2);
tone(6,1,2);
tone(8,1,2);
tone(9,1,2);
tone(10,1,2);
tone(6,4,2);
tone(6,4,2);
tone(6,2,2);
tone(5,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,4,2);
tone(6,4,2);
tone(6,4,2);
tone(6,1,2);
tone(8,1,2);
tone(9,1,2);
tone(10,1,2);
tone(13,4,2);
tone(5,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,4,30);
//5
tone(6,2,2);
tone(6,2,2);
tone(5,1,2);
tone(5,1,2);
tone(5,2,2);
tone(6,2,2);
tone(5,2,2);
tone(3,2,2);
tone(3,2,2);
tone(5,1,2);
tone(3,1,2);
tone(3,4,50);
tone(6,2,2);
tone(6,2,2);
tone(5,2,2);
tone(6,2,2);
tone(7,2,2);
tone(8,4,2);
tone(7,4,2);
tone(6,2,2);
tone(7,1,2);
tone(6,1,2);
tone(5,4,30);
//6
tone(6,2,2);
tone(6,2,2);
tone(5,2,2);
tone(5,2,2);
tone(6,1,2);
tone(5,1,2);
tone(5,2,2);
tone(3,2,2);
tone(3,2,2);
tone(5,1,2);
tone(3,1,2);
tone(3,4,10);
tone(5,2,2);
tone(5,2,2);
tone(6,2,10);
tone(5,2,2);
tone(5,2,2);
tone(6,2,10);
tone(6,1,2);
tone(7,1,2);
tone(8,4,2);
tone(9,4,2);
tone(6,2,2);
tone(3,2,2);
tone(3,2,2);
tone(5,2,2);
//7
tone(5,2,2);
tone(6,2,10);
tone(10,2,2);
tone(9,4,10);
tone(6,2,10);
tone(6,2,2);
tone(6,2,2);
tone(10,2,2);
tone(9,4,30);
tone(9,2,2);
tone(9,2,2);
tone(8,2,2);
tone(9,2,2);
tone(8,1,2);
tone(6,1,2);
tone(6,2,2);
tone(5,2,2);
tone(5,2,2);
tone(5,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,2,2);
tone(3,2,2);
tone(3,2,2);
tone(5,2,2);
//8
tone(5,2,2);
tone(6,2,10);
tone(10,2,2);
tone(9,4,10);
tone(6,2,10);
tone(6,2,2);
tone(6,2,2);
tone(10,2,2);
tone(9,4,30);
tone(9,2,2);
tone(9,2,2);
tone(8,2,2);
tone(9,2,2);
tone(8,1,2);
tone(6,1,2);
tone(6,1,2);
tone(3,1,2);
tone(5,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,2,2);
tone(5,2,2);
tone(6,4,10);
tone(3,1,2);
tone(5,1,2);
//9
tone(6,2,2);
tone(6,2,2);
tone(6,2,2);
tone(10,2,2);
tone(10,4,10);
tone(7,1,2);
tone(8,1,2);
tone(9,2,2);
tone(8,1,2);
tone(9,1,2);
tone(9,2,2);
tone(10,2,2);
tone(6,4,10);
tone(5,2,2);
tone(5,2,2);
tone(6,4,2);
tone(10,2,2);
tone(10,1,2);
tone(9,2,2);
tone(8,2,2);
tone(6,2,2);
tone(5,2,2);
tone(6,2,2);
tone(6,1,2);
tone(6,2,2);
tone(8,2,2);
tone(9,4,20);
//10
tone(6,2,2);
tone(6,1,2);
tone(6,1,2);
tone(6,2,2);
tone(5,1,2);
tone(5,1,2);
tone(6,2,2);
tone(10,2,10);
tone(8,2,2);
tone(9,2,2);
tone(8,1,2);
tone(9,1,2);
tone(9,2,2);
tone(10,2,2);
tone(10,4,10);
tone(5,2,2);
tone(6,2,2);
tone(8,2,10);
tone(5,2,2);
tone(6,2,2);
tone(10,2,10);
tone(10,1,2);
tone(9,1,2);
tone(8,2,2);
tone(7,2,2);
tone(6,2,2);
tone(5,2,2);
tone(5,2,2);
tone(6,4,10);
}
//11
tone(6,2,2);
tone(5,2,2);
tone(3,2,2);
tone(2,2,2);
tone(3,2,2);
tone(1,2,2);
tonel(5,2,2);
tonel(6,2,2);
tonel(5,2,2);
tonel(6,2,10);
tonel(6,4,20);
tonel(6,4,20);
tonel(7,4,00);
tonel(6,1,2);
tonel(7,1,2);
tonel(6,2,2);
tonel(6,1,2);
tonel(7,1,2);
tonel(6,2,2);
tone(1,4,20);
tonel(7,2,2);
tone(6,2,2);
tone(5,2,2);
tone(3,2,2);
tone(2,2,2);
tone(3,2,2);
tone(1,2,2);
tonel(5,2,2);
}
}