#include "led.h" #include "delay.h" #include "sys.h" #include "stm32f10x.h" #include "stdio.h" #include "key.h" #include "usart.h" #include "drive_dht11.h" #include "bh1750.h" #include "ds1302.h" #include "oled.h" #include "sk9822.h" #include "string.h" u8 humi=0;//湿度值 u8 temp=0;//温度值 u8 buffer[10]={0}; u16 GzVal=0; //实际光照值 char ShowBuf[16]={0}; char DateShowBuf[30]={0}; char SendBuff[50]={0}; short TEMP = 0; u16 cj_val=0;//测距值 u8 openflag=0;//手动模式开关按钮 u8 mode_flag=0; #define YP1 PCout(13) #define YP2 PCout(14) #define YP3 PCout(15) u8 warning_cnt=0; u16 GetTimer=0;//采集时间计数器 u8 dw_val=0;//挡位//亮度值 u8 sc_val=0;//色彩 int set_s1=7,set_f1=0; //设置 时间1 int cnt_s1=0,cnt_f1=0,cnt_m1=0;//学习时间 时分秒 #define RT_INPUT PBin(8)//人体红外感应 #define YP_BUSY PAin(6) #define KEY_GPIO_PROT GPIOA #define KEY1_GPIO_PIN GPIO_Pin_0 #define KEY2_GPIO_PIN GPIO_Pin_1 #define KEY3_GPIO_PIN GPIO_Pin_2 #define KEY4_GPIO_PIN GPIO_Pin_3 #define KEY5_GPIO_PIN GPIO_Pin_4 #define KEY1_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY1_GPIO_PIN) #define KEY2_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY2_GPIO_PIN) #define KEY3_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY3_GPIO_PIN) #define KEY4_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY4_GPIO_PIN) #define KEY5_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY5_GPIO_PIN) void key_gpio_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN|KEY3_GPIO_PIN|KEY4_GPIO_PIN|KEY5_GPIO_PIN|GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(KEY_GPIO_PROT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } #define Trig PBout(10) // 超声波测距 #define CW_ECHO1 PBin(11) u16 Distance=0; //超声波端口初始化 void Wave_IO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB0接TRIG GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化外设GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //接ECH0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设为输入 GPIO_Init(GPIOB, &GPIO_InitStructure); TIM_DeInit(TIM2); TIM_TimeBaseStructure.TIM_Period=65535; /* 自动重装载寄存器周期的值(计数值) */ /* 累计 TIM_Period个频率后产生一个更新或者中断 */ TIM_TimeBaseStructure.TIM_Prescaler= (360 - 1); /* 时钟预分频数 72M/360 */ TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */ TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM2, TIM_FLAG_Update); /* 清除溢出中断标志 */ // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // //TIM2_NVIC_Configuration();//定时器初始化 //TIM2_Configuration(); } //void TIM2_IRQHandler() //{ // static u8 st; // st=TIM_GetFlagStatus(TIM2, TIM_IT_Update); // if(st!=0) // { // TIM_ClearFlag(TIM2, TIM_IT_Update); // } //} //测距 //开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间 u16 Wave_Start(void) { u32 Distance; u32 timeout=0; Trig=1; delay_us(20); //输入一个10us的高电平 Trig=0; TIM_SetCounter(TIM2,0); timeout=0; while(!CW_ECHO1) //等待高电平 { if(++timeout>60000)break; delay_us(1); } TIM_Cmd(TIM2, ENABLE); //开启时钟 timeout=0; while(CW_ECHO1) //等待低电平 { if(++timeout>600000)break; delay_us(1); } TIM_Cmd(TIM2, DISABLE); //定时器2失能 Distance=TIM_GetCounter(TIM2)*5*34/2000; //计算距离 厘米cm TIM_SetCounter(TIM2,0); if(Distance>200)Distance=200; return Distance; } void TIMER3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitStrue.TIM_Period=arr; TIM_TimeBaseInitStrue.TIM_Prescaler=psc; TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CounterMode_Up; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3更新中断 //中断优先级NVIC设置 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寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx } char clear_flag=0; int key_Task(void) { static char key_flag=0; if(KEY1_IN==0|KEY2_IN==0|KEY3_IN==0|KEY4_IN==0|KEY5_IN==0) { if(key_flag==0) { key_flag=1; if(KEY1_IN==0) { mode_flag^=1; } else if(KEY2_IN==0) { if(mode_flag==0) { if(++dw_val>2)dw_val=0; }else { cnt_s1++; } } else if(KEY3_IN==0) { if(mode_flag==0) { if(++sc_val>2)sc_val=0; }else { if(cnt_s1>0)cnt_s1--; } } else if(KEY4_IN==0) { if(mode_flag==0) { openflag^=1;//开关按钮 }else { } } else if(KEY5_IN==0) { clear_flag^=1; } } }else { key_flag=0; } return 20; } u16 DataUpTime=0;//时间显示计数器 u8 rt_flag=0;//红外人体标志位 u16 rt_cnt=0; u8 seccnt=0; void TIM3_IRQHandler(void)//中断服务程序 { if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)//SET为1 { GetTimer++;//采集计数器 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3的更新中断标志 key_Task(); DataUpTime++; if(RT_INPUT==1) //检测人体感应 { rt_flag=1; rt_cnt=0; }else { if(rt_cnt++>50*15)//15s没人了 { rt_cnt=0;rt_flag=0; } } if(rt_flag) //有人 开始计时计算学习时间 { if(++seccnt>=50) { seccnt=0; if(++cnt_m1>59) { cnt_m1=0; if(++cnt_f1>59) { cnt_f1=0; if(++cnt_s1>23) { cnt_s1=0; } } } } } } } u8 GetFlag=0; uint8_t sendBuff[16]={0}; void ShowTo(char* Pdat,char len)//字符串中的空格补 0 { char ixd=0; for(ixd=0;ixd>= 1; } IO_TX_GPIO_Port=1; delay_us(104); } void sendData(char *p,unsigned char n) { if( p == 0) return ; if(n > 0) { while(n --) { uartX_sendByte(*p++); } } } u8 test=0; unsigned char sendbuff1[8]={0x7E, 0x04 ,0x03 ,0x00, 0x01, 0xEF}; unsigned char sendbuff2[8]={0x7E, 0x04 ,0x03 ,0x00, 0x02, 0xEF}; unsigned char sendbuff3[8]={0x7E, 0x04 ,0x03 ,0x00, 0x03, 0xEF}; int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级 delay_init(); //延时函数初始化 LED_Init(); //初始化与连接的硬件接口 YP1=1;YP2=1;YP3=1; uart_init(9600); delay_ms(100); key_gpio_init(); TIMER3_Int_Init(20000,71);//定时器初始化 //10ms进一次中断 BH1750_Init(); OLED_Init();//液晶初始化 OLED_Clear();//液晶清屏 delay_ms(10);//上电延时一会 Ds1302_Gpio_Init(); SK9822_Intit(); Wave_IO_Init(); SK9822_Write_Data(0xff,0,0,0); // Ds1302_Write_Time_All(1); delay_ms(10); while(1) { if(GetTimer>50)//1S { GetTimer=0; if(openflag) { switch(dw_val) { case 0: switch(sc_val) { case 0: SK9822_Write_Data(0xff,0xff,0xff,0xff); break; case 1: SK9822_Write_Data(0xff,255,255,0); break ; case 2: SK9822_Write_Data(0xff,60,255,60); break; } break; case 1: switch(sc_val) { case 0: SK9822_Write_Data(0xff,125,125,125); break; case 1: SK9822_Write_Data(0xff,125,125,0); break ; case 2: SK9822_Write_Data(0xff,30,125,30); break; } break; case 2: switch(sc_val) { case 0: SK9822_Write_Data(0xff,30,30,30); break; case 1: SK9822_Write_Data(0xff,40,40,0); break ; case 2: SK9822_Write_Data(0xff,10,50,10); break; } break; } }else{ SK9822_Write_Data(0xff,0,0,0);//熄灭 } if(mode_flag)//自动模式下控制 { OLED_ShowString(90,6,"A",16); }else{ //手动模式下控制 OLED_ShowString(90,6,"M",16); } if(dht11_read_data(buffer) == 0)//读取温湿度 { humi = buffer[0] + buffer[1] / 10;//取湿度值 temp = buffer[2] + buffer[3] / 10;//取温度值 } GzVal = Dispose();//读取光照 cj_val=Wave_Start(); if(cj_val>15) { OLED_ShowText(0,6,"坐姿:异常",0); warning_cnt|=0x01; }else { warning_cnt&=~0x01; OLED_ShowText(0,6,"坐姿:正常",0); } if(rt_flag) //有人 { OLED_ShowString(103,6,"1",16); } else //没人 { OLED_ShowString(103,6,"0",16); } printf("drv_X%dH%dD%dZ%d\r\n",temp,humi,GzVal,cj_val);//发送到上位机app if(mode_flag)//自动模式 { if(rt_flag) //有人 { openflag=1; if(GzVal<50) { dw_val=0;//开启最大亮度 } else if(GzVal>50&&GzVal<500) { dw_val=1; } else if(GzVal>500) { dw_val=2; } }else { openflag=0;//关闭 } }else{ //手动模式 } } if(DataUpTime>20) //400ms刷新一次数据 { DataUpTime=0;// Ds1302_Readtime(); sprintf((char*)DateShowBuf,"时间:%2d:%2d:%2d", (int)ds1302Data.hour, (int)ds1302Data.min, (int)ds1302Data.sec); ShowTo(DateShowBuf,strlen(DateShowBuf)); OLED_ShowText(0,0,DateShowBuf,0); sprintf((char*)DateShowBuf,"闹钟:%2d:%2d:00", (int)set_s1, (int)set_f1); ShowTo(DateShowBuf,strlen(DateShowBuf)); OLED_ShowText(0,2,DateShowBuf,0); sprintf((char*)DateShowBuf,"学习:%2d:%2d:%2d", (int)cnt_s1, (int)cnt_f1,cnt_m1); ShowTo(DateShowBuf,strlen(DateShowBuf)); OLED_ShowText(0,4,DateShowBuf,0); if((ds1302Data.hour==set_s1)&&(ds1302Data.min==set_f1)) //到达闹钟时间 { warning_cnt|=0x02; } else { warning_cnt&=~0x02; } if(cnt_s1>=2) { warning_cnt|=0x04; }else{ warning_cnt&=~0x04; } if(clear_flag==0)//取消提醒标志位 { if((warning_cnt&0x01)==0x01) //坐姿异常 { if(YP_BUSY==0) { sendData((char*)sendbuff1,6); } } else if((warning_cnt&0x02)==0x02)//闹钟 { if(YP_BUSY==0) { sendData((char*)sendbuff2,6); } } else if((warning_cnt&0x04)==0x04)//学习时间过长 { if(YP_BUSY==0) sendData((char*)sendbuff3,6); } } } } }