一直下学习A51汇编语言,流水灯,数码管,独立按键基本上都可以写出来,而学习蜂鸣器,死活驱动不了无源蜂鸣器,今天看了51单片机版主C语言,用他的C语言下载进去蜂鸣器响了,自己照他的程序写汇编,很多方式不太会用,汇编与C应用不是很懂(开始学习过一点C),不会写的去掉了,只留下自己会写的,下载程序,有点响了,改变定时器的时间,蜂鸣器响了,感觉很高兴,附上51单片机版主的程序和我的汇编程序,请各位指点一二
#include<reg52.h>
sbit BUZZ = P1^0; //蜂鸣器控制引脚
unsigned char T0LoadH = 0; //T0重载值的高字节
unsigned char T0LoadL = 0; //T0重载值的低字节
void OpenBuzz(unsigned int frequ);
void StopBuzz();
void main()
{
unsigned int i=0;
TMOD = 0x01; //配置T0工作在模式1,暂不启动
EA = 1; //使能全局中断
while (1)
{
OpenBuzz(2000); //以4KHz的频率启动蜂鸣器
for (i=0; i<30000; i++);
StopBuzz();
for (i=0; i<30000; i++);
OpenBuzz(2000); //以1KHz的频率启动蜂鸣器
for (i=0; i<30000; i++);
StopBuzz();
for (i=0; i<30000; i++);
}
}
void OpenBuzz(unsigned int frequ)
{
unsigned int reload;
reload = 65536 - (11059200/12) / (frequ*2); //由给定频率值计算定时器重载值
T0LoadH = reload >> 8; //16位重载值分解为高低两个字节
T0LoadL = reload;
TH0 = 0xFF; //设定一个接近溢出的初值,以使定时器马上投入工作
TL0 = 0xFE;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
void StopBuzz()
{
ET0 = 0; //禁用T0中断
TR0 = 0; //停止T0
}
void InterruptTimer0() interrupt 1
{
TH0 = T0LoadH; //溢出后进入中断重新赋值
TL0 = T0LoadL;
BUZZ = ~BUZZ; //反转蜂鸣器控制电平
}
这个为51单片机版主的C,下面为我写的汇编,已下载HEX文件到开发板可以正常发声了(驱动无源蜂鸣器,蜂鸣器为P1.0)
BUZZ BIT P1.0
ORG 0000H
LJMP START
ORG 000BH ;定时器0入口
LJMP ZHONGDUAN;跳转到定时中断
START:
MOV TMOD ,#01H ; 使用定时器T0
SETB EA ;开启总中断
MAIN:
LCALL OPENBUZZ ;调用开启无源蜂鸣器
LCALL YS1 ;延时下
LCALL STOPBUZZ ;关闭蜂鸣器
LCALL YS1 ;延时下
LCALL OPENBUZZ ;再开启蜂鸣器
LCALL YS1 ;延时下
LCALL STOPBUZZ ;关闭蜂鸣器
LCALL YS1 ;再延时
LJMP MAIN ;如此循环
OPENBUZZ:
MOV TH0,#0FFH ;定时时间在65536-65350=186US
MOV TL0,#046H ;根据你蜂鸣器的频率不同,调节定时时间
SETB ET0 ;开启定时器中断
SETB TR0 ;开启定时器
RET
STOPBUZZ: CLR ET0 ;关闭定时器中断和关闭定时器,蜂鸣器将不会鸣叫
CLR TR0
RET
ZHONGDUAN: MOV TH0,#0FFH ;给T0的重现赋初值
MOV TL0,#046H
CPL BUZZ ;对蜂鸣器进行取反
RETI
YS1: MOV R7,#20 ;延时子程序,时间长可以更改R6或R5的值。
D1: MOV R6,#200
D2: MOV R5,#100
D3: DJNZ R5,D3
DJNZ R6,D2
DJNZ R7,D1
RET
END
|
加油