STM32F103C8T6第三天:pwm、sg90、超声波、距离感应按键开盖震动开盖蜂鸣器

news2024/11/23 3:18:36

1. 定时器介绍1(317.21)

  • 软件定时(之前的定时方法)(软件延时)
  • 缺点:不精确、占用CPU资源
void Delay500ms() //@11.0592MHz
{
  unsigned char i, j, k;
  _nop_();
    i = 4;
    j = 129;
    k = 119;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

定时器工作原理:

  • 使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器。
    在这里插入图片描述

定时器分类:

  • 基本定时器(TIM6 ~ TIM7)
  • 通用定时器(TIM2 ~ TIM5)
  • 高级定时器(TIM1 和 TIM8)
    在这里插入图片描述

STM32F103C8T6定时器资源:

在这里插入图片描述

通用定时器介绍:

1) 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。
2) 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 165535 之间的任意数
值。
34 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
    A.输入捕获
    B.输出比较
    C.PWM 生成(边缘或中间对齐模式)
    D.单脉冲模式输出
4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电
路。
定时器计数模式:
定时器时钟源:
5)如下事件发生时产生中断/DMA:
    A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
    B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
    C.输入捕获
    D.输出比较
    E.支持针对定位的增量(正交)编码器和霍尔传感器电路
    F.触发输入作为外部时钟或者按周期的

2. 定时器介绍1(318.22)

定时器计数模式:

在这里插入图片描述
在这里插入图片描述

定时器时钟源:

在这里插入图片描述

定时器溢出时间计算公式:(加一是因为计算机是从0开始计数的)

在这里插入图片描述

  • 例如,要定时500ms(0.5s),则:PSC=7199,ARR=4999,Tclk=72M(72000000Hz)

3. 使用定时器中断点亮LED灯(319.23)

  • 需求:使用定时器中断方法,每500ms翻转一次LED1灯状态。
  1. RCC配置
  2. LED1灯配置
  3. 时钟数配置
  4. TIM2配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  5. 工程配置
  6. 重写更新中断回调函数
  • 代码(6.timer_test/MDK-ARM)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{//重写更新中断回调函数
	if(htim->Instance == TIM2)
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);//每过500ms翻转led1的状态
}
  1. 启动定时器
  • 在main.c中,在定时器初始化命令之后加入以下代码:
    HAL_TIM_Base_Start_IT(&htim2);

4. PWM概述(320.24)

STM32F103C8T6 PWM 资源:

  • 高级定时器(TIM1):7路
  • 通用定时器(TIM2~TIM4):各4路
    在这里插入图片描述
    在这里插入图片描述

PWM 输出模式:

  • PWM 模式1:在向上计数时,一旦 CNT < CCRx 时输出为有效电平,否则为无效电平; 在向下计数时,一旦 CNT > CCRx 时输出为无效电平,否则为有效电平。
  • PWM 模式2:在向上计数时,一旦 CNT < CCRx 时输出为无效电平,否则为有效电平; 在向下计数时,一旦 CNT > CCRx 时输出为有效电平,否则为无效电平。
    在这里插入图片描述

PWM 周期与频率:

在这里插入图片描述

PWM 占空比:

  • 由 TIMx_CCRx 寄存器决定。

5. PWM实现呼吸灯效果(321.25)

  • 需求:使用PWM点亮LED1实现呼吸灯效果。

LED灯为什么可以越来越亮,越来越暗?

  • 这是由不同的占空比决定的。

如何计算周期/频率?

  • 假如频率为 2kHz ,则:PSC=71,ARR=499

LED1连接到哪个定时器的哪一路?

  • 学会看产品手册:
    在这里插入图片描述

开始实战!

  1. 设置时钟
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 设置定时器
  • 把极性设置为 Low,因为 LED 灯是低电平亮
    在这里插入图片描述
  1. 配置工程
    在这里插入图片描述
    在这里插入图片描述
  2. 业务代码
  • 代码(7.pwm_test/MDK-ARM)
//main函数
// 定义变量
uint16_t pwmVal=0;  //调整PWM占空比 
uint8_t dir=1;    //设置改变方向。1:占空比越来越大;0:占空比越来越小

HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();

// 使能 Timer4 第3通道 PWM 输出
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);//打开pwm
// while循环实现呼吸灯效果
while (1)
{
  HAL_Delay(1);//如果没有 可能会不亮
  if (dir)
    pwmVal++;//1:越来越亮
  else
    pwmVal--;//0:越来越暗
    
    //pwmVal 达到 PWM 周期时,就会反向改变方向
	if(pwmVal >= htim4.Init.Period)//越来越亮到顶端后
		dir = 0;//变为越来越暗
	else if (pwmVal <= 0)//越来越暗到底端后
		dir = 1;//变为越来越亮
		
	//修改比较值(CCRx)即修改占空比
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal); 
}

6. 感应开关盖垃圾桶项目概述(322.26)

项目需求

  • 检测靠近时,垃圾桶自动开盖并伴随滴一声,2 秒后关盖
  • 发生震动时,垃圾桶自动开盖并伴随滴一声,2 秒后关盖
  • 按下按键时,垃圾桶自动开盖并伴随滴一声,2 秒后关盖

项目框图

在这里插入图片描述

硬件清单

  • SG90舵机,超声波模块,震动传感器,蜂鸣器

7. sg90舵机概述(324.28)

sg90舵机介绍

在这里插入图片描述

  • PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右。

确定周期/频率

在这里插入图片描述

  • 如果周期为20ms,则 PSC=7199,ARR=199

角度控制

  • 0.5ms-------------0度;2.5% 对应函数中 CCRx 为 5
  • 1.0ms------------45度;5.0% 对应函数中 CCRx 为 10
  • 1.5ms------------90度;7.5% 对应函数中 CCRx 为 15
  • 2.0ms-----------135度;10.0% 对应函数中 CCRx 为 20
  • 2.5ms-----------180度;12.5% 对应函数中 CCRx 为 25
    在这里插入图片描述

8. sg90舵机编程实战(323.27)

  • 需求: 每隔1s,转动一个角度:0度 --> 45度 --> 90度 --> 135度 --> 180度 --> 0度
  • 接线:
    在这里插入图片描述
  • STM32CubeMx工程配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 代码(8.sg90_test/MDK-ARM)
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);//打开Time4 第3通道的 PWM
 while (1)
{
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 5);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 10);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 15);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 20);
    HAL_Delay(1000);
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 25);
}

9. 超声波传感器介绍及实战(325.29)

超声波传感器介绍

在这里插入图片描述

  • 怎么让它发送波

    • Trig ,给Trig端口至少10us的高电平
  • 怎么知道它开始发送了

    • Echo信号,由低电平跳转到高电平,表示开始发送波
  • 怎么知道接收了返回波

    • Echo,由高电平跳转回低电平,表示波回来了
  • 怎么算时间
    Echo引脚维持高电平的时间!

    • 波发出去的那一刻,开始启动定时器;
    • 波返回来的拿一刻,开始停止定时器;

    计算出中间经过多少时间。

  • 怎么算距离

    • 距离 = 速度 (340m/s)* 时间/2
      在这里插入图片描述

编程实战

  • 需求: 使用超声波测距,当手离传感器距离小于5cm时,LED1点亮,否则保持不亮状态。
  • 接线:
    • Trig — PB6
    • Echo — PB7
    • LED1 — PB8
      在这里插入图片描述
  • 定时器配置:
    • 使用 TIM2 ,只用作计数功能,不用作定时。
    • 将 PSC 配置为 71,则计数 1 次代表 1us 。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  • 编写微秒级函数:
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{
  /* 使能定时器2计数 */
  __HAL_TIM_ENABLE(&htim2);
  __HAL_TIM_SetCounter(&htim2, 0);
  while(__HAL_TIM_GetCounter(&htim2) < (1 * n_us));
  /* 关闭定时器2计数 */
  __HAL_TIM_DISABLE(&htim2);
}

在这里插入图片描述

  • 主函数:
//1. Trig ,给Trig端口至少10us的高电平
//2. echo由低电平跳转到高电平,表示开始发送波
//波发出去的那一下,开始启动定时器
//3. 由高电平跳转回低电平,表示波回来了
//波回来的那一下,我们开始停止定时器
//4. 计算出中间经过多少时间
//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
//每500毫秒测试一次距离
  • 代码(9.sr_04_test/MDK-ARM)
int main()
{
	int cnt = 0;
	float distance = 0;
	
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
  	MX_TIM2_Init();
  	while (1)
  {
		//1. Trig ,给Trig端口至少10us的高电平
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//拉高
		TIM2_Delay_us(20);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//拉低
		
		//2. echo由低电平跳转到高电平,表示开始发送波
		//波发出去的那一下,开始启动定时器
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_RESET);
		HAL_TIM_Base_Start(&htim2);//启动定时器
		__HAL_TIM_SetCounter(&htim2,0);//从0开始计数
		
		//3. 由高电平跳转回低电平,表示波回来了
		//波回来的那一下,我们开始停止定时器
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_SET);
		HAL_TIM_Base_Stop(&htim2);
		
		//4. 计算出中间经过多少时间
		cnt = __HAL_TIM_GetCounter(&htim2);
		
		//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
		distance = 340*100*0.000001*cnt/2; //单位:cm
		
		if(distance < 5)
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
		else
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
		
		//每500毫秒测试一次距离
		HAL_Delay(500);
  }
}

10. 封装超声波测距代码(326.30)

  • 工程配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 代码(10.rubbish_test/MDK-ARM)
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{
    /* 使能定时器2计数 */
    __HAL_TIM_ENABLE(&htim2);
    __HAL_TIM_SetCounter(&htim2, 0);
    while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
    /* 关闭定时器2计数 */
    __HAL_TIM_DISABLE(&htim2);
}
double get_distance()
{
		int cnt = 0;
		//1. Trig ,给Trig端口至少10us的高电平
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//拉高
		TIM2_Delay_us(20);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//拉低
		
		//2. echo由低电平跳转到高电平,表示开始发送波
		//波发出去的那一下,开始启动定时器
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_RESET);
		HAL_TIM_Base_Start(&htim2);//启动定时器
		__HAL_TIM_SetCounter(&htim2,0);//从0开始计数
		
		//3. 由高电平跳转回低电平,表示波回来了
		//波回来的那一下,我们开始停止定时器
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_SET);
		HAL_TIM_Base_Stop(&htim2);
		
		//4. 计算出中间经过多少时间
		cnt = __HAL_TIM_GetCounter(&htim2);
		
		//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
		return (340*100*0.000001*cnt/2); //单位:cm
}
int main(void)
{
	float distance = 0;		
  	HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM2_Init();
    while (1)
  	{
		distance = get_distance();
		if(distance < 5)
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
		else
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
		//每500毫秒测试一次距离
		HAL_Delay(500);
  }
}

11. 实现距离感应开关盖(327.31)

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

三数之和(双指针)

15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三…

Python知识点——文件和数据格式化

目录 文件的打开 文件的打开模式 文件的路径 文件的关闭 文件内容读取 文件的读取 文件的写入 例题 文件的打开 文件的打开模式 文件打开模式描述‘r’只读模式&#xff0c;默认值&#xff0c;如果文件不存在&#xff0c;返回FileNotFoundErrorw覆盖写模式&#xff…

xray:漏洞扫描利器

简介 长亭科技旗下的一款网络安全漏洞扫描工具&#xff0c;用于检测和评估web应用程序的安全性。具有一下特点&#xff1a;检测速读快、检查范围广、代码质量高、高级可定制以及安全无危害。属于不开源的项目&#xff0c;用户直接下载xray的可执行文件&#xff0c;即可运行该工…

基于STM32的烟雾传感器

1.说到烟雾传感器&#xff0c;就有必要了解一下ADC的工作原理&#xff0c;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 。 2. 选择ADC 3.main函数 uint32_t smoke_value 0; while (1){HAL_ADC_Start(&hadc1);//启动ADC1转换HAL_ADC_PollForConversion(&am…

Linux防火墙入门:学会使用firewalld和iptables

1 防火墙 1.1 防火墙介绍 防火墙就是过滤的表格&#xff0c;被记录在表格中的信息&#xff0c;才允许通过访问。 1.2 两种火墙策略 iptables dnf install iptables-services -y systemctl disable --now firewalld systemctl mask firewalld systemctl enable --now ip…

BP神经网络的数据分类——语音特征信号分类

大家好&#xff0c;我是带我去滑雪&#xff01; BP神经网络&#xff0c;也称为反向传播神经网络&#xff0c;是一种常用于分类和回归任务的人工神经网络&#xff08;ANN&#xff09;类型。它是一种前馈神经网络&#xff0c;通常包括输入层、一个或多个隐藏层和输出层。BP神经网…

Go 面向对象,多态

面向对象 工程结构 新建一个oop.go package _oop // Package _oop 引用名称import ("fmt""strconv" )// GIRL 常量 const (// GIRL 自增GIRL Gender iotaFIRSTSECONDTHIRD )type Gender uint8 // 无符号的8位整数类型// User 结构体 type User struct…

pyinstaller 打包 paddleocr

一、场景 我们在使用pyinstaller打包完以后&#xff0c;在执行时会出现一些第三方库找不到&#xff0c;尤其是paddleocr库二、解决方法 在打包paddleocr的时候&#xff0c;他的一些模块不会跟着一起打包&#xff0c;我们要使用已下方法来进行打包处理一般情况下打包 pyinsta…

被王牌对王牌种草闺蜜机?来看看当贝PadGO

不少朋友都很喜欢热播综艺《王牌对王牌》,细心的朋友又在观看综艺的过程中被种草了可以移动的电视屏幕——闺蜜机。 目前国产闺蜜机比较热门的品牌是当贝PadGO和小度添添闺蜜机。个人在使用体验后更偏向当贝PadGO闺蜜机,因为从配置性能和系统功能当贝PadGO都更胜一筹。 1、4K画…

K8S知识点(六)

&#xff08;1&#xff09;资源管理方式1 其他参数 其他参数以json格式显示pod信息 以yaml显示pod信息&#xff1a; 用describe描述容器的详细信息&#xff1a;包括ip啊&#xff0c;镜像啊&#xff0c;端口啊&#xff0c;容器启动经历的历程 创建命名空间Pod&#xff1a; 查询…

排序算法之-冒泡

顺序排序算法原理 从头开始遍历未排序数列&#xff0c;遍历时比较相邻的两个元素&#xff0c;前面的大于后面的&#xff0c;则双方交换位置&#xff0c;一直比较到末尾&#xff0c;这样最大的元素会出现在末尾&#xff0c;接着再依次从头开始遍历剩余未排序的元素&#xff0c;…

upload-labs-1

文章目录 Pass-01 Pass-01 先上传一个正常的图片&#xff0c;查看返回结果&#xff0c;结果中带有文件上传路径&#xff0c;可以进行利用&#xff1a; 上传一个恶意的webshell&#xff0c;里面写入一句话木马&#xff1a; <?php eval($_POST[cmd]); echo "hello&quo…

Google警告黑客如何滥用日历服务作为隐蔽的C2信道

导语 最近&#xff0c;谷歌发布了一份关于黑客如何滥用日历服务作为隐蔽的C2信道的警告。这种新型攻击方式利用了谷歌日历作为C2基础设施&#xff0c;给安全防御带来了新的挑战。本文将介绍这种攻击方式的细节&#xff0c;以及如何防范这一威胁。 Google Calendar RAT&#xff…

三维虚拟沙盘数字全景沙盘M3DGIS系统开发教程第18课

三维虚拟沙盘数字全景沙盘M3DGIS系统开发教程第18课 上一节我们实现了模型的移动控制。这次我们来实现模型的材质控制&#xff0c;首先我们找一个模型。在3dmax中如下&#xff1a; 可以看到这个模型很复杂。分成了很多层。我们先不管它。导入SDK后如下图&#xff1a; 有贴图还…

IP代理如何选择?4大误区你别踩!

近年来&#xff0c;我国互联网商业保持持续发展的状态大环境的优化&#xff0c;大大小小的企业都想乘胜追击&#xff0c;大展宏图&#xff0c;积极推动各项数据业务的进程。 而对于跨境业务来说&#xff0c;代理IP是不可或缺的重要工具之一&#xff0c;市面上代理IP类型众多&a…

React动态生成二维码和毫米(mm)单位转像素(px)单位

一、使用qrcode.react生成二维码&#xff0c;qrcode.react - npm 很简单&#xff0c;安装依赖包&#xff0c;然后引用就行了 npm install qrcode.react或者 yarn add qrcode.react直接上写好的代码 import React, {useEffect, useState} from react; import QRCode from qr…

MySQL中的datetime和timestamp有什么区别

相同点: 存储格式相同 datetime和timestamp两者的时间格式都是YYYY-MM-DD HH:MM:SS 不同点: 存储范围不同. datetime的范围是1000-01-01到9999-12-31. 而timestamp是从1970-01-01到2038-01-19, 即后者的时间范围很小. 与时区关系. datetime是存储服务器当前的时区. 而timesta…

leetcode:2278. 字母在字符串中的百分比(python3解法)

难度&#xff1a;简单 给你一个字符串 s 和一个字符 letter &#xff0c;返回在 s 中等于 letter 字符所占的 百分比 &#xff0c;向下取整到最接近的百分比。 示例 1&#xff1a; 输入&#xff1a;s "foobar", letter "o" 输出&#xff1a;33 解释&…

解决ntfs-3g-mount: mount failed硬盘无法挂载的问题

操作系统&#xff1a;ubuntu 20.04 遇到的问题&#xff1a;开机后挂载usb外接硬盘失败&#xff08;外接硬盘盒&#xff09;&#xff0c;报错&#xff1a;ntfs-3g-mount: mount failed: Device or resource busy 问题原因&#xff1a;openwrt容器&#xff08;--restart always&a…

无人机航迹规划:小龙虾优化算法COA求解无人机路径规划MATLAB(可以修改起始点,地图可自动生成)

一、小龙虾优化算法COA 小龙虾优化算法&#xff08;Crayfsh optimization algorithm&#xff0c;COA&#xff09;由Jia Heming 等人于2023年提出&#xff0c;该算法模拟小龙虾的避暑、竞争和觅食行为&#xff0c;具有搜索速度快&#xff0c;搜索能力强&#xff0c;能够有效平衡…