光敏电阻模块演示

STM32F103C8T6 + 5528 光敏电阻 | ADC采集 | OLED显示

一、传感器原理与功能

1.1 光敏电阻(5528)外观

光敏电阻(Photoresistor)是一种阻值随光照强度变化而变化的半导体器件。本次演示使用的传感器型号为 5528,其外观如下图所示:

光敏电阻外观 光敏电阻外观图(正面)
光敏电阻外观2 光敏电阻外观图(侧面/背面)

1.2 工作原理

光敏电阻基于内光电效应工作。当光照射到光敏电阻表面时,半导体材料中的电子吸收光子能量后跃迁至导带,产生电子-空穴对,使材料的电导率增加,电阻值下降。

5528 的典型参数:

参数数值
产品型号5528
最大压力 (VDC)150
最大功耗 (MW)100
环境温度 (°C)-30 ~ +70
光谱峰值 (Nm)540
亮电阻 (千欧)10 ~ 20
暗电阻 (兆欧)1
响应时间 (ms)上升: 20 / 下降: 30
照度电阻特性3

1.3 功能说明

在本演示系统中,光敏电阻与固定电阻构成分压电路,光敏电阻阻值随环境光照变化,导致分压点电压变化。STM32F103C8T6 通过 ADC1 通道0(PA0)采集该模拟电压,经换算后得到 0~100 的光照强度值,并通过 OLED 屏实时显示。

二、原理图与 PCB 封装

下图为光敏电阻模块的原理图与 PCB 封装设计:

原理图 模块原理图
PCB封装 PCB 封装图

原理图中 R1 为固定限流电阻,RG1 为 5528 光敏电阻,信号输出接 PA0。

三、程序分析

3.1 main.c 主程序

主程序完成系统初始化、ADC 初始化、OLED 初始化,并在 while(1) 主循环中每 200ms 采集一次光照值并刷新显示。

/* main.c - 主程序 */
#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "./HAL/OLED/OLED.h"

uint32_t Time_Now;
uint8_t  Light;

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    OLED_Init();

    while (1)                          // 主循环
    {
        if(HAL_GetTick() - Time_Now >= 200)  // 每200ms更新一次
        {
            HAL_ADC_Start(&hadc1);             // 启动ADC转换
            if(HAL_ADC_PollForConversion(&hadc1, 999) == HAL_OK)
                Light = (HAL_ADC_GetValue(&hadc1)/4095.0)*100;  // 换算光照强度 0~100
            HAL_ADC_Stop(&hadc1);              // 停止ADC

            OLED_Clear();
            OLED_CenterPrintf(24, "Light:%d", Light);
            OLED_Update();

            Time_Now = HAL_GetTick();         // 更新时间戳
        }
    }
}

3.2 adc.c ADC 初始化

ADC1 配置为单通道、单次转换、软件触发、12位右对齐模式,采样时间为 239.5 个时钟周期,输入通道为 ADC_CHANNEL_0(PA0)。

/* adc.c - ADC1初始化 */
ADC_HandleTypeDef hadc1;

void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    hadc1.Instance = ADC1;
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;           // 禁止扫描模式
    hadc1.Init.ContinuousConvMode = DISABLE;              // 单次转换
    hadc1.Init.DiscontinuousConvMode = DISABLE;           // 禁止间断模式
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;     // 软件触发
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;           // 右对齐
    hadc1.Init.NbrOfConversion = 1;                       // 1个转换
    HAL_ADC_Init(&hadc1);

    sConfig.Channel = ADC_CHANNEL_0;                      // 通道0 -> PA0
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;    // 采样时间
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(adcHandle->Instance == ADC1)
    {
        __HAL_RCC_ADC1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /* PA0-WKUP -> ADC1_IN0 */
        GPIO_InitStruct.Pin = GPIO_PIN_0;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;          // 模拟输入
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}

3.3 gpio.c GPIO 初始化

GPIO 初始化使能了 GPIOA 和 GPIOD 的时钟,为 ADC 引脚配置提供时钟支持。

/* gpio.c - GPIO初始化 */
void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
}

四、程序流程图

程序主流程图 初始化阶段 开 始 HAL_Init() SystemClock_Config() MX_GPIO_Init() MX_ADC1_Init() OLED_Init() 主循环阶段 while (1) 主循环 HAL_GetTick() - Time_Now >= 200 ms ? N 时间未到,跳过 Y 1 HAL_ADC_Start() 2 HAL_ADC_PollForConversion() == HAL_OK 3 Light = ADC / 4095 * 100 换算光照强度 0 ~ 100 4 HAL_ADC_Stop() 5 OLED_Clear() 6 OLED_CenterPrintf() 显示 "Light: %d" 7 OLED_Update() 8 Time_Now = HAL_GetTick() 采集完成,返回循环

五、交互演示动画

拖动下方滑块模拟环境光照强度变化,观察光敏电阻阻值、分压电压及 ADC 采样值的变化关系:

☀️
环境光照
50
光照强度 (0~100)
黑暗明亮
ADC 采集进度条
原理:光照越强 → 光敏电阻阻值越小 → 分压电压越高 → ADC 值越大 → 显示数值越大

六、系统总结

本演示系统基于 STM32F103C8T6 微控制器,通过 ADC1 通道0(PA0)采集 5528 光敏电阻的分压信号,在 while(1) 主循环中每 200ms 完成一次采样、换算与 OLED 显示刷新。程序结构清晰,模块化设计便于移植与扩展。