单片机学习(四)蜂鸣器和独立按键的使用

阅读: 评论:0

单⽚机学习(四)蜂鸣器和独⽴按键的使⽤
⽬录
蜂鸣器
两种蜂鸣器的介绍
有源蜂鸣器⼀般是输⼊⼀个电流或电压即可直接驱动⼯作,⽽⽆源蜂鸣器则需要输⼊脉冲信号才可以进⾏⼯作。在51单⽚机开发板上的即为⽆源蜂鸣器。
蜂鸣器相关电路图
可以看出,信号是通过P15传递到ULN2003D芯⽚后进⽽传递到芯⽚的OUT5(即BEEP端⼝)再传递到蜂鸣器中的,其中ULN2003D芯⽚起着电流放⼤的作⽤。
控制代码
⾸先我们先获得控制蜂鸣器的引脚,从电路图可以看出是P15,所以:
sbit BEEP= P1^5;
因为这是⽆源蜂鸣器,所以我们需要给它提供脉冲信号输⼊才能使它⼯作。⽽当BEEP为0时有电流,BEEP为1时⽆电流,所以我们需要循环改变BEEP的值,主函数代码如下所⽰:
int main() {
while (1)
{
BEEP = ~BEEP;
deley(10);
}
}
如果我们希望改变蜂鸣器的⾳调,只需要改变脉冲信号的频率即可,也就是while循环中deley()的参数。
我们也可以不断改变deley()中填⼊的参数来使蜂鸣器发出奇怪的声⾳ :
int main() {
u16 time = 10;
u8 cnts = 50;
u8 i;
for(time=10;time<200;time++) {
for(i=0;i<cnts;i++) {
BEEP = ~BEEP;
deley(time);
}
}
}
独⽴按键
独⽴按键电路图
可以看到,这4个独⽴按键都是⼀端和单⽚机的引脚(P3[0..3])相连,⽽另⼀端直接接地的。
这些按键的效果是,当按键没有按下时,它们对应的端⼝的输出是⾼电平,⽽当按键按下之后,这些端⼝的输出则变为低电平了。
因此我们可以使⽤轮询的⽅式查看这些端⼝的电平情况来检测按钮是否被按下,如果按下,则我们可以进⾏计数等控制其他元件的操作。
按键控制⼀个LED的点亮和熄灭
我们希望当点击按键时,第⼀个LED点亮,⽽在此单击时则熄灭。
精炼剂按照之前的思路,我们很容易就能写出对应的控制代码:
sbit OneLED = P2^0; // 使⽤OneLED来控制对应的引脚的输出
sbit k1 = P3^1;
void keypros() {
if (k1 == 0) {
deley(1000); // 消抖
if (k1 == 0) {
OneLED = ~OneLED;
}
while (!k1);
}
}
int main() {
while (1) {
keypros();
}
}
重要的是keypros()函数中的内容,当我们点击第⼀个按钮时,k1的值会变为0,因此我们进⾏轮询的时候就会进⼊到keypros()函数的第⼀个if中。然后进
⾏deley(1000);是为了进⾏消抖处理。然后再次查看k1是否为0,若不为0则说明此次按动是⾮法的(即可能是抖动产⽣的),⽽如果为0则进⼊切换LED状态的代码。然后使⽤while (!k1);来等待抬⼿,若没有这句话,则此次函数调⽤结束后我们的⼿还没有抬起来⼜再次进⼊函数了,会导致灯光不断亮灭变换,和我们希望的不符,所以使⽤这个循环语句进⾏等待抬⼿再次轮询。
运⾏效果:
设置控制框架
可以看出,我们的按键控制其他硬件的框架已经搭好了,以后我们需要控制其他元件时就只需要将keypros()函数中的OneLED = ~OneLED;这个部分切换为其他的控制代码即可。但是直接切换⼜会显得⾮常的⿇烦,因此我们使⽤C语⾔的⼀个好⽤的东西函数指针来完成这项功能。
其实回调函数这种东西是⾮常常见的,特别是在JavaScript这个语⾔中被⼤量地使⽤,在JavaScript中函数是⼀等公民,可以随便作为参数进⾏传递,⽽在C语⾔可以通过函数指针将⼀个函数作为另⼀个函数的参数进⾏传递,例如:
typedef void (*CallBack)();
int getRunTime(CallBack function) {
clock_t startTime = clock();
function();
clock_t endTime = clock();
return endTime - startTime;
}
这⾥定义了⼀个回调函数指针类型CallBack,其指向的函数⽆参数⽆返回值。然后我们可以将⼀个函数指针作为参数传递到getRunTime()函数中,这样运⾏结束后我们即可获得传递进去的函数的运⾏时间是多少了,例如:
void countFunc() {
for (int i = 0; i < 10000000; ++i) {}
局部镀锡}
int main() {
int runTime = getRunTime(countFunc); <--将函数指针传递进去,相当于回调函数
cout << "runTime: " << runTime << "ms" << endl;
}
所以我们使keypros()函数接收⼀个函数指针,然后将OneLED = ~OneLED;替换为传⼊的函数:
typedef void (*CallBack)(void);
void keypros(CallBack function) {
if (k1 == 0) {
deley(1000);
if (k1 == 0) {
function();
}
while (!k1);
}
}
这样,我们写⼀个切换LED状态的函数:
void switchLED() {
OneLED = ~OneLED;
}
然后我们在主函数中将它传递到keypros()函数中:
int main() {
while (1) {
keypros(switchLED);
实木花盆
}
}
即我们希望在单击按钮后发⽣什么事件,就将这个事件的函数传递到keypros()中即可,这样按钮控制事件的框架就搭好了。
按钮点击计数器
既然框架已经搭好,我们继续编写事件函数即可。
大微动开关此时事件为计数器+1并显⽰出来。
u8 code smgduan[16] = {
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
u8 addOneDigitCnt = 1;
灌浆剂
void addOneDigit() {
P0 = smgduan[addOneDigitCnt];
addOneDigitCnt++;
if (addOneDigitCnt == 16) {
addOneDigitCnt = 0;
}
}
int main() {
P0 = smgduan[0];
while (1) {
keypros(addOneDigit);
}
}
运⾏效果:
按钮点击流⽔灯
我们点击按钮是LED灯向前传递⼀格。
代码:
void LEDMove() {
LED <<= 1;
if (LED != 0xfe) {
原油脱硫剂LED += 1;
}
}
int main() {
LED = 0xfe;
while (1) {
keypros(LEDMove);
}
}
运⾏效果:

本文发布于:2023-06-04 17:26:57,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/4/126073.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   蜂鸣器   控制
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图