第20章 光敏传感器实验

第二十章 光敏传感器实验

1. 硬件设计

本实验用到的硬件资源有:

  • 指示灯DS0

  • TFTLCD模块

  • ADC

  • 光敏传感器

前三个之前均有介绍,光敏传感器与 STM32F4 的连接如图所示:

屏幕截图 20241014 125059png

图中, LS1 是光敏二极管(实物在开发板摄像头接口右侧), R58 为其提供反向电压,当环境光线变化时, LS1 两端的电压也会随之改变,从而通过 ADC3_IN5 通道,读取LIGHT_SENSOR(PF7)上面的电压,即可得到环境光线的强弱。光线越强,电压越低,光线越暗,电压越高。

2. 软件设计

2.1 ADC初始化

ADC_HandleTypeDef ADC3_Handler;//ADC句柄
// 初始化ADC
// ch: ADC_channels 
// 通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void Adc3_Init(void)
{   
    ADC3_Handler.Instance=ADC3;
    ADC3_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; // 4分频,ADCCLK=PCLK2/4=84/4=21MHZ
    ADC3_Handler.Init.Resolution=ADC_RESOLUTION_12B;           // 12位模式
    ADC3_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;           // 右对齐
    ADC3_Handler.Init.ScanConvMode=DISABLE;                    // 非扫描模式
    ADC3_Handler.Init.EOCSelection=DISABLE;                    // 关闭EOC中断
    ADC3_Handler.Init.ContinuousConvMode=DISABLE;              // 关闭连续转换
    ADC3_Handler.Init.NbrOfConversion=1;                       // 1个转换在规则序列中 也就是只转换规则序列1 
    ADC3_Handler.Init.DiscontinuousConvMode=DISABLE;           // 禁止不连续采样模式
    ADC3_Handler.Init.NbrOfDiscConversion=0;                   // 不连续采样通道数为0
    ADC3_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;     // 软件触发
    ADC3_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;// 使用软件触发
    ADC3_Handler.Init.DMAContinuousRequests=DISABLE;           // 关闭DMA请求
    HAL_ADC_Init(&ADC3_Handler);                               // 初始化     
}

2.2 采集ADC值

// ADC底层驱动,引脚配置,时钟使能
// 此函数会被HAL_ADC_Init()调用
// hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    __HAL_RCC_ADC3_CLK_ENABLE();   // 使能ADC3时钟
}
// 获得ADC值
// ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
// 返回值:转换结果
u16 Get_Adc3(u32 ch)   
{
    ADC_ChannelConfTypeDef ADC1_ChanConf; 
    ADC1_ChanConf.Channel=ch;                            // 通道
    ADC1_ChanConf.Rank=1;                                // 1个序列
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; // 采样时间
    ADC1_ChanConf.Offset=0;                              // 偏移量为0
    HAL_ADC_ConfigChannel(&ADC3_Handler,&ADC1_ChanConf); // 通道配置
    HAL_ADC_Start(&ADC3_Handler);                        // 开启ADC
    HAL_ADC_PollForConversion(&ADC3_Handler,10);         // 轮询转换
	return (u16)HAL_ADC_GetValue(&ADC3_Handler);	     // 返回最近一次ADC1规则组的转换结果
}

2.3 初始化光敏传感器

//初始化光敏传感器
void Lsens_Init(void)
{
	GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOF_CLK_ENABLE();		// 开启GPIOF时钟
    GPIO_Initure.Pin=GPIO_PIN_7;        // PF7
    GPIO_Initure.Mode=GPIO_MODE_ANALOG; // 模拟
    GPIO_Initure.Pull=GPIO_NOPULL;      // 不带上下拉
    HAL_GPIO_Init(GPIOF,&GPIO_Initure);
	Adc3_Init();//初始化ADC3
}

2.4 获取光亮值

//读取Light Sens的值
//0~100:0,最暗;100,最亮 
u8 Lsens_Get_Val(void)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<LSENS_READ_TIMES;t++)
	{
		temp_val+=Get_Adc3(ADC_CHANNEL_5);	//读取ADC值,通道5
		delay_ms(5);
	}
	temp_val/=LSENS_READ_TIMES;//得到平均值 
	if(temp_val>4000)temp_val=4000;
	return (u8)(100-(temp_val/40));
}

2.5 主函数

int main(void)
{
	u8 adcx;	
    HAL_Init();                  // 初始化HAL库    
    Stm32_Clock_Init(336,8,2,7); // 设置时钟,168Mhz
	delay_init(168);             // 初始化延时函数
	uart_init(115200);           // 初始化USART
	usmart_dev.init(84); 		 // 初始化USMART
	LED_Init();				     // 初始化LED	
	KEY_Init();				     // 初始化KEY
 	LCD_Init();           		 // 初始化LCD
	Lsens_Init(); 				 // 初始化光敏传感器
	POINT_COLOR = RED; // 设置字体为红色 
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"LSENS TEST");	  
	POINT_COLOR=BLUE;//设置字体为蓝色
	LCD_ShowString(30,130,200,16,16,"LSENS_VAL:");	             
	while(1)
	{
		adcx = Lsens_Get_Val(); // 获取光敏传感器的值
		LCD_ShowxNum(30+10*8,130,adcx,3,16,0);//显示ADC的值 
		LED0=!LED0;
		delay_ms(250);	
	}
}

3. 小结

本章主要还是在学习ADC采集电压,不过这次我们接入了一个光敏传感器,不同光亮程度电压不同,ADC所采集的值也就不同了。下面我们来回顾一下:

硬件连接

  1. 光敏传感器(LDR):将光敏传感器的一个引脚连接到 STM32 的 ADC 输入引脚,另一个引脚接地。
  2. 电源:为光敏传感器提供适当的电源(一般为 3.3V 或 5V,具体取决于你使用的传感器)。
  3. ADC 输入:选择合适的 ADC 通道连接到光敏传感器。

示例代码

#include "main.h"  // 包含 STM32 库的主头文件
// ADC 句柄和 UART 句柄的声明
ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart1;
// 函数原型声明
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART1_UART_Init(void);
int main(void) {
    // 初始化 HAL 库
    HAL_Init();
    // 配置系统时钟
    SystemClock_Config();
    // 初始化 GPIO、ADC 和 USART
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_USART1_UART_Init();
    while (1) {
        // 启动 ADC 转换
        HAL_ADC_Start(&hadc1);
        // 等待 ADC 转换完成
        HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
        // 读取 ADC 转换值
        uint32_t adcValue = HAL_ADC_GetValue(&hadc1);
        // 计算光敏传感器的输出电压
        // 假设 Vref = 3.3V, 分辨率为 12 位
        float voltage = (3.3f * adcValue) / 4095.0f; // 将 ADC 值转换为电压值
        // 将电压值格式化为字符串,准备发送
        char buffer[50]; // 缓冲区用于存储输出字符串
        snprintf(buffer, sizeof(buffer), "LDR Voltage: %.2f V\r\n", voltage);
        // 通过串口发送电压值
        HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
        // 延时1秒
        HAL_Delay(1000); // 等待 1 秒以便下次读取
    }
}

// ADC 初始化函数
static void MX_ADC1_Init(void) {
    // 配置 ADC 通道
    ADC_ChannelConfTypeDef sConfig = {0}; // 创建一个 ADC 通道配置结构体
    __HAL_RCC_ADC1_CLK_ENABLE(); // 启用 ADC1 的时钟
    // 配置 ADC 的基本参数
    hadc1.Instance = ADC1; // 选择 ADC1 实例
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // ADC 时钟预分频
    hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 12 位分辨率
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 禁用扫描模式
    hadc1.Init.ContinuousConvMode = ENABLE; // 启用连续转换模式
    hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁用不连续模式
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发转换
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据对齐方式
    hadc1.Init.NbrOfConversion = 1; // 只进行一次转换
    HAL_ADC_Init(&hadc1); // 初始化 ADC1
    // 配置光敏传感器通道
    sConfig.Channel = ADC_CHANNEL_0; // 设置通道为 ADC_CH0 (请根据实际情况选择)
    sConfig.Rank = ADC_REGULAR_RANK_1; // 设置为常规通道的第一个
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; // 采样时间设置为 3 个时钟周期
    HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 配置 ADC 通道
}
// USART 和 GPIO 的初始化代码省略
static void MX_USART1_UART_Init(void) {
    // 配置 UART 参数
    huart1.Instance = USART1; // 选择 USART1 实例
    huart1.Init.BaudRate = 9600; // 设置波特率为 9600
    huart1.Init.WordLength = UART_WORDLENGTH_8B; // 8 位数据长度
    huart1.Init.StopBits = UART_STOPBITS_1; // 1 个停止位
    huart1.Init.Parity = UART_PARITY_NONE; // 无奇偶校验
    huart1.Init.Mode = UART_MODE_TX_RX; // 同时支持发送和接收
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 禁用硬件流控制
    huart1.Init.OverSampling = UART_OVERSAMPLING_16; // 16 倍过采样
    HAL_UART_Init(&huart1); // 初始化 USART1
}
// GPIO 初始化函数
static void MX_GPIO_Init(void) {
    // GPIO 初始化代码根据具体需求进行配置
}
// 系统时钟配置函数
void SystemClock_Config(void) {
    // 系统时钟配置代码,设置主时钟源、分频器等
}
posted @ 2024-10-15 12:04  hazy1k  阅读(37)  评论(0编辑  收藏  举报