帮我写一个stm32f103c8t6用光敏电阻根据电压转为光照强度的值控制灯亮灭的代码
时间: 2023-08-29 09:06:06 浏览: 141
好的,以下是基于STM32F103C8T6的光敏电阻控制灯亮灭的代码,代码中使用ADC采集光敏电阻的电压值,然后根据电压值转换为对应的光照强度,并控制灯的状态:
```
#include "stm32f10x.h"
#define ADC1_DR_Address ((u32)0x4001244C)
void ADC1_Init(void);
u16 Get_ADC(u8 ch);
int main(void)
{
u16 adc_value;
float voltage_value, light_intensity;
//初始化LED引脚为输出模式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//初始化ADC
ADC1_Init();
while (1)
{
//获取光敏电阻电压值
adc_value = Get_ADC(ADC_Channel_0);
voltage_value = (float)adc_value * 3.3 / 4096; //计算电压值
//根据电压值转换为对应的光照强度
light_intensity = voltage_value / 0.01;
//控制灯的状态
if (light_intensity > 50)
GPIO_ResetBits(GPIOC, GPIO_Pin_13); //灯灭
else
GPIO_SetBits(GPIOC, GPIO_Pin_13); //灯亮
}
}
//ADC初始化函数
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); //使能GPIOA和ADC1时钟
//配置ADC1通道0的GPIO引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//DMA传输配置
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&adc_value; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设到内存
DMA_InitStructure.DMA_BufferSize = 1; //DMA通道的数据缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址寄存器不变
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道x
//ADC1配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目为1
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //ADC1通道0,采样时间为55.5周期
ADC_DMACmd(ADC1, ENABLE); //使能ADC的DMA请求
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1))
; //等待ADC1校准重置完成
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1))
; //等待ADC1校准完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1的软件转换启动
}
//获取ADC采集值
u16 Get_ADC(u8 ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5); //配置ADC1的通道ch,采样时间为55.5周期
DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA传输
while (!DMA_GetFlagStatus(DMA1_FLAG_TC1))
; //等待DMA传输完成
DMA_Cmd(DMA1_Channel1, DISABLE); //禁止DMA传输
DMA_ClearFlag(DMA1_FLAG_TC1); //清除DMA传输完成标志位
return adc_value; //返回ADC采集的值
}
```
需要注意的是,代码中的光照强度计算方法仅供参考,具体计算方法需要根据光敏电阻的特性曲线来确定。同时,代码中的GPIO引脚和ADC通道需要根据实际的硬件连接进行修改。
阅读全文