找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 336|回复: 4
打印 上一主题 下一主题
收起左侧

这是stm32根据环境亮度自动调节灯光亮度的代码,跑不起来求大佬看一看

[复制链接]
跳转到指定楼层
楼主
ID:1039168 发表于 2023-12-13 09:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下载到单片机里灯闪一下就灭了,不知道是什么原因main.c


#include "led.h"
#include "delay.h"
#include "sys.h"
#include "adc.h"
#include "lsens.h"
#include "timer.h"
   
u8 adcx=0;                           //光敏传感器ADC转换值


int main(void)
{         
        delay_init();                          //延时函数初始化          
        LED_Init();                                      //初始化与LED连接的硬件接口
                            
        Lsens_Init();                               //初始化光敏传感器
       
        TIM3_PWM_Init(100,0);
        TIM4_Int_Init(1999,35999);
                      
   
         while(1)
                        {
                        adcx=Lsens_Get_Val();
                                       
                                if((adcx>0)&&(adcx<=20))                        //当前环境亮度小于20,灯光亮度调至最高的第五档
                                {
                                        TIM_SetCompare2(TIM3,100);
                                        delay_ms(10);
                                }
                                if((adcx>20)&&(adcx<=40))                       //当前环境亮度小于40大于20,灯光亮度调至第四档
                                {
                                        TIM_SetCompare2(TIM3,80);
                                        delay_ms(10);
                                }
                                if((adcx>40)&&(adcx<=60))                       //当前环境亮度小于60大于40,灯光亮度调至第三档
                                {
                                        TIM_SetCompare2(TIM3,60);
                                        delay_ms(10);
                                }
                                if((adcx>60)&&(adcx<=80))                        //当前环境亮度小于80大于60,灯光亮度调至第二档
                                {
                                        TIM_SetCompare2(TIM3,40);
                                        delay_ms(10);
                                }
                                if((adcx>80)&&(adcx<=95))                        //当前环境亮度小于95大于80,灯光亮度调至第一档
                                {
                                        TIM_SetCompare2(TIM3,20);
                                        delay_ms(10);
                                }
                                if((adcx>95)&&(adcx<=100))                       //当前环境亮度小于100大于95,关闭灯光
                                {
                                        TIM_SetCompare2(TIM3,0);
                                        delay_ms(10);
                                }
                        }
       
}




adc.c


#include "delay.h"
#include "sys.h"


//初始化ADC1
                                                                                                                                          
void  Adc1_Init(void)
{      
        ADC_InitTypeDef ADC_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟
       
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);//ADC复位
       
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);//复位结束            
       
        ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1的全部寄存器重设为缺省值
       
       
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式: 独立模式
        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数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器  


       
        ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1
       
        ADC_ResetCalibration(ADC1);        //使能复位校准  
         
        while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束
       
        ADC_StartCalibration(ADC1);         //开启AD校准

        while(ADC_GetCalibrationStatus(ADC1));         //等待校准结束
}                 
//获得ADC1某个通道的值
//ch:通道值 0~16
//返回值:转换结果
u16 Get_Adc1(u8 ch)   
{
  //设置指定ADC的规则组通道,一个序列,采样时间
        ADC_RegularChannelConfig(ADC1,ch,1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采样时间为239.5周期                                      
  
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能       
         
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束


        return ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果
}



lsens.c光敏电阻


#include "lsens.h"
#include "delay.h"

//初始化光敏传感器
void Lsens_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
       
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTF时钟       
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PF8 anolog输入
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOA, &GPIO_InitStructure);       
        Adc1_Init();
}
//读取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_Adc1(LSENS_ADC_CHX);        //读取ADC值
                delay_ms(5);
        }
        temp_val/=LSENS_READ_TIMES;//得到平均值
        if(temp_val>4000)temp_val=4000;
        return (u8)(100-(temp_val/40));
}


timer.c

#include "timer.h"
#include "led.h"
#include "usart.h"
#include "lsens.h"
#include "adc.h"
#include "lsens.h"           
//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数




void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能


        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断


        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


        TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
                                                         
}




//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                {
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
                LED0=!LED0;
                }
}


//TIM3 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
       


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //使能定时器3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
       
        GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   

   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形        GPIOB.5
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

   //初始化TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        //初始化TIM3 Channel2 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OCInitStructure.TIM_Pulse=0;
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2


        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器

        TIM_Cmd(TIM3, ENABLE);  //使能TIM3
       


}


void TIM4_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能


        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断


        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


        TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设
                                                         
}
void PWM_SetCompare1(uint16_t Compare)
{
        TIM_SetCompare1(TIM2, Compare);
}





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2023-12-13 09:41 | 只看该作者
没接光敏传感器。
回复

使用道具 举报

板凳
ID:895440 发表于 2023-12-13 09:52 | 只看该作者
跑不起来的现象是什么?是编译不通过还是不会自动调整
回复

使用道具 举报

地板
ID:94031 发表于 2023-12-13 10:24 | 只看该作者
这和光敏电阻特性有关,自己要根据实际光敏电阻特性修改一下程序。
回复

使用道具 举报

5#
ID:958310 发表于 2023-12-13 11:16 | 只看该作者
把ADC值打印出来看跑到哪个步骤。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表