IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32 CubeMax TCRT5000L光电对管巡线 原理与实现 -> 正文阅读

[嵌入式]STM32 CubeMax TCRT5000L光电对管巡线 原理与实现

STM32 CubeMax TCRT5000L光电对管巡线 原理与实现

1. 光电对管的原理

电子制作中使用的光电对管一般为TCRT5000系列,该系列分为TCRT5000TCRT5000L,两者的区别仅在于针脚的长度不同

在每一个管中,包含一个红外光电二极管和一个光敏三极管,红外光电二极管不断向外发射红外线,红外线经外部环境反射后被光敏三极管吸收,光敏三极管导通的程度和吸收的红外线强度成正比。所以只要检测光敏三极管导通的程度就知道反射红外线材料的性质。一般颜色深的材质吸收红外线多,颜色浅的材质反射红外线多,这就是我们检测黑线的基本原理

由原理图可知,光敏三极管导通后输出的值是一个连续的模拟值,所以我们可以通过ADC读取模拟值送入单片机进行处理,这样可以得到灵敏度非常高的结果。这种做法的缺点算法复杂,如果管子数量多了也会对ADC提出高要求。所以简便起见,我们一般把这个模拟值送到一个电压比较器中,这种情况下,输出值只有0和1两种情况,单片机的负担就会小很多,也足以应付大部分场合

使用比较器的典型电路长这样(自己画的,仅供参考),使用多个光电对管排成一排对黑线进行检测是目前的主流做法

图中的三角形就是电压比较器的符号了,型号是LM393

典型的实物像这样,这是某宝上买的模块

如果要买现成的模块,最好看一下上面有没有电位器(直插的贴片的都行),有电位器的一般都可以调节比较器的阈值,可以调整探测黑线的灵敏度(上面这个就没有电位器,说不定得自己换电阻…)

这时的算法编写就比较简单,只要用GPIO读取高、低电平即可

2. CubeMax配置

以上面发的那个实物模块为例,一共有5个光电对管,我们就需要5个输入引脚。这里最好使用外部中断输入而不是GPIO输入,使用中断输入能够避免一直轮询检测,节约一些GPIO资源

所以我们需要配置5个GPIO外部中断输入引脚,在配置引脚时,千万不要配置数字相同的引脚作为中断输入,比如说PA1和PB1,因为数字相同的引脚是共用中断线的,字母靠后的引脚会覆盖字母靠前的引脚(PB会覆盖PA),字母靠前的引脚的中断就不起作用了(详见数据手册)

因为这一款模块是探测到黑线输出低,所以我们需要设置为内部上拉,上升\下降沿触发中断

最后,记得将外部中断的优先级设低一点,否则可能会出现中断冲突导致卡死,比如说在外部输入中断函数中调用HAL_Delay时,就会与Time base中断冲突导致卡死

其他基础配置不再赘述

3. 接线

模块与STM32的接线如下

对管模块STM32
5V5V
GNDGND
OUT1PB0
OUT2PB1
OUT3PB10
OUT4PB11
OUT5PB12

4. 代码编写

eletube.h内容如下

#ifndef _ELETUBE_H_

#define _ELETUBE_H_

  

#include "stm32f1xx.h"

#include <stdio.h>

  

//光电对管中断输入引脚

#define ETUBE_PIN_1  GPIO_PIN_0

#define ETUBE_PIN_2  GPIO_PIN_1

#define ETUBE_PIN_3  GPIO_PIN_10

#define ETUBE_PIN_4  GPIO_PIN_11

#define ETUBE_PIN_5  GPIO_PIN_12

  

#define ETUBE_PORT_1 GPIOB

#define ETUBE_PORT_2 GPIOB

#define ETUBE_PORT_3 GPIOB

#define ETUBE_PORT_4 GPIOB

#define ETUBE_PORT_5 GPIOB

  

void Etube_Check(void);//将探测情况输出

  

#endif

eletube.c内容如下

#include "eletube.h"

  

uint8_t etubeCkeck[5] = {1,1,1,1,1};//存放每个对管探测到黑线的状态,1没探测到,0探测到

  

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//输入中断处理函数

{

    if(GPIO_Pin == ETUBE_PIN_1)//1号引脚

    {

        if(HAL_GPIO_ReadPin(ETUBE_PORT_1, ETUBE_PIN_1))//上升沿

        {

            etubeCkeck[0] = 1;

        }

        if(!HAL_GPIO_ReadPin(ETUBE_PORT_1, ETUBE_PIN_1))//下降沿

        {

            etubeCkeck[0] = 0;

        }

    }

  

    else if(GPIO_Pin == ETUBE_PIN_2)//2号引脚

    {

        if(HAL_GPIO_ReadPin(ETUBE_PORT_2, ETUBE_PIN_2))//上升沿

        {

            etubeCkeck[1] = 1;

        }

        if(!HAL_GPIO_ReadPin(ETUBE_PORT_2, ETUBE_PIN_2))//下降沿

        {

            etubeCkeck[1] = 0;

        }

    }

  

    else if(GPIO_Pin == ETUBE_PIN_3)//3号引脚

    {

        if(HAL_GPIO_ReadPin(ETUBE_PORT_3, ETUBE_PIN_3))//上升沿

        {

            etubeCkeck[2] = 1;

        }

        if(!HAL_GPIO_ReadPin(ETUBE_PORT_3, ETUBE_PIN_3))//下降沿

        {

            etubeCkeck[2] = 0;

        }

    }

    else if(GPIO_Pin == ETUBE_PIN_4)//4号引脚

    {

        if(HAL_GPIO_ReadPin(ETUBE_PORT_4, ETUBE_PIN_4))//上升沿

        {

            etubeCkeck[3] = 1;

        }

        if(!HAL_GPIO_ReadPin(ETUBE_PORT_4, ETUBE_PIN_4))//下降沿

        {

            etubeCkeck[3] = 0;

        }

    }

    else if(GPIO_Pin == ETUBE_PIN_5)//4号引脚

    {

        if(HAL_GPIO_ReadPin(ETUBE_PORT_5, ETUBE_PIN_5))//上升沿

        {

            etubeCkeck[4] = 1;

        }

        if(!HAL_GPIO_ReadPin(ETUBE_PORT_5, ETUBE_PIN_5))//下降沿

        {

            etubeCkeck[4] = 0;

        }

    }

}

  

void Etube_Check(void)//将探测情况输出

{
    uint8_t i = 0;

    for(i = 0;i < 5;i++)

    {

        if(etubeCkeck[i] == 0) printf("0  ");

        else if(etubeCkeck[i] == 1) printf("1  ");

        else {};

  

        printf("\r\n");

    }

}

之后在main函数里调用探测情况输出函数即可

while (1)

  {

    /* USER CODE END WHILE */

  

    /* USER CODE BEGIN 3 */

    Etube_Check();

    HAL_Delay(500);

  }

(记得自己将printf重定义)

5. 结果

输出正常,很ok

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:46  更:2022-04-18 17:59:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:28:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码