草庐IT

【STM32Cube】学习笔记(五):红外避障传感器

Synchron. 2023-11-06 原文

文章目录


摘要

本篇文章用STM32CubeMX和STM32CubeIDE软件编程,主控芯片为STM32F103C8T6驱动红外避障传感器,通过红外避障传感器输出的电平来改变LED灯的状态,并且通过串口打印出红外避障传感器的状态信息。由于本次设计采用已设计好的红外避障模块,所以相对来说编程比较容易,只要知道红外避障传感器的原理和功能即可。通过本文可以学会红外避障传感器的原理以及使用和操作GPIO相关功能。

所用工具:

1、芯片: STM32F103C8T6

2、驱动设备:红外避障传感器

3、配置软件:STM32CubeMX

4、IDE: STM32CubeIDE

知识概括:

通过本篇文章您将学到:

1、红外避障传感器工作原理

2、GPIO相关操作与功能


一、简介

1.GPIO简介

STM32F1系列MCU一般有多个GPIO(General Purpose Input-Output)端口,每个端口由16个引脚,作为GPIO引脚使用时,我们可以输入或输出数字信号。STM32F103C8芯片有3个16引脚的GPIO端口,从PA到PC,这些GPIO端口都连接在AHB1总线上,最高时钟频率为72MHz,GPIO引脚能承受5V电压。每个引脚的输入输出数据可以单独设置。其内部有双向保护二极管,有可配置是否使用的上拉和下拉电阻,每个GPIO引脚可以配置多种工作模式。其内部结构图如图所示。

GPIO工作模式
1、作为GPIO输入
(1)输入浮空(Input floating),并且不使用上拉或下拉。
(2)输入上拉(Input pull-up),使用内部上拉电阻,引脚外部无输入时读取的引脚输入电平为高电平。
(3)输入下拉(Input pull-down),使用内部下拉电阻,引脚外部无输入时读取的引脚输入电平为低电平。

2、作为GPIO输出
(1)具有上拉或下拉的开漏输出(Output open-drain)。如果没有上拉或下拉,开漏输出1时引脚是高阻态,输出0时引脚是低电平,这种模式可用于共用总线的信号。
(2)具有上拉或下拉的推挽输出(Output push-pull)。如果没有上拉或下拉,推挽输出1时引脚为高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。

3、作为ADC或DAC引脚
(1)模拟(Analog 功能),作为GPIO模拟引脚,用于ADC输入或DAC输出引脚。

4、作为复用功能引脚
(1)具有上拉或下拉的复用功能推挽(Alternate function push-pull)
(2)具有上拉或下拉的复用功能开漏(Alternate function open-drain)

每个GPIO端口有4个32位寄存器,用于配置GPIO引脚的工作模式,1个32位输入数据寄存器和1个32位输出寄存器,还有复用功能选择寄存器等,所有未进行任何配置的GPIO引脚,在系统复位后处于输入浮空模式。

2.红外避障传感器

红外避障传感器,又叫红外对管传感器,即有两个红外管,分别是发送管和接收管,特点是对环境光线的适应能力强,干扰较小,便于安装等。红外避障传感器由一对红外光线发射管与红外光线接收管、传感器电路组成,引脚上有VCC、GND、OUT三个引脚。其工作原理是红外光线发射管发射红外光线,红外光线接收管接收红外光线,当没有接收到返回的红外光线时,OUT引脚输出高电平,当接收到返回的红外光线时,OUT引脚输出低电平。
图中的蓝色器件为传感器的检测距离调节器,所以当我们需要改变测量距离是只需要改变调节器的旋钮即可。该调节器可以调节传感器的检测距离,对于白色的物体,反射的最远距离最大,黑色物体,反射的最远距离最小,面积大的物体所能探测的距离达,面积小的物体所能探测的距离小。最短检测距离是2cm,最长检测距离可以达到20cm,工作电压较低,同时可以检测偏移角40°的物体。当传感器模块检测到障碍物或者有物体靠近时,其模块的绿色灯会亮起,同时OUT引脚会变低电平。因模块是非接触式传感器,所以具有响应快,精度高等特点。被广泛运用于避障或者循迹等场合。

3.性能参数

工作电压:3.3V-5V
工作电流:≥20mA
工作温度:-10℃到+50℃
检测距离:2-20cm
输出信号:接收到光线输出低电平,没有接收到光线输出高电平

附:传感器模块输出端口OUT可直接与IO口相连接,也可以直接驱动一个5V继电器。


二、硬件电路设计

1.模块内部电路

由于是已经封装好的模块,所以这部分了解即可。图中通过调节电位器的阻值来与LM393比较器做比较,从而达到调节测量距离的目的。

2.与单片机相连接电路

模块与单片机相连的电路也很简单,即将单片机的PB12引脚接到模块的OUT端口,模块VCC接3.3V,GND与单片机GND相连即可。


三、软件设计

1.CubeMX配置

(1)时钟配置
如下图分别为设置HSE(高速外部时钟)以及时钟树的配置。选定HSE之后芯片会自动选定两个引脚用来连接外部晶振,设置LSE之后配置时钟树,设置HCLK为72MHz(最高72MHz,也可以配置其他),其配置图如图所示。

(2)调试接口配置
如图所示,将调试接口设置的设置为SW模式,占用芯片两个引脚。

(3)GPIO配置
如图,在CubeMX中芯片的引脚中点击鼠标左键可以给引脚设置功能。这里将PC13设置为输出模式,PB12设置为输入模式。


在输出配置中有GPIO输出电平,输出模式,上拉下拉,最高输出速率。由原理图可知LED灯的输出电平设置为低时则接上就会亮,将GPIO模式设置为推挽模式,LED的最高输出速率无要求。

在GPIO工作模式设置中按如图所示设置,其中红外避障传感器OUT引脚PB12配置为输入模式之后需要设置上拉与下拉,这里设置未上拉模式。

(4)串口配置
为显示结果,用串口将转换结果传到电脑上,设置为异步模式,波特率为115200Bits/s,其UART配置如下图所示。设置完成之后会自动引出两个引脚用于串口通信。

(5)引脚使用情况
本次除了调试接口和外部震荡接口外,还有PC13代表LED灯,PB12连接红外避障传感器的OUT引脚,还有一组串口RX和TX。使用情况如下图所示。

(6)保存
在ProjectManager中设置如如图所示,设置集成开发环境为STM32CubeIDE。运用其他平台比如IAR,Keil也可以对应选择。
下图勾选生成外围.c.h文件,个人习惯,也可以不勾选让外围文件生成在main文件里。

2.CubeIDE代码

(1)GPIO相关HAL函数
GPIO函数很少,读者只要熟练掌握标红的三个函数即可,分别是写,读和翻转操作。本文用到读和写的功能。

(2)代码
思路:红外避障模块是直接封装好的,会直接在OUT引脚输出信号,所以只要将单片机PB12引脚设置为输入取接收模块的信号即可,通过引脚接受的状态取获取传感器检测物体信息。
功能:当红外避障传感器检测到物体存在时,PC13会亮并且串口会发送已检测信号,当红外避障传感器未检测到物体存在时,PC13会灭并且串口会发送未检测信号。
位置:位于/* USER CODE BEGIN WHILE */沙箱内。

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET)        //当检测到红外避障传感器OUT引脚(PB12)为低电平,即检测到物体
	  {
		  uint8_t Str1[] = "Already Detected!\r\n";
		  HAL_UART_Transmit(&huart1, Str1, sizeof(Str1), 200);          //串口轮询打印已检测

		  HAL_Delay(50);                                                //延时50ms

		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);        //LED灯(PC13)设置为低电平,即亮

	  }
	  else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_SET)     //当检测到红外避障传感器OUT引脚(PB12)为高低电平,即未检测到物体
	  {
		  uint8_t Str2[] = "Not Detected!\r\n";
		  HAL_UART_Transmit(&huart1, Str2, sizeof(Str2), 200);          //串口轮询打印未检测

		  HAL_Delay(50);                                                //延时50ms

		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);        //LED灯(PC13)设置为高电平,即灭

	  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

四、结果显示

(1)这是串口所接收到的传感器状态信息,每20ms读取一次。

(2)这是状态灯显示信息,可见,当未检测到物体或者距离不够时,模块和开发板上的灯都不亮。

(3)当距离达到检测距离时,模块和开发板上的灯都亮。


五、总结

本次设计了解了红外避障传感器的原理以及简单的功能实现,只是在达到测量距离时点亮LED灯以及串口发送数据。在本次设计中,红外传感器看做是输入,LED灯和串口看做是由输入所产生的状态所触发的不同动作,即输出。借由这个思想就可以借助红外避障传感器实现避障或者循迹等一系列的功能,即改变红外传感器的状态所触发的动作即可,比如驱动电机往哪转,打开蜂鸣器等等,根据不同应用场合添加不同功能。读者可以自己尝试不同的输出方式,体会红外传感器的方便。


附录

完整代码:

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET)        //当检测到红外避障传感器OUT引脚(PB12)为低电平,即检测到物体
	  {
		  uint8_t Str1[] = "Already Detected!\r\n";
		  HAL_UART_Transmit(&huart1, Str1, sizeof(Str1), 200);          //串口轮询打印已检测

		  HAL_Delay(50);                                                //延时50ms

		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);        //LED灯(PC13)设置为低电平,即亮

	  }
	  else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_SET)     //当检测到红外避障传感器OUT引脚(PB12)为高低电平,即未检测到物体
	  {
		  uint8_t Str2[] = "Not Detected!\r\n";
		  HAL_UART_Transmit(&huart1, Str2, sizeof(Str2), 200);          //串口轮询打印未检测

		  HAL_Delay(50);                                                //延时50ms

		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);        //LED灯(PC13)设置为高电平,即灭

	  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

有关【STM32Cube】学习笔记(五):红外避障传感器的更多相关文章

  1. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  2. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  3. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  4. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  5. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  6. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

  7. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

  8. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  9. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  10. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

随机推荐