【基于stm32 FreeRtos的智能台灯控制】

基于stm32 FreeRtos的智能台灯控制

之前做了一个裸机版本的智能台灯,最近刚好复习一下FreeRto的一些基础知识,朋友发给了我一个功能需求刚好用来实践一下,需要的朋友可以自行下载。
完整工程下载链接

FreeRtos的引入

FreeRTOS是一个操作系统内核,提供操作系统最重要的特性:任务调度
操作系统允许多个任务同时运行,这个叫做多任务。实际上,一个处理器核心在某一时刻只能运行一个任务。 操作系统中任务调度器的责任就是决定在某一时刻究竟运行哪个任务, 任务调度在各个任务之间的切换非常快!
像 FreeRTOS 这种传统的 RTOS 类操作系统是由用户给每个任务分配一个任务优先级, 任务调度器就可以根据此优先级来决定下一刻应该运行哪个任务

单片机引入RTOS,可以将各个功能模块分别设计为单独的任务,每个任务都是一个死循环,就好比有多个人在同时干活,这样CPU的利用率就提高了,并且可以处理一些并行逻辑。
单片机只有一个CPU(核),那怎么让多个人同时干活呢?其实每个子任务虽然都是死循环,但并不是每个子任务一直都在执行,每个子任务在执行期间,可能需要延时,也可能需要等另一个任务的数据到来,所有,在某个任务在等待的时候,CPU就可以停止此任务,然后切换到其它任务执行,这样看起来就是多个人在同时干活了

在这里插入图片描述

想了解更多FreeRtos的知识需要的小伙伴可以去我专栏里面看哦,有基础实验测试,自己可以试试从
移值开始,这个工程的话都是移值好了FreeRtos 直接用就行了。

一、题目说明

在这里插入图片描述

二、功能说明

使用说明:
1.按键模式 也是上电默认的功能 在该功能下
PB6 直接用来控制灯的亮灭 第一次按下开灯 再次按下关灯
PB7 PB8 用来进行灯的亮度等级调节 一个变亮 一个变暗
PB9 按下后为定时模式 默认为定时5s时间到后会关闭灯光 并通过蜂鸣器进行5次提示
在定时模式的时候 PB6 PB7则为进行时间的调节  按键模式下为亮度的调节(PB6 PB7为两种功能的控制)

2、光敏模式:在该模式下灯光可以跟随环境的变化而自动调节

3、红外模式: 通过检测距离来进行灯光的控制

4、定时模式:到一定时间后自动关闭灯光 并以蜂鸣器实行进行提示
5、实时检测当前电压
6、超时波测距模式:也是通过距离的检测来控制灯光(该功能屏蔽了)
注意:按键是没有模式切换的只有按键 和定时可以控制所有进行其他模式切换时是以蓝牙控制
通过手机来控制的,语音同样可以进行模式切换和亮度控制

简单的焊接了一个方便调试

在这里插入图片描述

由于在进行OLED显示时刷新有点问题,所以将各模式下数据通过蓝牙发送到手机上了,以两种形式进行显示,实时电压值在手机上会一直打印 ,其他显示只有在进行相应功能切换时才打印

在这里插入图片描述

三、硬件部分

stm32f103c8t6最小系统1
oled (IIC)1
超声波1
光敏模块1
红外模块1
按键4
蜂鸣器1
蓝牙HC-051
语音模块SU-03T1
杜邦线若干
1.stm32f103c8t6

在这里插入图片描述

2.oled显示屏

在这里插入图片描述

3.su-03t语音模块

在这里插入图片描述

4.红外模块

在这里插入图片描述

5.超声波模块

在这里插入图片描述

6.光敏模块

在这里插入图片描述

7.蓝牙模块

在这里插入图片描述

8.蜂鸣器

在这里插入图片描述

四、硬件接线

1.PB6 PB7 PB8 PB9 接四个按键
2.oled PB13--CLK  PB14--DIN
3.光敏 A0---PA4
4.LED -- PB5
5.超声波 Trig--PB10  ECHO--PB11 
6.蜂鸣器 -- PC14
7.红外模块--PB4
8.电压 ---PA5
9.蓝牙-- TX-PA3 RX--PA2  
10.语音 TX-PA10 RX--PA9

五、软件部分

下面代码为主函数内容,需要完整工程大家可以自行下载

/*=============================基于FreeRtos的智能台灯======================

@Author;小殷童鞋
@Date:2022-11-25

===========================================================================*/

/**********************************引脚接线**********************************
按键 PB6 PB7 PB8 PB9
OLED GND VCC  PB13-CLK PB14-DIN
光敏 PA4
LED PB5
超声波 gnd vcc  Trig--PB10 Echo--PB11
蜂鸣器  PC14
蓝牙  TX--PA3(PA10)   RX--PA2(PA9)  
红外模块 PB4
电压  一端接PA5  一端接电源正极 
******************************************************************************/


/*=====================================功能说明=================================
1.默认界面显示按键模式  PB6 直接开关灯  PB7 PB8进行亮度调高调低  PB9为定时模式
按下PB9后 PB7 PB8的功能变为进行时间的加减  (这里PB7 PB8按键有两种功能)
2.光敏模式  界面只显示光敏界面
3.定时模式  显示时间 到时自动熄灭
4.红外距模式  
5.实时电压显示
注意:蓝牙和语音与其他模式互不影响
================================================================================*/

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"
#include "semphr.h"
#include "string.h"
#include "HC_SR04.h"
#include "beep.h"
#include "timer.h"
#include "ldr.h"
#include "infrared.h"
#include "oled.h"
#include "adc1.h"



/*================单独功能调试时只改变下面宏开关的值即可代码不动==================*/
//开关宏定义   1打开  0关闭

#define   USART_START           1
#define   CLOCK_START           1
#define   CSB_START             0           //超声波检测时有问题 暂时没用
#define   LDR_START             1
#define   KEY_START             1
#define   INFRARED_START        1
#define   INTERFACE_START       1

/*=================================任务宏定义====================================*/

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		512  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//按键任务
//任务优先级
#define BUTTON_TASK_PRIO		5
//任务堆栈大小	
#define BUTTON_STK_SIZE 		128  
//任务句柄
TaskHandle_t BUTTONTask_Handler;
//任务函数
void button_task(void *pvParameters);





//超声波任务
//任务优先级
#define CSB_TASK_PRIO		5
//任务堆栈大小	
#define CSB_STK_SIZE 		100  
//任务句柄
TaskHandle_t CSBTask_Handler;
//任务函数
void csb_task(void *pvParameters);




//串口数据处理任务
//任务优先级
#define USART_TASK_PRIO		6
//任务堆栈大小	
#define USART_STK_SIZE 		128  
//任务句柄
TaskHandle_t USARTTask_Handler;
//任务函数
void usart_task(void *pvParameters);



//定时任务
//任务优先级
#define CLOCK_TASK_PRIO		4
//任务堆栈大小	
#define  CLOCK_STK_SIZE 		50  
//任务句柄
TaskHandle_t  CLOCKTask_Handler;
//任务函数
void clock_task(void *pvParameters);



//光敏任务
//任务优先级
#define LDR_TASK_PRIO		2
//任务堆栈大小	
#define  LDR_STK_SIZE 		50  
//任务句柄
TaskHandle_t LDRTask_Handler;
//任务函数
void ldr_task(void *pvParameters);




//红外任务
//任务优先级
#define INFARED_TASK_PRIO		4
//任务堆栈大小	
#define  INFARED_STK_SIZE 		50  
//任务句柄
TaskHandle_t INFAREDTask_Handler;
//任务函数
void  infrared_task(void *pvParameters);



//界面显示任务
//任务优先级
#define INTERFACE_TASK_PRIO		3
//任务堆栈大小	
#define  INTERFACE_STK_SIZE 		50  
//任务句柄
TaskHandle_t INTERFACETask_Handler;
//任务函数
void  interface_task(void *pvParameters);






//========================================变量定义================================*/

#define Dis      50                    //实时距离小于DIS的时候灯打开 
#define Set_Dis  20                    //距离预设  可根据实际情况进行修改
unsigned char Usart1_cmd = 0;           //用来接收蓝牙和语音的指令
unsigned int current_duty = 0;        //当前占空比 默认关闭
unsigned char clock_start = 0;            //功能模式
unsigned char sec;                      //秒
unsigned char min;                      //分
unsigned char hour;                     //时
unsigned int count,clock_flag = 0;      //计数变量   时间到标志
unsigned int set_time = 5;              //默认为5s
unsigned char time[6];                  //存储时间转换后的值
unsigned char adcx; //光敏值 0-100
unsigned char work_mode = 1,send_flag = 1; //模式变量  发送到蓝牙的标志
float voltage = 0.0;                     //电压
char str[24];                           //存储信息字符串的形式显示
void Buzzer_Voice(void);                //蜂鸣器提示声音
void Init_interface(void);              //初始化界面
void Time_Display(void);                 //定时显示界面
void KEY_Display(void);                  //按键显示界面
void Infrared_Display(void);             //红外显示界面
void LDR_Display(void);                  //光敏界面
void VoltageDisplay(void);               //电压显示


/*==================================功能界面显示函数===============================*/
//初始化界面
void Init_interface(void)
{
		OLED_ShowCHinese(6,0,0);//智
		OLED_ShowCHinese(26,0,1);//能
		OLED_ShowCHinese(46,0,2);//台
		OLED_ShowCHinese(66,0,3);//灯
		OLED_ShowCHinese(86,0,4);//系
		OLED_ShowCHinese(106,0,5);//统	 
		OLED_ShowNum(6,4,2022,4,16);
		OLED_ShowCHinese_TWO(40,4,0);//年 
		OLED_ShowNum(60,4,11,2,16);
		OLED_ShowCHinese_TWO(74,4,1);//月 
		OLED_ShowNum(92,4,17,2,16);
		OLED_ShowCHinese_TWO(108,4,2);//日 
}

//定时模式显示定时的时间
void Time_Display(void)
{

	 OLED_ShowCHinese(26,0,12);//定
	 OLED_ShowCHinese(46,0,13);//时
	 OLED_ShowCHinese(66,0,14);//模
	 OLED_ShowCHinese(86,0,15);//式
	 OLED_ShowNum(30,3,time[0],2,4);
	 OLED_ShowNum(38,3,time[1],2,4);
	 OLED_ShowChar(46,3,':',4);
	 OLED_ShowNum(52,3,time[2],2,4);
	 OLED_ShowNum(60,3,time[3],2,4);
	 OLED_ShowChar(68,3,':',4);
	 OLED_ShowNum(74,3,time[4],2,4);
	 OLED_ShowNum(82,3,time[5],2,4);	
   //电压显示
	 OLED_ShowString(10,6,(unsigned char *)str,8);
}

//按键模式
void KEY_Display(void)
{
	 OLED_ShowCHinese(26,3,10);//按
	 OLED_ShowCHinese(46,3,11);//键
	 OLED_ShowCHinese(66,3,14);//模
	 OLED_ShowCHinese(86,3,15);//式
	  //电压显示
	 OLED_ShowString(10,6,(unsigned char *)str,8);
}

//光敏模式模式
void LDR_Display(void)
{
	 OLED_ShowCHinese(26,3,6);//光
	 OLED_ShowCHinese(46,3,7);//敏
	 OLED_ShowCHinese(66,3,14);//模
	 OLED_ShowCHinese(86,3,15);//式
	  //电压显示
	 OLED_ShowString(10,6,(unsigned char *)str,8);
}

//红外模式
void Infrared_Display(void)
{
	 OLED_ShowCHinese(26,3,8);//红
	 OLED_ShowCHinese(46,3,9);//外
	 OLED_ShowCHinese(66,3,14);//模
	 OLED_ShowCHinese(86,3,15);//式
	  //电压显示
	 OLED_ShowString(10,6,(unsigned char *)str,8);
}


//电压显示
void VoltageDisplay(void)
{
//	 OLED_ShowCHinese(26,5,20);//当
//	 OLED_ShowCHinese(46,5,21);//前
//	 OLED_ShowCHinese(66,5,22);//电
//	 OLED_ShowCHinese(86,5,23);//压
	  OLED_ShowString(10,6,(unsigned char *)str,8);
}



/*=====================================主函数及功能函数================================*/

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	
	delay_init();	    			     	 //延时函数初始化	 
	Init_Usart();					         //初始化串口
	LED_Init();		  					     //初始化LED
	KEY_GPIO_INIT();               //按键初始化
	HC_SR04_init();                //超声波初始化
	init_timer4_exti();            //定时器中断
	Buzzer_GPIO_Init();            //蜂鸣器初始化
	Lsens_Init();                  //光敏初始化
	Infrared_Init();               //红外初始化
	Power_init();                  //ADC1初始化  测电压
	OLED_Init();			             //初始化OLED  
	OLED_Clear(0);	
	TIM3_PWM_Init(100-1,7200-1);	//pwm控制初始化 1hkz  计数到100为10ms	 
	Init_interface(); 						 //初始化界面只显示一次
	delay_ms(1000);	

	//printf("----------------测试---------------\r\n");
	 
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	

#if KEY_START
    //创建按键任务
    xTaskCreate((TaskFunction_t )button_task,     	
                (const char*    )"button_task",   	
                (uint16_t       )BUTTON_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )BUTTON_TASK_PRIO,	
                (TaskHandle_t*  )&BUTTONTask_Handler);     
#endif
	
#if CSB_START
	
		//创建超声波任务
		xTaskCreate((TaskFunction_t )csb_task,     
                (const char*    )"csb_task",   
                (uint16_t       )CSB_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )CSB_TASK_PRIO,
                (TaskHandle_t*  )&CSBTask_Handler);    
#endif



#if USART_START
								
			//创建串口处理任务
		xTaskCreate((TaskFunction_t )usart_task,     
                (const char*    )"usart_task",   
                (uint16_t       )USART_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )USART_TASK_PRIO,
                (TaskHandle_t*  )&USARTTask_Handler);  
#endif
								
#if CLOCK_START							
		//创建定时处理任务
		xTaskCreate((TaskFunction_t )clock_task,     
                (const char*    )"clock_task",   
                (uint16_t       )CLOCK_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )CLOCK_TASK_PRIO,
                (TaskHandle_t*  )&CLOCKTask_Handler);  
#endif

#if LDR_START 								
				//创建光敏处理任务
		xTaskCreate((TaskFunction_t )ldr_task,     
                (const char*    )"ldr_task",   
                (uint16_t       )LDR_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LDR_TASK_PRIO,
                (TaskHandle_t*  )&LDRTask_Handler);  
#endif


#if INFRARED_START 								
				//创建光敏处理任务
		xTaskCreate((TaskFunction_t )infrared_task,     
                (const char*    )"infrared_task",   
                (uint16_t       )INFARED_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )INFARED_TASK_PRIO,
                (TaskHandle_t*  )&INFAREDTask_Handler);  
#endif


#if INTERFACE_START 								
				//创建界面现实处理任务
		xTaskCreate((TaskFunction_t )interface_task,     
                (const char*    )"interface_task",   
                (uint16_t       )INTERFACE_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )INTERFACE_TASK_PRIO,
                (TaskHandle_t*  )&INTERFACETask_Handler);  
#endif

    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}



//按键声响声音  m每次按下按键会有一声按键声响
void Buzzer_Voice(void)
{
		  Buzzer_ON();
			delay_ms(200);
		  Buzzer_OFF();			
    	delay_ms(200);
}


#if KEY_START
//按键任务函数 
void button_task(void *pvParameters)
{
	u8 key = 0;
	static u8 flag = 0;
	while(1)
    {
			if(work_mode == 1)
			{
				 //需要进行调试的时候可将其打开串口观察是否运行
			//	printf("==================按键模式==================\r\n");
				key = KEY_Scan();
				//进行定时模式
				if(key == KEY0_Value)  //PB9  KEY0_Value 
				{
						Buzzer_Voice();            //按键提示音
						clock_start = 1;// 开始计时
						hour = 0,min = 0,sec = 0;  //每次都从0开始
						
				}
				
				//clock_start 为0 时表示进行灯光占空比的控制 为1时为时间的控制
				if(clock_start == 0)
				{
						//亮度调高
					 if(key == KEY1_Value)
						{
							 Buzzer_Voice();            //按键提示音
							//调整亮度 变量
							current_duty += 20;                     //可根据实际效果进行修改
							printf("current_duty = %d\r\n",current_duty);
							//printf("this is key1 = %d\r\n",key);  //需要进行按键检测调试时可将其打开					
						}		
						//亮度调低
						else if(key == KEY2_Value)
						{
							Buzzer_Voice();            //按键提示音
							//调整亮度  变暗
							current_duty -= 20;
							printf("current_duty = %d\r\n",current_duty);
							//printf("this is key2 = %d\r\n",key);  //需要进行按键检测调试时可将其打开
							
						}		
					}
				
				
				else if(clock_start == 1)
				{
					if(key == KEY1_Value)
						{
							 Buzzer_Voice();            //按键提示音
							//调整时间  ++
							set_time += 5;                     //可根据实际效果进行修改
							//printf("this is key1 = %d\r\n",key);  //需要进行按键检测调试时可将其打开					
						}		
						//亮度调低
						else if(key == KEY2_Value)
						{
							Buzzer_Voice();            //按键提示音
							//时间 --
							set_time -= 5;
							//printf("this is key2 = %d\r\n",key);  //需要进行按键检测调试时可将其打开
						}		
				}
			
					
					
						//直接控制LED的亮灭 第一次按下亮 再次按下熄灭
					 if(key == KEY3_Value)
						{
							Buzzer_Voice();            //按键提示音
							if(flag == 0)
							{
								flag = 1;
								current_duty = 100;   //占空比最大亮
							}
							else if(flag == 1)
							{
								 flag = 0;
								 current_duty = 0;    //占空比最小 熄灭
							}
							printf("current_duty = %d\r\n",current_duty);
							//printf("this is key2 = %d\r\n",key);  //需要进行按键检测调试时可将其打开				
						}
					}
					
      vTaskDelay(120);
    }
}   
#endif


#if LDR_START 	
//光敏任务函数 
void ldr_task(void *pvParameters)
{
		while(1)
		{
			if(work_mode ==2)
			{
				 //需要进行调试的时候可将其打开串口观察是否运行
				//printf("==================光敏模式==================\r\n");
				adcx = Lsens_Get_Val();
				//根据光敏强度自动调节灯光的亮度  这里分为5个等级
				if(adcx > 0  && adcx < 20 )
				{
					current_duty = 100;
					
				}
				else if(adcx >= 20 && adcx < 40)
				{
					current_duty = 80;
				}
				else if(adcx >= 40 && adcx < 60)
				{
					current_duty = 60;
				}
				else if(adcx >= 60 && adcx < 80)
				{
					current_duty = 40;
				}
				else if(adcx >= 80 && adcx < 100)
				{
					current_duty = 20;
				}
				TIM_SetCompare2(TIM3,current_duty);
				printf("adcx = %d\r\n",adcx);
			}
			 vTaskDelay(40);
		}
}
#endif



#if CSB_START
//超声波任务函数 
void csb_task(void *pvParameters)
{
	float distance = 0;
	unsigned char i = 0;
	while(1)
    {
				if(work_mode == 5)
				{
				 distance = Get_HS_Length_Value();
				 if(distance < Set_Dis)   //SSet_Dis 宏定义可自己更改数值
				 {
					 for(i = 0;i<5;i++)
					 {
						 Buzzer_Voice();       //报警声响
					 }		
				 }
				 
				 //处于开灯的范围
				 if(distance < Dis)
				 {
					 current_duty = 100;
					}
				  printf("distance = %.2f\r\n",distance);  //进行串口调试的时候将其打开
				}
				vTaskDelay(80);
    }
}   
#endif


#if USART_START

//串口功能接收函数

//注意下面 cmd_temp 后面的十六进制可根据自己的指令来更改

void usart_task(void *pvParameters)
{
	 unsigned char cmd_temp = 0;
		while(1)
		{
			//后面的命令有根据自己来进行调节最后写十六进制
			cmd_temp = Usart1_cmd;
			Usart1_cmd = 0;   //清除
		
			if(cmd_temp == 0x01)   //板载LED PC13
			{
				LED = 0;             //PC13 打开
			}
			else if(cmd_temp == 0x02)
			{
				LED = 1;             //PC13 关闭
				
			}		
			
			/*==========================下面指令是控制我们用的LED (PWM控制)===========================*/
			else if(cmd_temp == 0x03)     //直接打开 最亮 占空比百分百
			{
				 current_duty = 100;
			}
			else if(cmd_temp == 0x04)     //直接关闭 最暗  占空比最小 0
			{
				 current_duty = 0;
			}
			else if(cmd_temp == 0x05)    //占空比控制 加加
			{
				 current_duty += 20;       //这里的数字可根据实际效果写大或者写小
			}
			else if(cmd_temp == 0x06)     //占空比控制 --
			{
				current_duty -= 20;        //这里的数字可根据实际效果写大或者写小
			}
			
			
			//==========================模式切换命令============================
			else if(cmd_temp == 0xea)
			{
				 work_mode = 1;   //按键模式		
				 send_flag = 1;
			}
			else if(cmd_temp == 0xeb)
			{			
				work_mode = 2;   //光敏模式
				send_flag = 2;
			}
			//在时间设置模式下才能进行时间的修改
			else if(cmd_temp == 0xec)
			{
				work_mode = 3;
				send_flag = 3;
				clock_start = 1;// 开始计时
				hour = 0,min = 0,sec = 0;  //每次都从0开始
				//时间增加 每次加5s  可自己修改数值
			}
			//红外
			else if(cmd_temp == 0xed)
			{
         work_mode = 4;
				 send_flag = 4; 
				
			}
			//超声波
			else if(cmd_temp == 0xff)
			{
         work_mode = 5;
			 	send_flag = 5;
				
			}

			else if(cmd_temp == 0x07)     
			{
				 set_time += 5;
				//	printf("set_time = %d\r\n",set_time);
			}
				
			//时间--每次-5s  可自己修改数值
			else if(cmd_temp == 0x08)  
			{
				set_time -= 5;
			//	printf("set_time = %d\r\n",set_time);
			}
			TIM_SetCompare2(TIM3,current_duty);
			printf("current_duty = %d\r\n",current_duty);
			vTaskDelay(120);
	}
}
#endif

#if CLOCK_START
//定时任务函数 
void clock_task(void *pvParameters)
{
	unsigned char i = 0;
	while(1)
	{
	
			//定时时间到了 灯自动熄灭 蜂鸣器给个提示音
			if(clock_flag == 1)
			{
					 //需要进行调试的时候可将其打开串口观察是否运行
					//printf("==================定时模式==================\r\n");
					printf("==============时间到了==============\r\n");
				  USART_Send_String(USART2,"time over");
				  clock_flag = 0;   //重新置0  等待下一次
					current_duty = 0;
					for(i = 0;i< 5;i++)
					{
						Buzzer_Voice(); 
					}
					
			}
			 vTaskDelay(50);
    }
}   

#endif


#if INFRARED_START
//红外人体感应功能测试
//感应到人体输出高电平,离开感应区域输出低电平
void infrared_task(void *pvParameters)
{
	
	while(1)
	{
			//定时时间到了 灯自动熄灭 蜂鸣器给个提示音
			if(work_mode == 4)
			{
				 //需要进行调试的时候可将其打开串口观察是否运行
				//printf("==================红外模式==================\r\n"); 
				if(Read_STATE() == RESET)  //检测到人了 开灯
				{
					current_duty = 100;
				}
				else
				{
					current_duty = 0;
				}
				
			}
			TIM_SetCompare2(TIM3,current_duty);	
			 vTaskDelay(50);
    }
}

#endif


#if INTERFACE_START


//下面发送到蓝牙放的数据可根据自己需求 也可以屏蔽掉
void interface_task(void *pvParameters)
{
	static unsigned char temp_mode = 1;
	while(1)
	{
			if(temp_mode != work_mode)
			{
				OLED_Clear(0);
				temp_mode = work_mode;
			}
			if(work_mode == 1)
			{
				//按键模式
				KEY_Display();
				if(send_flag ==1)
				{
					send_flag = 0; 
				  USART_Send_String(USART2,"========按键模式=======\r\n");
				}
			}
			else if(work_mode == 2)
			{
				 //光敏模式
				 LDR_Display();
				if(send_flag == 2)
				{
					send_flag = 0;
					USART_Send_String(USART2,"========光敏模式=======\r\n");
				}
			}
			else if(work_mode == 3)
			{
				//定时模式
				Time_Display();
				if(send_flag == 3)
				{
					send_flag = 0;
				  USART_Send_String(USART2,"========定时模式=======\r\n");
				}
			}
			else if(work_mode == 4)
			{
				//红外模式 
				Infrared_Display();
				if(send_flag == 4)
				{
					send_flag = 0;
					USART_Send_String(USART2,"========红外模式=======\r\n");
				}		
			}	
			 vTaskDelay(200);
    }
}

#endif

/*-------------------------------串口中断服务函数-------------------------*/
//串口1接收  PA9 PA10   语音模块
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
	{
		Usart1_cmd = USART_ReceiveData(USART1);
		USART_SendData(USART1,Usart1_cmd);
		USART_ClearFlag(USART1, USART_FLAG_RXNE);
	}
}


//l蓝牙 RX-  PA2  TX-PA3
void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    {
       Usart1_cmd = USART_ReceiveData(USART2);				
			 USART_ClearFlag(USART2, USART_FLAG_RXNE);
    }
}





void TIM3_IRQHandler(void)   //TIM3中断
{
	static unsigned int volt_t = 0;          //控制电压检测时间 2s检测一下电压
	char str_t[24];                          //发送时间到蓝牙
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
				TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志  //10ms
				volt_t++;
			if(volt_t == 200)
			{
				volt_t = 0;   //计数清零
				voltage = Power_Get_VBAT();
				sprintf(str,"volt:%.2f\r\n",voltage);
				USART_Send_String(USART2,str);
				//printf("voltage = %.2f\r\n",voltage);  //需要用串口进行观察时将其打开
			}
			  if(clock_start == 1)  //定时模式 开始进行计时
				{
					count++;
					if(count == 100)
					{
						count = 0;
					
						sec++;
						if(sec == 60)
						{
							sec = 0;
							min++;
							if(min== 60)
							{
								min = 0;
								hour++;
								if(hour == 24)
								{
									hour = 0;
								}
							}
						}
					sprintf(str_t,"%02d:%02d:%02d\r\n",hour,min,sec);
					USART_Send_String(USART2,str_t);
					//	printf("%2d:%2d:%2d\r\n",hour,min,sec);
					}
					time[0] = hour/10; //获取小时的十位
					time[1] = hour%10;//获取小时的个位
					time[2] = min/10; //获取分钟的十位
					time[3] = min%10;//获取分钟的个位
					time[4] = sec/10; //获取秒的十位
					time[5] = sec%10; //获取秒的个位
					if(hour *24 + min *60 + sec == set_time)   //计时时间与我们设定的时间相等
					{
						 clock_flag = 1;           //标志置1
						  clock_start = 0;          //停止计时				
					}	
					
				}
			}
}
  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值