STM32F103C8T6 + 5528 光敏电阻 | ADC采集 | OLED显示
光敏电阻(Photoresistor)是一种阻值随光照强度变化而变化的半导体器件。本次演示使用的传感器型号为 5528,其外观如下图所示:
光敏电阻外观图(正面)
光敏电阻外观图(侧面/背面)
光敏电阻基于内光电效应工作。当光照射到光敏电阻表面时,半导体材料中的电子吸收光子能量后跃迁至导带,产生电子-空穴对,使材料的电导率增加,电阻值下降。
5528 的典型参数:
| 参数 | 数值 |
|---|---|
| 产品型号 | 5528 |
| 最大压力 (VDC) | 150 |
| 最大功耗 (MW) | 100 |
| 环境温度 (°C) | -30 ~ +70 |
| 光谱峰值 (Nm) | 540 |
| 亮电阻 (千欧) | 10 ~ 20 |
| 暗电阻 (兆欧) | 1 |
| 响应时间 (ms) | 上升: 20 / 下降: 30 |
| 照度电阻特性 | 3 |
在本演示系统中,光敏电阻与固定电阻构成分压电路,光敏电阻阻值随环境光照变化,导致分压点电压变化。STM32F103C8T6 通过 ADC1 通道0(PA0)采集该模拟电压,经换算后得到 0~100 的光照强度值,并通过 OLED 屏实时显示。
下图为光敏电阻模块的原理图与 PCB 封装设计:
模块原理图
PCB 封装图
原理图中 R1 为固定限流电阻,RG1 为 5528 光敏电阻,信号输出接 PA0。
主程序完成系统初始化、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(); // 更新时间戳
}
}
}
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);
}
}
GPIO 初始化使能了 GPIOA 和 GPIOD 的时钟,为 ADC 引脚配置提供时钟支持。
/* gpio.c - GPIO初始化 */
void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
拖动下方滑块模拟环境光照强度变化,观察光敏电阻阻值、分压电压及 ADC 采样值的变化关系:
本演示系统基于 STM32F103C8T6 微控制器,通过 ADC1 通道0(PA0)采集 5528 光敏电阻的分压信号,在 while(1) 主循环中每 200ms 完成一次采样、换算与 OLED 显示刷新。程序结构清晰,模块化设计便于移植与扩展。