文章目录
STM32单片机开发实现楼道声、光控制灯
1、STM32CubeIDE配置
###1、配置使能LED灯
这里我们使用LED灯模拟灯泡实现灯光控制,配置LED连接的相应CPU管脚,设置默认电平为高电平(灯状态为灭)
1.配置LED管脚
2.配置使能ADC
配置ADC1,使能IN15和IN16,选择Single-ended(Differential 为差分信号)。这时候PB0和PB1两个管脚设置为输入模式了,然后对管脚进行重命名。
ADC的时钟树最好不要设置的太高,这里调整为12MHZ;
2、 任意位置按Ctrl+s将开始自动生成代码
3.修改相关源代码
修改gpio.c代码实现LED灯
/* USER CODE BEGIN 2 */
typedef struct gpio_s
{
GPIO_TypeDef *group;
uint16_t pin;
}gpio_t;
gpio_t leds[LedMax]=
{
{RedLed_GPIO_Port, RedLed_Pin},
{GreenLed_GPIO_Port,GreenLed_Pin},
{BlueLed_GPIO_Port, BlueLed_Pin},
};//LED灯
gpio_t relays[RelayMax] =
{
{Relay_GPIO_Port, Realy_Pin},
};//继电器
void turn_led(int which, int status)
{
GPIO_PinState level;
if(which>=LedMax)
return ;
level = status==OFF ? GPIO_PIN_SET : GPIO_PIN_RESET;
HAL_GPIO_WritePin(leds[which].group,leds[which].pin,level);
}
void blink_led(int which, uint32_t interval)
{
turn_led(which,ON);
HAL_Delay(interval);
turn_led(which,ON);
HAL_Delay(interval);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static uint8_t relay_status=OFF;
if(Key1_Pin == GPIO_Pin)
{
blink_led(BlueLed,500);
}
else if(Key2_Pin == GPIO_Pin)
{
blink_led(RedLed,500);
}
}
头文件gpio.h里添加LED控制函数turn_led()和blink_led()的声明及相关枚举、宏定义:
/* USER CODE BEGIN Prototypes */
enum
{
RedLed,
GreenLed,
BlueLed,
LedMax,
};
enum
{
Relay,
RelayMax,
};
#define OFF 0
#define ON 1
/*函数说明:控制LED灯?/灭的功能函数
* 参数说明:which指定要控制哪个灯,取枚举里的?
* status要控制灯亮还是灭,取宏定?
* 返回值:无
*/
extern void turn_led(int which, int status);
/*函数说明:控制LED闪烁功能函数
* 参数说明:which指定要控制的灯?
* interval:指定闪烁的间隔时间,单位为毫秒
* 返回值: 无
*/
extern void blink_led(int which, uint32_t interval);
extern void turn_relay(int which,int status);
/* USER CODE END Prototypes */
修改adc.c文件,添加环境光强传感器和声音传感器实现;
/* USER CODE BEGIN 1 */
enum
{
ADCCHN_LUX,
ADCCHN_NOISY,
ADCCHN_MAX,
};
int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy)
{
uint8_t i;
uint32_t timeout=0xffffff;
for(i=0; i<ADCCHN_MAX; i++)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,timeout);
if(ADCCHN_LUX == i)
{
*lux=HAL_ADC_GetValue(&hadc1);
}
else if(ADCCHN_NOISY ==i)
{
*noisy=HAL_ADC_GetValue(&hadc1);
}
HAL_Delay(10);
}
HAL_ADC_Stop(&hadc1);
return 0;
}
/* USER CODE END 1 */
修改adc.h,添加ADC采样函数的声明
/* USER CODE BEGIN Includes */
extern int adc_sample_lux_noisy(uint32_t *lux,uint32_t *noisy);
/* USER CODE END Includes */
4.修改main.c源代码
实现功能
/* USER CODE BEGIN 1 */
uint32_t lux,noisy;
uint32_t start;
uint8_t light_status=0;
/* USER CODE END 1 */
/* USER CODE BEGIN WHILE */
//beep_start(2,300);
while (1)
{
if(OFF==light_status)
{
adc_sample_lux_noisy(&lux,&noisy);
printf("Lux[%lu] Noisy[%lu]\r\n",lux,noisy);
if(lux<800&& noisy>100)
{
printf("Turn light ON\r\n");
turn_led(RedLed,ON);
light_status=ON;
start = HAL_GetTick();
}
else
{
if(time_after(HAL_GetTick(),start+10000))
{
printf("Turn Light OFF\r\n");
turn_led(RedLed,OFF);
/*must give delay for turn relay off got noisy*/
HAL_Delay(200);
/*set light status as OFF*/
light_status=OFF;
}
}
}
HAL_Delay(500);
/* USER CODE END WHILE */
至此相关功能均已实现