文章目录
- 摘要
- 一、简介
-
- 1.GPIO简介
- 2.红外避障传感器
- 3.性能参数
- 二、硬件电路设计
-
- 1.模块内部电路
- 2.连接到单片机的电路
- 三、软件设计
-
- 1.CubeMX配置
- 2.CubeIDE代码
- 四、结果显示
- 五、总结
- 附录
摘要
本篇文章用STM32CubeMX和STM32CubeIDE软件编程,主控芯片STM32F103C8T6驱动红外避障传感器,。由于本设计采用了设计好的红外避障模块,只要知道红外避障传感器的原理和功能,编程相对容易。
1、芯片: STM32F103C8T6
2、驱动设备:红外避障传感器
3、配置软件:STM32CubeMX
4、IDE: STM32CubeIDE
通过这篇文章学到:
1、红外避障传感器的工作原理
2、GPIO相关操作及功能
一、简介
1.GPIO简介
STM32F1系列MCU一般有多个GPIO(General Purpose Input-Output)每个端口有16个引脚GPIO使用引脚时,我们可以输入或输出数字信号。,GPIO引脚能承受5V电压。每个引脚的输入输出数据可以单独设置。内部有双向保护二极管,上下拉电阻是否可以配置,每个引脚都可以单独设置。GPIO引脚可配置多种工作模式。其内部结构图如图所示。
1、 (1)输入浮空(Input floating),不要使用上拉或下拉。 (2)输入上拉(Input pull-up),使用内部上拉电阻,引脚输入电平为高电平。 (3)输入下拉(Input pull-down),使用内部下拉电阻,无输入时读取的引脚输入电平为低电平。
2、 (1)上拉或下拉开漏输出(Output open-drain)。若无上拉或下拉,开漏输出1时引脚为高阻态,输出0时引脚为低电平,该模式可用于共用总线信号。 (2)上拉或下拉推挽输出(Output push-pull)。若无上拉或下拉,推拉输出1时引脚为高电平,输出0时引脚为低电平。若需增强引脚输出驱动能力,则可使用上拉。
3、 (1)模拟(Analog 作为GPIO用于模拟引脚ADC输入或DAC输出引脚。
4、 (1)上拉或下拉复用功能推挽(Alternate function push-pull) (2)上拉或下拉复用功能开漏(Alternate function open-drain)
每个GPIO配置端口有4个32位寄存器GPIO引脚的工作模式,一个32位输入数据寄存器,一个32位输出寄存器,复用功能选择寄存器等。GPIO系统复位后,引脚处于输入浮空模式。
2.红外避障传感器
,也就是说,有两个红外管,即输送管和接收管,具有适应性强、干扰小、安装方便等特点。红外避障传感器由一对红外发射管、红外接收管和传感器电路组成, 图中的蓝色设备是传感器的检测距离调节器,所以当我们需要改变测量距离时,我们只需要改变调节器的旋钮。调节器可以调节传感器的检测距离。对于白色物体,反射的最远距离最大,黑色物体,反射的最远距离最小,大物体可以检测的距离达到,小物体可以检测的距离小。最短检测距离为2cm,最长检测距离可达20cm,工作电压低,偏移角40可检测°的物体。当传感器模块检测到障碍物或物体靠近时,模块的绿灯会同时亮起OUT引脚会降低电平。由于模块是非接触式传感器,具有响应快、精度高的特点。广泛应用于避障或跟踪。
3.性能参数
工作电压:3.3V-5V 工作电流:≥20mA 工作温度:-10℃到+50℃ 检测距离:2-20cm 输出信号:接收低电平的光输出,未接收高电平的光输出
附件:传感器模块输出端口OUT可直接与IO口相连接也可以直接驱动5V继电器。
二、硬件电路设计
1.模块内部电路
这部分可以理解,因为它是一个已经包装好的模块。图中通过调整电位器的电阻值LM比较393比较器,以调整测量距离。
2.连接到单片机的电路
模块连接到单片机的电路也很简单,即将单片机PB12引脚接到模块OUT端口,模块VCC接3.3V,GND与单片机GND相连即可。
三、软件设计
1.CubeMX配置
设置如下图所示HSE(高速外部时钟)及时钟树的配置。HSE之后芯片会自动选定两个引脚用来连接外部晶振,设置LSE然后配置时钟树,设置HCLK为72MHz(最高72MHz,也可配置其他),其配置图如图所示。
如图所示,调试接口设置为SW模式,占用两个芯片引脚。
如图,在CubeMX点击鼠标左键在中芯片的引脚中设置引脚功能。这里将是PC13设置为输出模式,PB12设置为输入模式。 有输出配置GPIO输出电平,输出模式,上拉下拉,最高输出速率。从原理图可以看出LED当灯的输出电平设置为低时,连接会亮起,并且会亮起GPIO模式设置为推拉模式,LED无要求最高输出率。 在GPIO红外避障传感器设置如图所示OUT引脚PB输入模式后需要设置上拉和下拉,这里设置未上拉模式。
为显示结果,用串口将转换结果传到电脑上,设置为异步模式,波特率为115200Bits/s,其UART配置如下图所示。设置完成后,串口通信将自动引出两个引脚。
除了调试接口和外部冲击接口外,还有PC13代表LED灯,PB12连接红外避障传感器OUT引脚,还有一组串口RX和TX。如下图所示。
在ProjectManager如图所示,设置集成开发环境STM32CubeIDE。使用其他平台,比如IAR,Keil也可对应选择。 下图勾选生成外围.c.h文件,个人习惯,也可以不检查就生成外围文件main文件里。
2.CubeIDE代码
GPIO函数很少,读者只需要掌握标记红色的三个函数,即写作、阅读和翻转操作。本文使用了阅读和写作的功能。
思路:em>红外避障模块是直接封装好的,会直接在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灯以及串口发送数据。在。借由这个思想就可以借助红外避障传感器实现避障或者循迹等一系列的功能,即改变红外传感器的状态所触发的动作即可,比如驱动电机往哪转,打开蜂鸣器等等,根据不同应用场合添加不同功能。读者可以自己尝试不同的输出方式,体会红外传感器的方便。
附录
/* 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 */