学习笔记|认识蜂鸣器|控制原理|电磁炉LED实战|逻辑运算|STC32G单片机视频开发教程(冲哥)|第八集(上):蜂鸣器应用

news2025/1/16 13:51:43

文章目录

  • 1.认识蜂鸣器
    • 区别
  • 2.控制原理
    • 实现蜂鸣器控制原理
  • 3.蜂鸣器实战应用
    • 需求分析
    • 代码编写
      • 步骤一代码编写及分析
      • test.h的固定模板
      • Tips:提示:“test\test.c(14): error C16: unprintable character 0xA3 skipped
      • Tips:“test\test.c(14): warning C137: constant in condition expression”
    • 实现主要代码
      • 步骤二:关机代码编写及分析
      • 步骤三:状态选择按键代码编写及分析
    • 实现完整功能的test.c代码
    • Tips:C语言的逻辑运算符
  • 总结
  • 课后练习

1.认识蜂鸣器

反面包上黑胶的是有源蜂鸣器。
在这里插入图片描述
在背面裸露的一块线路板的是无源蜂鸣器。
在这里插入图片描述
YX55675-无源蜂鸣器模块的资料
提取码:nl73

区别

1、有源蜂鸣器内部带震荡源,所以只要一通电就会叫(一边高电平,一边低电平),而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫(必须不断给高低电平)。
2、价格不同,有源蜂鸣器要比无源蜂鸣器贵,贵在里面多了震荡源。有源容易控制。播放音乐无源的更好。
围绕这个有源蜂鸣器展开我们的实验。

2.控制原理

原理图:
在这里插入图片描述
三极管基极如果是低电平,则SS8550发射至集电极导通,接BEEP1正极,BEEP1负极接地。
C35电容起到简单滤波作用。
P54引脚给高电平关闭
P54引脚给低电平打开
这里我们尝试自己动手写一段,结合上一节课的按钮点灯,这里要实现:按钮按一下打开蜂鸣器,按钮按一下关闭蜂鸣器的程序!(先自己尝试一下,再来看看我写的!)

实现蜂鸣器控制原理

需要背诵的按键单触发代码:

		if (KEY1 == 0)
		{
			delay_ms(10);
			if (KEY1 == 0)
			{
				while(KEY1 == 0);
				BEEP = !BEEP;
			}

		}

3.蜂鸣器实战应用

实物图:
在这里插入图片描述

需求分析

本节选择控制8个LED(LED1~LED8)和KEY1(开关),KEY2按键(功能选择)。
按键2,LED8,蜂鸣器*1
1、按键1按下,蜂鸣10ms,开始自检,
LED1-8全部点亮200ms在熄灭,表示开机。
2.开机后,按键2按下,蜂鸣10ms,LED1-8轮流点亮,表示切换煲汤、烧水等功能。
3.开机后按键1再次按下,蜂鸣10ms,LED全部熄灭,表示关机。

代码编写

步骤一代码编写及分析

先在项目文件夹下新建test子目录,在目录中新建test.c和test.h。
将test.c加入工程:
在这里插入图片描述
在这里插入图片描述

test.h的固定模板

#ifndef	__TEST_H   //判断是否有test.h
#define __TEST_H


#include "COMM/stc.h"  //调用头文件
#include "COMM/usb.h"




#endif

test.c加入test.h的引用,test.c文件添加进入工程,添加include文件引用路径:

将define文件移至test.h,通过之前添加的include,其他文件都可以访问到该预定义。

之后写需求功能。
第一步,编写状态变量及test函数:

#include "test.h"

bit  Run_Flag = 0; //0-1开关机变量
u8   Run_Mode = 0; //0-8 模式几 0:没有模式

void Test(void)   //电磁炉的功能
{
		if (KEY1 == 0)   //开关机键
		{
			delay_ms(10);
			if (KEY1 == 0)
			{
				while(KEY1 == 0);	//按钮按下,并等待按钮松开
				if (Run_Flag = 0)  //表示还没有开机
				{
					Run_Flag = 1;   //开机变量改为1,表示已经开机
					BEEP = 0;		//打开蜂鸣
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					P40 = 0;		//打开了LED总电源
					P6 = 0X00;		//全部点亮
					delay_ms(200);   //延迟200ms
					P6 = 0XFF; 		//全部关闭
				}
			}

		}
}

头文件中需要包含函数的声明,如:

void delay_ms(u16 ms);
void Test(void);

开始编译,提示“test\test.c(10): warning C140: ‘delay_ms’ undefined; assuming ‘extern int delay_ms()’”:
原因是delay_ms未在test.h中定义,需要先移动过来,如果仅复制,则会提示以下错误:
在这里插入图片描述

Tips:提示:“test\test.c(14): error C16: unprintable character 0xA3 skipped

test\test.c(14): error C16: unprintable character 0xA9 skipped”
这是因为:keil里面出现了中文输入法时写的标点,例如: //lcm_w_word(“abc您好”); 不能出现全角的任何字符,包括空格在内任何标点符号和空格都只能在英文的状态下输入,提示这个错误的话
把全角的字符或者标点替换一下即可,但是正常情况是看不到的,你只有加入了//才能发现的

Tips:“test\test.c(14): warning C137: constant in condition expression”

在if()里面不应该使用=,而应该使用==,使用=就相当于变量赋值一个常量了,所以编译器提示告警。接下来如果有else if,会接着提示:“warning C294: unreachable code”(本例无else if,故未出现。)

实现主要代码

main.c中增加Test函数:

    while(1) //死循环
    {
		if( DeviceState != DEVSTATE_CONFIGURED ) 	//判断USB是否连接成功,最新版usb.h中该有定义
			continue;
		if( bUsbOutReady )    //判断有没有接收到数据
		{
			usb_OUT_done(); //接收应答(固定格式)
		}
		Test();
	}

test.h中定义:

#ifndef	__TEST_H   //判断是否有test.h
#define __TEST_H


#include "COMM/stc.h"  //调用头文件
#include "COMM/usb.h"

#define MAIN_Fosc 24000000UL

#define KEY1 P32
#define KEY2 P33

#define BEEP P54  //定义一个BEEP控制引脚

void delay_ms(u16 ms);
void Test(void);


#endif

test.c中实现第一步功能中自定义变量及函数的代码:

#include "test.h"

bit  Run_Flag = 0; //0-1开关机变量
u8   Run_Mode = 0; //0-8 模式几 0:没有模式

void Test(void)   //电磁炉的功能
{
		if (KEY1 == 0)   //开关机键,第一步骤代码段
		{
			delay_ms(10);
			if (KEY1 == 0)
			{
				//while(KEY1 == 0);	//按钮按下,并等待按钮松开
				if (Run_Flag == 0)  //表示还没有开机
				{
					Run_Flag = 1;   //开机变量改为1,表示已经开机
					BEEP = 0;		//打开蜂鸣
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					P40 = 0;		//打开了LED总电源
					P2 = 0X00;		//全部点亮
					delay_ms(300);   //延迟200ms
					P2 = 0XFF; 		//全部关闭
				}
			}

		}
}

void delay_ms(u16 ms)	//unsigned int
{
	u16 i;
	do
	{
		i = MAIN_Fosc/6000;
		while(--i);
	}while(--ms);
}

执行完代码后,蜂鸣响1声,8个状态等全亮后关闭,之后再按其他按键无响应,待补充后续功能代码。

步骤二:关机代码编写及分析

开机后按键1再次按下,蜂鸣10ms,LED全部熄灭,P40总电源指示灯熄灭,表示关机。
基础的功能状态都是key1按下,根据开机变量的不同,选择不同的执行代码。

				else
				{
					Run_Flag = 0;   //已关机
					BEEP = 0;		//打开蜂鸣(提醒)
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					P2 = 0XFF;		//状态指示全部关闭
					P40 = 1;		//关闭总电源LED
				}

步骤三:状态选择按键代码编写及分析

开机后,按键2按下,蜂鸣10ms,LED1-8轮流点亮,表示切换煲汤、烧水等功能。
实现代码:

/*=======================按下按键2,执行本段代码=====================*/
		if (KEY2 == 0)   //开关机键
		{
			delay_ms(10);  //防抖
			if (KEY2 == 0)
			{
				while(KEY2 == 0);	//等待按键松开,将要执行
/*=======================还没有开机的情况下,执行本段代码=====================*/
				if (Run_Flag == 0)  //表示还没有开机
				{
					BEEP = 0;		//打开蜂鸣
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					Run_Mode++;		//每次按下,模式+1(移至下一个led)
					if (Run_Mode > 8)  //如果模式大于8,回到模式1
						Run_Mode = 1;  //Run_Mode超过8后清零,回到第一个灯

					P2 = ~(1<< (Run_Mode - 1));	//最先想到的“1<< Run_Mode”是错误写法,执行结果是8个灯中每次移动仅1个不亮。
												//灯是低电平点亮,1<< Run_Mode,即1<<1,左移以后为0000 0010,仅1个LED灭,继续左移,尾部补0,还是只有1个LED灭
												//解决方法:RunMode先减1,再左移,最后全部取反。这里用~为全取反。而!是位取反。
												//P2 = 0XFX;  P6<< 1 + 1;  也可以实现
				}

实现完整功能的test.c代码

执行时发现第一次按键时,如果是开机状态,0位灯不亮,则需要在关机代码中加入Run_Mode = 0; //模式清零。
实现完整功能的test.c代码如下:

#include "test.h"

bit  Run_Flag = 0; //0-1开关机变量
u8   Run_Mode = 0; //0-8 模式几 0:没有模式

void Test(void)   //电磁炉的功能
{
		if (KEY1 == 0)   //开关机键
		{
			delay_ms(1000);  //长按1s开机
			if (KEY1 == 0)
			{
				//while(KEY1 == 0);	//按钮按下,并等待按钮松开
/*=======================还没有开机的情况下,执行本段代码=====================*/
				if (Run_Flag == 0)  //表示还没有开机
				{
					Run_Flag = 1;   //开机变量改为1,表示已经开机
					BEEP = 0;		//打开蜂鸣
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					P40 = 0;		//打开了LED总电源
					P2 = 0X00;		//全部点亮
					delay_ms(300);   //延迟200ms
					P2 = 0XFF; 		//全部关闭
				}
/*=======================已经开机的状态下,执行关机操作=====================*/
				else
				{
					Run_Flag = 0;   //标记已关机
					BEEP = 0;		//打开蜂鸣(提醒)
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					P2 = 0XFF;		//状态指示全部关闭
					P40 = 1;		//关闭总电源LED
					Run_Mode = 0;   //模式清零
				}
			}

		}
/*=======================按下按键2,执行本段代码=====================*/
		if (KEY2 == 0)   //状态选择键被按下
		{
			delay_ms(10);  //防抖
			if (KEY2 == 0)
			{
				while(KEY2 == 0);	//等待按键松开,将要执行
				{
					BEEP = 0;		//打开蜂鸣
					delay_ms(10);   //延迟10ms
					BEEP = 1;		//关闭蜂鸣
					Run_Mode++;		//每次按下,模式+1(移至下一个led)
					if (Run_Mode > 8)  //如果模式大于8,回到模式1
						Run_Mode = 1;  //Run_Mode超过8后清零,回到第一个灯
					P2 = ~(1<< (Run_Mode - 1));	//错误写法,执行结果是8个灯中仅1个不亮
												//灯是低电平点亮,1<< Run_Mode,即1<<1,左移以后为0000 0010,仅1个LED灭,继续左移,尾部补0,还是只有1个LED灭
												//解决方法:RunMode先减1,再左移,最后全部取反。这里用~为全取反。而!是位取反。
												//P2 = 0XFX;  P6<< 1 + 1;  也可以实现
				}

			}

		}
}

void delay_ms(u16 ms)	//unsigned int
{
	u16 i;
	do
	{
		i = MAIN_Fosc/6000;
		while(--i);
	}while(--ms);
}

Tips:C语言的逻辑运算符

一、与运算 &&
与运算需要使用关键字符&&,表示将两个或者多个表达式连接成一个,所有表达式必须都为TRUE,整个表达式才为TRUE,否则为false。
二、或运算 ||
或运算需要使用关键字符||,表示将两个或者多个表达式连接成一个,任意一个表达式为TRUE,整个表达式就为TRUE;只有当所有表达为false的时候,整个表达式才为false。
三、非运算 !
非运算需要使用关键字符!,用于将单个表达式结果取反。
如果原表达式的结果为false,在表达式前面加上运算符!结果取反之后就是TRUE;如果原计算结果是TRUE,在表达式前面加上运算符!结果取反之后就是false。

总结

1.了解蜂鸣器怎么使用
2.尝试去使用蜂鸣器

课后练习

增加按键3,按下后表示启动,选择的对应的功能的LED持续闪烁,表示正在工作,且在工作的时候无法切换功能。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/914645.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql with as定义子查询

文章目录 1. 定义2. 适用场景3. 语法4. 示例 1. 定义 使用with as 可以让子查询重用相同的with查询块&#xff0c; 并在select查询块中直接引用&#xff0c; 一般用在select查询块会多次使用某个查询sql时&#xff0c; 会把这个sql语句放在with as 中&#xff0c; 作为公用的表…

使用威胁搜寻增加网络安全

什么是威胁搜寻 威胁搜寻&#xff08;也称为网络威胁搜寻&#xff09;是一种主动网络安全方法&#xff0c;涉及主动搜索隐藏的威胁&#xff0c;例如组织网络或系统内的高级持续性威胁和入侵指标。威胁搜寻的主要目标是检测和隔离可能绕过网络外围防御的威胁&#xff0c;使管理…

代码随想录算法训练营第四十二天 | 01背包问题,01背包问题(滚动数组),416. 分割等和子集

代码随想录算法训练营第四十二天 01背包问题01 背包二维dp数组01背包 01背包问题(滚动数组)416. 分割等和子集 01背包问题 视频讲解 以下是几种背包&#xff0c;如下&#xff1a; 至于背包九讲其其他背包&#xff0c;面试几乎不会问&#xff0c;都是竞赛级别的了&#xff0c;…

Ribbon:自定义负载均衡

自定义负载均衡算法 package com.kuang.myconfig;import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server;import java.util.…

Java网络编程(二)NIO和Netty实现多人聊天功能

NIO实现 服务端 package com.bierce.io; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; //服务器端 publ…

基于Python科研论文绘制学习 - task2

Matplotlib 1、subplot&#xff08;&#xff09; matplotlib.pyplot模块提供了一个 subplot() 函数&#xff0c;它可以均等地划分画布&#xff0c;该函数的参数格式如下&#xff1a; plt.subplot(nrows, ncols, index) nrows 与 ncols 表示要划分几行几列的子区域&#xff0…

Jmeter性能 —— 事务控制器

统计性能测试结果一定会关注TPS&#xff0c;TPS表示&#xff1a;每秒处理事务数&#xff0c;JMeter默认每个事务对应一个请求。我们可以用逻辑控制器中的事务控制器将多个请求统计为一个事务。 1、添加事务控制器 2、事务控制器参数说明 Generate parent sample&#xff1a;如…

Spring Framework

文章目录 一 Spring Framework简介 1.1 Spring Framework系统架构 1.2 对spring的理解 1.3 设计理念 二 核心 1. IoC 容器 1.1. Spring IoC容器和Bean简介 1.2. 容器概述 1.2.1. 配置元数据 1.2.2. 实例化一个容器 构建基于XML的配置元数据 Groovy Bean Definitio…

传递函数零极点对系统的影响

传递函数的零点和极点分别对系统的影响的详细介绍&#xff1a; 零点&#xff08;Zero&#xff09;的影响&#xff1a;传递函数的零点是使得传递函数的分子为零的点。零点对系统的频率响应和稳定性产生影响。具体而言&#xff1a; 频率响应&#xff1a;零点的位置会影响系统在不…

Linux常用配置(持续记录)

写在前面&#xff1a;学的东西太多&#xff0c;一个健忘的程序猿&#xff0c;只记得那啥那啥&#xff0c;这东西好像是这个&#xff0c;哎&#xff0c;又忘了。现在就记在这个小本本上&#xff0c;方便日后来回顾。 全局配置host 命令&#xff1a; vim /etc/hosts 作用&#…

使用EventLog Analyzer 进行路由器监控

路由器是任何计算机网络的构建块&#xff0c;引导网络中的流量&#xff0c;管理员需要确保路由器已配置并正常工作&#xff0c;以确保网络安全。 监控路由器中的用户活动 在网络安全方面&#xff0c;与路由器相关的风险是一个严重的问题。具有松散安全策略的网络使入侵者可以…

PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码

文章目录 1&#xff1a;PCI9054的FPGA侧&#xff08;local侧引脚定义&#xff09;2&#xff1a;PCI9054的C模式下的读写时序3&#xff1a;FPGA代码部分具体代码&#xff1a; 1&#xff1a;PCI9054的FPGA侧&#xff08;local侧引脚定义&#xff09; 而PCI9054的本地总线端的主要…

基于Googlenet深度学习网络的交通工具种类识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ....................................................................................% 获…

PHP反序列化 字符串逃逸

前言 最近在打西电的新生赛&#xff0c;有道反序列化的题卡了很久&#xff0c;今天在NSS上刷题的时候突然想到做法&#xff0c;就是利用字符串逃逸去改变题目锁死的值&#xff0c;从而实现绕过 为了研究反序列化的字符串逃逸 我们先简单的测试下 原理 <?php class escape…

大数据——一文熟悉HBase

1、HBase是什么 HBase是基于HDFS的数据存储&#xff0c;它建立在HDFS文件系统上面&#xff0c;利用了HDFS的容错能力&#xff0c;内部还有哈希表并利用索引&#xff0c;可以快速对HDFS上的数据进行随时读写功能。 Hadoop在已经有一个HiveMapReduce结构的数据读写功能&#x…

Apollo自动驾驶:引领未来的智能出行

自动驾驶技术正日益成为当今科技领域的焦点&#xff0c;它代表着未来出行的一大趋势&#xff0c;而Baidu公司推出的Apollo自动驾驶平台则在这一领域中展现出强大的领导地位。本文将深入探讨Apollo自动驾驶技术的关键特点、挑战以及它对未来智能出行的影响。 Apollo自动驾驶平台…

QT基础教程之二 第一个Qt小程序

QT基础教程之二 第一个Qt小程序 按钮的创建 在Qt程序中&#xff0c;最常用的控件之一就是按钮了&#xff0c;首先我们来看下如何创建一个按钮 QPushButton * btn new QPushButton; 头文件 #include <QPushButton>//设置父亲btn->setParent(this);//设置文字btn-&g…

C++进阶 多线程相关

本篇博客介绍&#xff1a; 主要介绍C中的一些线程操作以及线程库 C进阶 多线程相关 为什么要有线程库线程库介绍线程库常见的接口构造线程对象获取线程idjoin和deteach mutex库原子操作相关条件变量库总结 为什么要有线程库 我们在Linux中写多线程的时候使用的是Linux下提供的…

Windows使用MobaXterm远程访问ubuntu20.04桌面

参考ubuntu 2020.4 安装vnc 一、脚本文件 remote_setup.sh脚本文件内容&#xff1a; #! /bin/bash #参考链接&#xff1a;https://blog.csdn.net/hailangdeyingzi/article/details/124507304 sudo apt update sudo apt install x11vnc -y sudo x11vnc -storepasswd telpo.12…

【论文阅读】POIROT:关联攻击行为与内核审计记录以寻找网络威胁(CCS-2019)

POIROT: Aligning Attack Behavior with Kernel Audit Records for Cyber Threat Hunting CCS-2019 伊利诺伊大学芝加哥分校、密歇根大学迪尔伯恩分校 Milajerdi S M, Eshete B, Gjomemo R, et al. Poirot: Aligning attack behavior with kernel audit records for cyber thre…