你现在位置:首页>技术论文>行业应用>其他>正文
单片机发声音入门
日期:2010-3-11 10:44:29 点击:
来源:本站整理
作者:
点击【】放大字体.

做个实际的项目,总有某些时候需要出点声音的,例如键盘按下后就要来个‘D’的声音,其实单片机发个声音是很简单的,IO,电阻,三极管,蜂鸣器,就可以了。这里以DX板上的发声系统为硬件基础:

WWW_PLC※JS_COM-PmLC-技.术_网

这个设计和普通的蜂鸣器有点不同,其实就是为了让P17可以免除干扰地复用作ISP口。平时P17为低电平,可以省电。

WW.W_PLCJS_COM-PLC-技.术_网

这里需要说明一下的,这些小小的两个脚的蜂鸣器,表面上个个一样,但实际上是分两种的,一种是通电就会响,另外一种是只能通过脉冲发声。通电响的那种用做普通发声设备,发出单纯的声音,简单方便。脉冲式的使用上没那么方便,但发出的各频率的声音都比较悦耳的。DX51学习板上用的就是脉冲式的了,所以平时P17是高是低,它都不会响。

P.L.C.技.术.网——可编程控制器技术门户

以下是DX学习板上的普通发声程序:
WWW_PL※CJS_COM-PLC-技.术_网

sbit BB=P1^7;

WW.W_PLCJS_COM-PLC-技.术_网

void beep(uchar t)
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户

{
WW.W_PLC※JS_C,OM-PL,C-技.术_网

uchar i;
W1WW_P4LCJS_COM-PLC-技.术_网

uint j;
WWW.PLCJS.COM——可编程控制器技术门户

for(j=0;j<t*256;j++)
WWW.PLCJS.COM——可编程控制器技术门户

{
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)

for(i=100;i>0;i--);//给i赋的初值决定输出的频率
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

BB=~BB;
WWW.PLCJS.COM——可编程控制器技术门户

}
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

}
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)

由于是脉冲形式的,所以发声就是通过一个取反BB=~BB;完成。上面的程序很简单,t决定了发声时间,i的初值决定了发声频率。频率是多少可以通过指令周期的计算得到,但个人觉得这类单声的东东,还是用耳朵听,多试几个频率值,方能找到我们最满意的频率:)

——可——编——程——控-制-器-技——术——门——户

如果要产生几个音调,可以写多几组不同时间长短和不同频率的代码,简单的我们从上面的代码修改:

WWW_P※LCJS_CO※M-PLC-技-.术_网

sbit BB=P1^7;
plcjs.技.术_网

void beep(uchar t)
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)

{
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)

uchar i;
WWcW_PLCJS_COM-PLC-技.术_网

uint j;
WWW.PLCJS.COM——可编程控制器技术门户

//第一声
——可——编——程——控-制-器-技——术——门——户

for(j=0;j<t*256;j++)
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户

{
WWW_PL※CJS_COM-PLC-技.术_网

for(i=100;i>0;i--);
WWW_PLC※JS_COM-PmLC-技.术_网

BB=~BB;
WWW_PLCJS_COM-PLC-技.术_网

}
WWW.PLCJS.COM——可编程控制器技术门户

WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

for(j=0;j<t*100;j++); 这个是两个声音之间的时间间隔
WWW_PLCJS_COM-PLC-技.术_网

WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)

//第二声
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)

for(j=0;j<t*200;j++)
P.L.C.技.术.网——可编程控制器技术门户

{
WW.W_PLCJS_COM-PLC-技.术_网

for(i=150;i>0;i--);
WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)

BB=~BB;
WWW_PLCJ-S_COM-PLC-技.术_网(可-编程控-制器技术-门户)

}
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)

plcjs.技.术_网

}
P.L.C.技.术.网——可编程控制器技术门户

程序很简单,就是发了一声后,延迟一定时间再发第二声.大家可以试着写段自己的代码,听听声音效果.

WWW_PLCJS@_COM%-PLC-技.术_网

但上面的程序是用延时发声的,当你要发出很长的声音的时候,延时部分就会占用了所有CPU资源,也就是在发声过程中我们什么都做不了,当然对于一般的响应声音,例如按键后发出声音,程序应付有余,但对于其它用途,这种方法就显得效率很低了。这里介绍一中用定时器的方法实现的声#include "reg51.h"

WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)

#define uchar unsigned char

WWW.PLCJS.COM——可编程控制器技术门户

sbit BB=P1^7; //蜂鸣器控制脚

WWW_P※LCJS_COM-PLC-)技.术_网

uchar beep_flag=0; //发声标志
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)

uchar count_time=0; //中断计数
WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)

void initTimer(void)

WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

{
WW.W_PLCJS_COM-PLC-技.术_网

TMOD=0x1;
WWcW_PLCJS_COM-PLC-技.术_网

TH0=0xe0;
WWcW_PLCJS_COM-PLC-技.术_网

TL0=0xc6;
WWW_PL※CJS_COM-PLC-技.术_网

}
W1WW_P4LCJS_COM-PLC-技.术_网

void timer0(void) interrupt 1

WWW.PLCJS.COM——可编程控制器技术门户

{
plcjs.技.术_网

TH0=0xe0;
WW.W_PLCJS_COM-PLC-技.术_网

TL0=0xc6;
WWW_P※LCJS_CO※M-PLC-技-.术_网

if(!beep_flag)
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户

{
P_L_C_技_术_网——可——编——程——控-制-器-技——术——门——户

count_time=0;
WWW_PLC※JS_COM-PmLC-技.术_网

}
WWW_PL※CJS_COM-PLC-技.术_网

else
W1WW_P4LCJS_COM-PLC-技.术_网

{
WW.W_PLC※JS_C,OM-PL,C-技.术_网

count_time++;
WWW_P※LCJS_CO※M-PLC-技-.术_网

BB=~BB;
plcjs.技.术_网

if(count_time>70)
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)

{
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

count_time=0;
WW.W_PLC※JS_C,OM-PL,C-技.术_网

beep_flag=0;
WWW_PLC※JS_COM-PmLC-技.术_网

}
WWW_PLCJS_COM-PLC-技.术_网

}

WW.W_PLC※JS_C,OM-PL,C-技.术_网

}

WWW_PLC※JS_COM-PmLC-技.术_网

 
WWW_PLC※JS_COM-PLC-技.术_网(可编程控※制器技术门户)

void main(void)

WWW※PLCJS_COM-PL#C-技.术_网(可编※程控※制器技术门户)

{
WW.W_PLCJS_COM-PLC-技.术_网

initTimer();
W1WW_P4LCJS_COM-PLC-技.术_网

TR0=1;
WW.W_PLCJS_COM-PLC-技.术_网

ET0=1;
P.L.C.技.术.网——可编程控制器技术门户

EA=1;
W1WW_P4LCJS_COM-PLC-技.术_网

beep_flag=1;
WWW_PLCJS※COM-PLC-技×术_网(可编程控※制器技术门户)

while(1);
WWW_PLCJS※COM-PLC-技.术_网(可※编程控※制器技术门户)

}
WWcW_PLCJS_COM-PLC-技.术_网

 
plcjs.技.术_网

WWcW_PLCJS_COM-PLC-技.术_网

——可——编——程——控-制-器-技——术——门——户

上面程序有着大家已经熟悉的count_time变量,其实它就是用来控制发声时间长短的,而定时时间(取决于TH,TL)就是用来产生频率的。可能初学者第一次看这样的程序有一点点迷惑也说不定,但只要用心去想想,几分钟后大家就能明白。说透了,定时器中断函数是会不断地执行的,但对于函数中的BB=~BB;这一句,就只会在 beep_flag=1;之后运行一段时间——这段时间取决于count_time 要计时多长,count_time>70后就计算完,此时清除beep_flag=0;那么count_time++; BB=~BB;就不会再运行了。
WW.W_PLCJS_COM-PLC-技.术_网

评论内容
载入中...
载入中...
P
L
C



|










|


P
L
C









·最新招聘信息
·最新求职信息
·推荐产品
·推荐厂商
·栏目热门排行
·站内热门排行