51单片机学习笔记

您所在的位置:网站首页 门铃开门原理 51单片机学习笔记

51单片机学习笔记

2024-07-09 06:50| 来源: 网络整理| 查看: 265

文中绝大数代码来自普51开发板实验例程

门铃这个实验实际上就是按键和蜂鸣器的组合实验,没啥难度,唯一的用处就是为下一个实验(音乐播放器)做铺垫。

文章目录 门铃实现原理扩展,调节“叮咚”实验例程完整源码改进版完整代码(修改叮咚频率)

门铃实现原理

门铃实验核心代码在定时器中断函数中,当主函数检测到按键K1按下,则打开定时器0,定时器周期为250us,所以“叮”的周期就是250us;当定时器第2000次触发中断,也就是0.5秒时,flag被更新为1,蜂鸣器开始“咚”状态,“咚”的周期为定时器溢出中断周期的两倍,即500us;“咚”状态持续0.5后,定时器自己关闭,完成响铃的操作。

定时器中断服务函数,完整源码见文末。

void time0() interrupt 1 { n++; TH0=0Xff; TL0=0X06; //250us if(n==2000) //定时0.5s 叮响0.5秒,咚响0.5秒 { n=0; if(flag==0) { flag=~flag; } else { flag=0; stop=1; TR0=0; //关闭定时器0 } } if(flag==0) { //通过改变定时计数时间可以改变门铃的声音 ding++; //叮 if(ding==1) { ding=0; beep=~beep; } } else { dong++; if(dong==2) //咚 { dong=0; beep=~beep; } } }

分析完例程源码,我迫不及待地将程序烧写到开发板—— 卧槽,声音和我想象的不太一样。一直按着按键K1,我仿佛听到了救护车从身边经过。。。

扩展,调节“叮咚”

既然都开始学了,那这个“叮咚”是肯定得弄出来的,差点忘了,我还不知道怎么设置定时器的定时周期,例程中定时器采用了方式1,我也沿用他的设定吧。

在这里插入图片描述

直接把普中的开发攻略关于时间设定的介绍拷过来(好像我之前第一天学习时过了一遍,但一点都不记得了,。。罪过。。)

51 单片机内部时钟频率是外部 时钟的 12 分频,也就是说当外部晶振的频率输入到单片机里面的时候要进行 12 分频。比如说你用的是 12MHZ 晶振,那么单片机内部的时钟频率就是 12/12MHZ, 当你使用 12MHZ 的外部晶振的时候,机器周期=1/1M=1us。如果我们想定时 1ms的初值是多少呢?1ms/1us=1000。也就是要计数 1000 个,初值=65535-1000+1 (因为实际上计数器计数到 66636(2 的 16 次方)才溢出,所以后面要加 1) =64536=FC18H,所以初值即为 THx=0XFC,TLx=0X18。

现在可以开始考虑时间到底该设置为多少了,网上查到:叮的声音频率大约为1230Hz,咚的频率为680Hz,换成周期,叮的周期约为813us,咚的周期约为1470us,而例程中分别为250和500,显然不合适,怎么办?改~!

考虑到叮和咚的周期(频率)没有合适的公因数,一个0定时器实现813us和1470us两种周期有些困难,所以我觉得再开一个定时器(timer1)。

定时器0用来控制叮的频率,周期为65535-813+1=64,723=FCD3H(TH0=0XFC,TL0=0XD3) 定时器1用来控制咚的频率,周期为65535-1470+1=64,066=FA42H(TH1=0XFA,TL1=0X42) 叮和咚除了频率不同,持续时间也不同,叮要比咚短,那就设叮为0.5s,咚为1s。

核心代码为两个定时器中断函数:按键按下后,先打开定时器0,蜂鸣器以813us的周期进行高低切换(发出响声),持续时间813 x 615 约等于 500000us,0.5s过后,关闭定时器0,开启定时器1;此时蜂鸣器以1470us的周期进行高低切换,持续时间约1s,最后关闭定时器1,并设置stop=0(main函数卡在while(!stop);中)。

void time0() interrupt 1 { n++; TH0 = 0XFC; TL0 = 0XD3; //定时813us if(n == 615) //定时0.5s 叮 { n = 0; TR0 = 0; //关闭定时器0 TR1 = 1; //开启定时器1 } beep = ~beep; //叮 } void time1() interrupt 3 { m++; TH1 = 0XFA; TL1 = 0X42; //定时1470us if(m == 680) //定时1s { m = 0; TR1 = 0; //关闭定时器1 stop = 1; } beep = ~beep; //咚 }

烧录进单片机,终于,听起来有那味了——不过有点粗糙,能加上点渐变就更好了。

实验例程完整源码 /* 实验说明: 实验接线: 蜂鸣器模块-->单片机管脚 参考蜂鸣器实验接线(开发攻略内在对应的实验章节内实验现象有接线说明) BEEP-->P15 独立按键模块-->单片机管脚 K1-->P31 实验现象: 按下K1键,蜂鸣器发出”叮咚”门铃声 */ #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit beep=P1^5; sbit k1=P3^1; u8 ding,dong,flag,stop; u16 n; void delay(u16 i) { while(i--); } void time0init() //定时器0初始化 { TMOD=0X01; //定时器0 方式1 TH0=0Xff; TL0=0X06; //定时250us // TR0=1; EA=1; ET0=1; } void biaohaoinit() //各个标号初始化 { ding=0; //叮声音 计数标志 dong=0; //咚声音 计数标志 n=0; //定时0.5s标志 flag=0; stop=0; //结束标志 } void main() { time0init(); biaohaoinit(); while(1) { if(k1==0) //判断按键是否按下 { delay(1000); //消抖 if(k1==0) { TR0=1; //打开定时器0 while(!stop); } } } } void time0() interrupt 1 { n++; TH0=0Xff; TL0=0X06; //250us if(n==2000) //定时0.5s 叮响0.5秒,咚响0.5秒 { n=0; if(flag==0) { flag=~flag; } else { flag=0; stop=1; TR0=0; //关闭定时器0 } } if(flag==0) { //通过改变定时计数时间可以改变门铃的声音 ding++; //叮 if(ding==1) { ding=0; beep=~beep; } } else { dong++; if(dong==2) //咚 { dong=0; beep=~beep; } } } 改进版完整代码(修改叮咚频率) /* 实验说明: 实验接线: 蜂鸣器模块-->单片机管脚 参考蜂鸣器实验接线(开发攻略内在对应的实验章节内实验现象有接线说明) BEEP-->P15 独立按键模块-->单片机管脚 K1-->P31 实验现象: 按下K1键,蜂鸣器发出”叮咚”门铃声 */ #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit beep=P1^5; sbit k1=P3^1; u8 stop; u16 n; //叮持续时间(单位为一个定时器计数溢出的周期) u16 m; //咚持续时间 void delay(u16 i) { while(i--); } void time0init() //定时器0初始化 { TMOD|=0X01; //定时器0 方式1 TH0=0XFC; TL0=0XD3; //定时813us // TR0=1; EA=1; ET0=1; } void time1init() //定时器1初始化 { TMOD|=0X10; //定时器1 方式1 TH1=0XFA; TL1=0X42; //定时1470us // TR1=1; EA=1; ET1=1; } void biaohaoinit() //各个标号初始化 { // ding=0; //叮声音 计数标志 // dong=0; //咚声音 计数标志 n=0; //定时0.5s标志 stop=0; //结束标志 m = 0; //定时1s标志 } void main() { time0init(); time1init(); //定时器1初始化 biaohaoinit(); while(1) { if(k1==0) //判断按键是否按下 { delay(1000); //消抖 if(k1==0) { TR0=1; //打开定时器0 while(!stop); } } } } void time0() interrupt 1 { n++; TH0 = 0XFC; TL0 = 0XD3; //定时813us if(n == 615) //定时0.5s 叮 { n = 0; TR0 = 0; //关闭定时器0 TR1 = 1; //开启定时器1 } beep = ~beep; //叮 } void time1() interrupt 3 { m++; TH1 = 0XFA; TL1 = 0X42; //定时1470us if(m == 680) //定时1s { m = 0; TR1 = 0; //关闭定时器1 stop = 1; } beep = ~beep; //咚 }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3