main.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "stm32f10x.h"
  5. #include "stdio.h"
  6. #include "key.h"
  7. #include "usart.h"
  8. #include "drive_dht11.h"
  9. #include "bh1750.h"
  10. #include "ds1302.h"
  11. #include "oled.h"
  12. #include "sk9822.h"
  13. u8 humi=0;//湿度值
  14. u8 temp=0;//温度值
  15. u8 buffer[10]={0};
  16. u16 GzVal=0; //实际光照值
  17. char ShowBuf[16]={0};
  18. char DateShowBuf[30]={0};
  19. char SendBuff[50]={0};
  20. short TEMP = 0;
  21. u16 cj_val=0;//测距值
  22. u8 ld_val=0;//亮度值
  23. u8 openflag=0;//手动模式开关按钮
  24. int set_s1=7,set_f1=0; //设置 时间1
  25. int cnt_s1=0,cnt_f1=0,cnt_m1=0;//学习时间 时分秒
  26. #define RT_INPUT PBin(1)//人体红外感应
  27. #define KEY_GPIO_PROT GPIOA
  28. #define KEY1_GPIO_PIN GPIO_Pin_0
  29. #define KEY2_GPIO_PIN GPIO_Pin_1
  30. #define KEY3_GPIO_PIN GPIO_Pin_2
  31. #define KEY4_GPIO_PIN GPIO_Pin_3
  32. #define KEY5_GPIO_PIN GPIO_Pin_4
  33. #define KEY1_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY1_GPIO_PIN)
  34. #define KEY2_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY2_GPIO_PIN)
  35. #define KEY3_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY3_GPIO_PIN)
  36. #define KEY4_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY4_GPIO_PIN)
  37. #define KEY5_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY5_GPIO_PIN)
  38. void key_gpio_init(void)
  39. {
  40. GPIO_InitTypeDef GPIO_InitStructure;
  41. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
  42. GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN|KEY3_GPIO_PIN|KEY4_GPIO_PIN|KEY5_GPIO_PIN;
  43. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  44. GPIO_Init(KEY_GPIO_PROT, &GPIO_InitStructure);
  45. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  46. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  47. GPIO_Init(GPIOA, &GPIO_InitStructure);
  48. }
  49. #define Trig PBout(10) // 超声波测距
  50. #define CW_ECHO1 PBin(11)
  51. u16 Distance=0;
  52. //超声波端口初始化
  53. void Wave_IO_Init(void)
  54. {
  55. GPIO_InitTypeDef GPIO_InitStructure;
  56. // NVIC_InitTypeDef NVIC_InitStructure;
  57. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  58. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
  59. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE);
  60. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB0接TRIG
  61. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出模式
  62. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  63. GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化外设GPIO
  64. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //接ECH0
  65. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设为输入
  66. GPIO_Init(GPIOB, &GPIO_InitStructure);
  67. TIM_DeInit(TIM2);
  68. TIM_TimeBaseStructure.TIM_Period=65535; /* 自动重装载寄存器周期的值(计数值) */
  69. /* 累计 TIM_Period个频率后产生一个更新或者中断 */
  70. TIM_TimeBaseStructure.TIM_Prescaler= (360 - 1); /* 时钟预分频数 72M/360 */
  71. TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */
  72. TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */
  73. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  74. TIM_ClearFlag(TIM2, TIM_FLAG_Update); /* 清除溢出中断标志 */
  75. // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  76. // NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  77. // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  78. // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  79. // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  80. // NVIC_Init(&NVIC_InitStructure);
  81. //
  82. //TIM2_NVIC_Configuration();//定时器初始化
  83. //TIM2_Configuration();
  84. }
  85. //void TIM2_IRQHandler()
  86. //{
  87. // static u8 st;
  88. // st=TIM_GetFlagStatus(TIM2, TIM_IT_Update);
  89. // if(st!=0)
  90. // {
  91. // TIM_ClearFlag(TIM2, TIM_IT_Update);
  92. // }
  93. //}
  94. //测距
  95. //开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间
  96. u16 Wave_Start(void)
  97. {
  98. u32 Distance;
  99. u32 timeout=0;
  100. Trig=1;
  101. delay_us(20); //输入一个10us的高电平
  102. Trig=0;
  103. TIM_SetCounter(TIM2,0);
  104. timeout=0;
  105. while(!CW_ECHO1) //等待高电平
  106. {
  107. if(++timeout>60000)break;
  108. delay_us(1);
  109. }
  110. TIM_Cmd(TIM2, ENABLE); //开启时钟
  111. timeout=0;
  112. while(CW_ECHO1) //等待低电平
  113. {
  114. if(++timeout>600000)break;
  115. delay_us(1);
  116. }
  117. TIM_Cmd(TIM2, DISABLE); //定时器2失能
  118. Distance=TIM_GetCounter(TIM2)*5*34/2000; //计算距离 厘米cm
  119. TIM_SetCounter(TIM2,0);
  120. if(Distance>200)Distance=200;
  121. return Distance;
  122. }
  123. void TIMER3_Int_Init(u16 arr,u16 psc)
  124. {
  125. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
  126. NVIC_InitTypeDef NVIC_InitStructure;
  127. TIM_TimeBaseInitStrue.TIM_Period=arr;
  128. TIM_TimeBaseInitStrue.TIM_Prescaler=psc;
  129. TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;
  130. TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CounterMode_Up;
  131. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  132. TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);
  133. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3更新中断
  134. //中断优先级NVIC设置
  135. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
  136. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  137. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  138. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  139. NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
  140. TIM_Cmd(TIM3, ENABLE); //使能TIMx
  141. }
  142. u8 mode_flag=0;
  143. u16 GetTimer=0;//采集时间计数器
  144. u8 dw_val=0;//挡位
  145. u8 sc_val=0;//色彩
  146. int key_Task(void)
  147. {
  148. static char key_flag=0;
  149. if(KEY1_IN==0|KEY2_IN==0|KEY3_IN==0|KEY4_IN==0)
  150. {
  151. if(key_flag==0)
  152. {
  153. key_flag=1;
  154. if(KEY1_IN==0)
  155. {
  156. mode_flag^=1;
  157. }
  158. else if(KEY2_IN==0)
  159. {
  160. if(mode_flag==0)
  161. {
  162. if(++dw_val>2)dw_val=0;
  163. }else
  164. {
  165. }
  166. }
  167. else if(KEY3_IN==0)
  168. {
  169. if(mode_flag==0)
  170. {
  171. if(++sc_val>2)sc_val=0;
  172. }else
  173. {
  174. }
  175. }
  176. else if(KEY4_IN==0)
  177. {
  178. if(mode_flag==0)
  179. {
  180. }else
  181. {
  182. }
  183. }
  184. }
  185. }else
  186. {
  187. key_flag=0;
  188. }
  189. return 20;
  190. }
  191. u16 DataUpTime=0;//时间显示计数器
  192. u8 rt_flag=0;//红外人体标志位
  193. u16 rt_cnt=0;
  194. u8 seccnt=0;
  195. void TIM3_IRQHandler(void)//中断服务程序
  196. {
  197. if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)//SET为1
  198. {
  199. GetTimer++;//采集计数器
  200. TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3的更新中断标志
  201. key_Task();
  202. DataUpTime++;
  203. if(RT_INPUT==1) //检测人体感应
  204. {
  205. rt_flag=1;
  206. rt_cnt=0;
  207. }else
  208. {
  209. if(rt_cnt++>100*10)
  210. {
  211. rt_cnt=0;rt_flag=0;
  212. }
  213. }
  214. if(rt_flag) //有人 开始计时计算学习时间
  215. {
  216. if(++seccnt>50)
  217. {
  218. seccnt=0;
  219. if(++cnt_m1>59)
  220. {
  221. cnt_m1=0;
  222. if(++cnt_f1>59)
  223. {
  224. cnt_f1=0;
  225. if(++cnt_s1>23)
  226. {
  227. cnt_s1=0;
  228. }
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. u8 GetFlag=0;
  236. uint8_t sendBuff[16]={0};
  237. void ShowTo(char* Pdat,char len)//字符串中的空格补 0
  238. {
  239. char ixd=0;
  240. for(ixd=0;ixd<len;ixd++)
  241. {
  242. if(Pdat[ixd]==' ')
  243. {
  244. Pdat[ixd]='0';
  245. }
  246. }
  247. }
  248. int main(void)
  249. {
  250. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  251. delay_init(); //延时函数初始化
  252. LED_Init(); //初始化与连接的硬件接口
  253. uart_init(115200);
  254. delay_ms(1000);
  255. TIMER3_Int_Init(20000,71);//定时器初始化 //10ms进一次中断
  256. Wave_IO_Init();
  257. BH1750_Init();
  258. OLED_Init();//液晶初始化
  259. OLED_Clear();//液晶清屏
  260. delay_ms(10);//上电延时一会
  261. key_gpio_init();
  262. Ds1302_Gpio_Init();
  263. while(1)
  264. {
  265. if(GetTimer>50)//1S
  266. {
  267. GetTimer=0;
  268. if(dht11_read_data(buffer) == 0)//读取温湿度
  269. {
  270. humi = buffer[0] + buffer[1] / 10;//取湿度值
  271. temp = buffer[2] + buffer[3] / 10;//取温度值
  272. }
  273. GzVal = Dispose();
  274. cj_val=Wave_Start();
  275. if(cj_val<10)
  276. {
  277. OLED_ShowText(0,6,"坐姿:异常",0);
  278. }else
  279. {
  280. OLED_ShowText(0,6,"坐姿:正常",0);
  281. }
  282. printf("wsdgzcheck_X%dH%dD%dZ\r\n",temp,humi,GzVal);//发送到上位机app
  283. }
  284. if(DataUpTime>20) //400ms刷新一次数据
  285. {
  286. DataUpTime=0;//
  287. Ds1302_Readtime();
  288. sprintf((char*)DateShowBuf,"时间:%2d:%2d:%2d", (int)ds1302Data.hour, (int)ds1302Data.min, (int)ds1302Data.sec);
  289. ShowTo(DateShowBuf,9);
  290. OLED_ShowText(0,0,DateShowBuf,0);
  291. sprintf((char*)DateShowBuf,"闹钟:%2d:%2d:00", (int)set_s1, (int)set_f1);
  292. ShowTo(DateShowBuf,10);
  293. OLED_ShowText(0,2,DateShowBuf,0);
  294. sprintf((char*)DateShowBuf,"学习:%2d:%2d:%2d", (int)cnt_s1, (int)cnt_f1,cnt_m1);
  295. ShowTo(DateShowBuf,10);
  296. OLED_ShowText(0,4,DateShowBuf,0);
  297. }
  298. }
  299. }