原本是打算应用于测试机架设备,专门检测灯光有无闪烁,及灯光的闪烁次数,但后面没有实际使用。
灯光检测的灵敏度可以通过电位器调节。
代码实现功能,通过主要利用光敏电阻的模块直接接DO口到单片机,单片机直接通过IO检测光敏模块的TTL电平,然后通过电位变化检测灯是否闪烁并且可以返回在限定时间能共闪烁多少次。
#include "led.h"
//初始化PA1为输入下拉口.并使能这个口的时钟
//LED IO初始化
extern uint8_t count;
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //LED2-->PC13 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为10MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化PA1
}
/*******************************************************************************
* 函数名:GetLED_Flash
* 功 能:获得LED灯在N秒内的闪烁次数
* 参 数:time 设置时间 temp[0]保存状态,temp[1]保存次数
* 返回值:无
* 说 明:
*******************************************************************************/
void GetLED_Flash(uint8_t time,uint8_t *temp)
{
u8 Flag=0;
memset(temp,0,sizeof temp); //清空数组
TIM_Cmd(TIM3, ENABLE); //使能TIM3
while(1)
{
while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)) //灯光变亮
{
if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)) Flag=1; //灯光变进入循环
if(count>time*10)break; //超时退出
}
delay_ms(10); //消抖
if( Flag==1&&GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)) //变亮标志与变暗同时成立则记录闪烁
{
temp[1]++;
}
Flag = 0; //标志位清0
if(temp[1]>0)temp[0]=1; //闪烁超1次记录为闪烁
if(count>time*10)break; //超时退出
}
TIM_Cmd(TIM3, DISABLE); //关闭TIM3
count=0; //超时计数清0
}
头文件
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
#include "usart.h"
#include "string.h"
void LED_Init(void);//初始化
void GetLED_Flash(uint8_t time,uint8_t *temp);
#endif
#include "timer.h"
#include "led.h"
uint8_t count;
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
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( //使能或者失能指定的TIM中断
TIM3, //TIM2
TIM_IT_Update ,
ENABLE //使能
);
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寄存器
}
void TIM3_IRQHandler(void) //TIM3中断
{
/***检查指定的TIM中断发生与否:TIM 中断源 ***/
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
/***清除TIMx的中断待处理位:TIM 中断源 ***/
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
count++;
}
}
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
#include "usart.h"
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "adc.h "
#include "string.h"
#include "timer.h"
uint16_t result;
int main(void)
{
float voltage;
uint8_t temp[2]={0};
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口初始化为9600
LED_Init();;
TIM3_Int_Init(999,7199);//10Khz的计数频率,计数到999为1000ms
printf("hello world!");
while(1)
{
GetLED_Flash(3,temp); //闪烁3s然后判断
printf("闪烁:%d\n",temp[0]);
printf("次数:%d\n",temp[1]);
delay_ms(1000);
}
}