叮咚 产生的方式

仿真

程序代码
#include<reg51.h>
sbit key=P3^4;//设置一个按键的接口
sbit beep=P1^5;//设置门铃接口
#define CRYSTAL_FREQ 12000000 //晶振
#define INTERRUPT_PERIOD_0 4000//分频系数 1/4000s=250us
#define uchar unsigned char
#define uint unsigned int
uchar ding,dong,start,stop;
uint flag;
//
//
void delayms(uchar x)//按键消抖毫秒级延时
{
int i,j;
for(i=x;i>0;i--)
for(j=0;j<120;j++);
}
//https://blog.youkuaiyun.com/qq_43033547/article/details/89678078
//关于延时函数的一些说明
void Canshu_Init()
{
ding=0;
dong=0;
start=0;
stop=0;
flag=0;
}
//
//
void Interrupt_Init()//中断初始化,注意事先关闭定时器0所以TR0先没有赋1
{
TMOD = 0x01;
TH0 = (65536 - CRYSTAL_FREQ / 12 / INTERRUPT_PERIOD_0) / 256;
TL0 = (65536 - CRYSTAL_FREQ / 12 / INTERRUPT_PERIOD_0) % 256;
ET0 = 1;
EA = 1;
}
//
//
void main()
{
Canshu_Init();
Interrupt_Init();
while(1) //一直检测有没有按键按下
{
if(key==0)
{
delayms(5);
if(key==0)
{
TR0 = 1;//timer0 start
while(stop);//直到按键松开
}
}
}
}
//
//
void Timer0() interrupt 1//重点函数
{
TH0 = (65536 - CRYSTAL_FREQ / 12 / INTERRUPT_PERIOD_0) / 256;
TL0 = (65536 - CRYSTAL_FREQ / 12 / INTERRUPT_PERIOD_0) % 256;
flag++;//记录每一个250us
if(flag==2000)//0.5s get 函数1,切换叮咚
{
flag=0;
if(start==0) //
{
start=~start;
}
else
{
start=0;
stop=~stop;
TR0=0;//关闭定时器,等待下次按铃
}
}
if(start==0)// 函数2,检测到按键后ding响,0.5s后执行函数1,让start=1
{
ding++;
if(ding==3)
{
ding=0;
beep=~beep;
}
}
else // 函数3,start=1之后开始执行,执行完执行函数1
{
dong++;
if(dong==4)
{
dong=0;
beep=~beep;
}
}
}