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

文章目录

  • 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持续闪烁,表示正在工作,且在工作的时候无法切换功能。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R语言如果列表中有列表,且每个子列表有一个向量:如何转变为仅仅一个列表里面含有向量

引言 有些时候&#xff0c;比如批量读取表格中的某一列的时候&#xff0c;最终你会得到列表里面装列表&#xff0c;且每个列表里面只有一个向量的情况。我们的目标是不要中间这一层列表&#xff0c;而是直接变成列表-向量这种简单的结构&#xff0c;如何完成呢。我觉得有很多方…

Linux Ubuntu系统安装OpenVPN服务

OpenVPN Ubuntu/Linux 服务端安装 官方文档&#xff1a;https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage 介绍 嘿&#xff0c;今天我们要探讨的话题是OpenVPN——那个让你在互联网上以安全又私密的方式冲浪的神奇工具。 首先&#xff0c;你可能会问&#xff…

用正则处理Unicode 编码的文本

Unicode&#xff08;中文&#xff1a;万国码、国际码、统一码、单一码&#xff09;是计算机科学领域里的一项业界标准。它对世界上大部分的文字进行了整理、编码。Unicode 使计算机呈现和处理文字变得简单。 现在的 Unicode 字符分为 17 组编排&#xff0c;每组为一个平面&…

什么是住宅ip,静态和动态怎么选?

上文我们介绍了数据中心代理&#xff0c;这次我们来介绍下住宅代理ip&#xff0c;住宅代理ip分类两种类型&#xff1a;静态住宅代理和动态住宅代理&#xff0c;他们有什么区别又能用在什么场景呢&#xff1f;我们先从他们是如何运作开始。 一、什么是住宅代理ip isp住宅代理i…

C++内存模型

目录 内存模型分类 堆和栈的区别 C中new的工作过程 堆和栈的区别 为什么堆区要比栈区大 内存模型分类 文本段&#xff08;ELF&#xff09;&#xff08;数据区&#xff09;&#xff1a;主要用于存放我们编写的代码&#xff0c;但是不是按照代码文本的形式存放&#xff0c;而…

打开软件提示msvcp140.dll丢失的解决方法,msvcp140主要丢失原因

今天&#xff0c;我将为大家介绍一种非常常见的问题——msvcp140.dll丢失。这个问题可能会导致许多应用程序无法正常运行&#xff0c;甚至崩溃。但是&#xff0c;请不要担心&#xff0c;我会为大家提供5种解决方法&#xff0c;帮助大家轻松解决问题。 首先&#xff0c;我们来看…

分布式搜索引擎----elasticsearch

目录 1、初识elasticsearch 1.1、什么是elasticsearch 1.2.ELK技术栈 2、正向索引和倒排索引 2.1、正向索引 2.2、倒排索引 2.3、正向索引和倒排索引的区别 3、elasticsearch中的概念理解 3.1、文档和字段 3.2、索引和映射 3.3、mysql与elasticsearch 1、初识elasti…

【C++11】future和async等

C11的future和async等关键字 1.async和future的概念 std::async 和 std::future 是 C11 引入的标准库功能&#xff0c;用于实现异步编程&#xff0c;使得在多线程环境中更容易处理并行任务。它们可以帮助你在不同线程中执行函数&#xff0c;并且能够方便地获取函数的结果。 在…

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【二】

&#x1f600;前言 本篇博文是关于Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【二】的&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文…

命令全局安装 ts

1.全局安装 typeScript编译 npm install -g typescript2.查看版本 tsc-v安装成功的画面

Spring与Mybatis整合aop整合pageHelper分页插件

前言 Spring与MyBatis整合的意义在于提供了一种结合优势的方式&#xff0c;以便更好地开发和管理持久层&#xff08;数据库访问&#xff09;代码。 这里也是总结了几点主要意义 简化配置&#xff1a;Spring与MyBatis整合后&#xff0c;可以通过Spring的配置文件来管理和配置M…

31、springboot 配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口

配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口 ★ 设置HTTP服务端口&#xff1a; - server.port或者SERVER_PORT环境变量——总结来说&#xff0c;其实就是要配置server.port外部配置属性。▲ 同样遵守如下优先级&#xff1a; 这些都是外部配置源&#x…

基于javaweb的新生报到系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&…

Vue路由(详解)

目录 路由原理 路由到底有什么作用&#xff1f; 路由安装和使用&#xff08;vue2&#xff09; 路由跳转 跳转实例&#xff1a; 路由的传值和取值 传值实例&#xff1a; 查询参和路由参的区别&#xff1a; 嵌套路由 嵌套实例&#xff1a; 路由守卫 守卫实例&#xff1…

如何使用CSS实现一个响应式轮播图?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现响应式轮播图的示例⭐ HTML 结构⭐ CSS 样式 (styles.css)⭐ JavaScript 代码 (script.js)⭐ 实现说明⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带…

EMR电子病历系统 SaaS电子病历编辑器源码 电子病历模板编辑器

EMR&#xff08;Electronic Medical Record&#xff09;指的是电子病历。它是一种基于电子文档的个人医疗记录&#xff0c;可以包括病人的病史、诊断、治疗方案、药物处方、检查报告和护理计划等信息。EMR采用计算机化的方式来存储、管理和共享这些信息&#xff0c;以便医生和医…

在Linux中使用gcc/g++编译代码

gcc/g 1.方法速记2.具体过程2.1 预处理阶段2.2 编译阶段2.3 汇编阶段2.4链接阶段2.4.1 链接的细节 gcc和g的操作一样&#xff0c;g的方法就仅需把gcc换成g即可。 1.方法速记 直接编译语法&#xff1a;将text.c文件或者text.cpp文件直接编译成text文件。 gcc text.c -o text /…

ElementUI中的日历组件加载无效的问题

在ElementUI中提供了一个日历组件。在某些场景下还是比较有用的。只是在使用的时候会有些下坑&#xff0c;大家要注意下。   官网提供的信息比较简介。我们在引入到项目中使用的时候可以能会出现下面的错误提示。 Unknown custom element: <el-calendar> - did you …

git通过fork-merge request实现多人协同

一、问题 对于一个项目&#xff0c;如果需要多人协同开发&#xff0c;大家都在原始仓库中进行修改提交&#xff0c;经常会发生冲突&#xff0c;而且一不小心会把别人的代码内容覆盖掉。为了避免这样的问题&#xff0c;git提供了fork-merge request这样的协同方式。 二、仓库框…

【C++】—— 简述C++11新特性

序言&#xff1a; 从本期开始&#xff0c;我将会带大家学习的是关于C11 新增的相关知识&#xff01;废话不多说&#xff0c;我们直接开始今天的学习。 目录 &#xff08;一&#xff09;C11简介 &#xff08;二&#xff09;统一的列表初始化 1、&#xff5b;&#xff5d;初始…