main.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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 "ds18b20.h"
  13. #include "string.h"
  14. #include "adc.h"
  15. u8 humi=0;//湿度值
  16. u8 temp=0;//温度值
  17. u8 buffer[10]={0};
  18. u16 GzVal=0; //实际光照值
  19. char ShowBuf[16]={0};
  20. char DateShowBuf[30]={0};
  21. char SendBuff[50]={0};
  22. short TEMP = 0;
  23. u16 cj_val=0;//测距值
  24. u8 openflag=0;//手动模式开关按钮
  25. u8 mode_flag=0;
  26. #define AM_PIN PCout(13) //按摩控制引脚
  27. #define FAN_PIN PCout(14) //风扇控制引脚
  28. #define ZM_PIN PCout(15) //照明控制引脚
  29. #define FM_PIN PAout(12) //蜂鸣器报警引脚
  30. #define LED_PIN PAout(11) //红色led引脚
  31. #define SAMPLE_PERIOD 20 // 波形采样
  32. #define BUFF_SIZE 50 // 数据缓冲区大小
  33. typedef enum {FALSE, TRUE} BOOL;
  34. uint16_t VitData, LastData; // 读取到的 AD 值
  35. uint16_t timeCount = 0; // 采样周期计数变量
  36. uint16_t firstTimeCount = 0; // 第一个心跳时间
  37. uint16_t secondTimeCount = 0; // 第二个心跳时间
  38. /*adjoin_val: 相邻两个心跳的时间,bmp_val: 心率值, pulse_val: 脉象图的数值化表示*/
  39. uint16_t adjoin_val, bmp_val, pulse_val;
  40. uint16_t data[BUFF_SIZE] = {0}; // 采样数据缓存
  41. int buf_index = 0; // 缓存数组下标
  42. uint16_t max, min, mid; // 最大、最小及中间值
  43. uint16_t filter_val; // 滤波值
  44. BOOL PULSE = FALSE; // 有效脉搏
  45. BOOL PRE_PULSE = FALSE; // 先前有效脉搏
  46. uint8_t pulseCount = 0; // 脉搏计数
  47. uint32_t i;
  48. void Print_Wave(void);
  49. uint16_t Get_Array_Max(uint16_t * array, uint32_t size);
  50. uint16_t Get_Array_Min(uint16_t * array, uint32_t size);
  51. u16 Get_ADC_Average_Val(void);
  52. u8 warning_cnt=0;
  53. u16 GetTimer=0;//采集时间计数器
  54. u8 dw_val=0;//挡位//亮度值
  55. u8 sc_val=0;//色彩
  56. int cnt_s1=2,cnt_f1=0,cnt_m1=0;//学习时间 时分秒
  57. u8 zm_open_flag=0; //照明开关标志位
  58. u8 ln_open_flag=0;//拉链开关标志位
  59. u8 am_open_flag=0;//按摩
  60. u8 off_time_s=22,off_time_f=0;//定时关闭时间 时分
  61. u8 set_s1=8,set_f1=0; //设置 时间闹钟
  62. #define RT_INPUT PBin(8)//人体红外感应
  63. #define KEY_GPIO_PROT GPIOA
  64. #define KEY1_GPIO_PIN GPIO_Pin_1
  65. #define KEY2_GPIO_PIN GPIO_Pin_2
  66. #define KEY3_GPIO_PIN GPIO_Pin_3
  67. #define KEY4_GPIO_PIN GPIO_Pin_4
  68. #define KEY5_GPIO_PIN GPIO_Pin_5
  69. #define KEY6_GPIO_PIN GPIO_Pin_6
  70. #define KEY7_GPIO_PIN GPIO_Pin_7
  71. #define KEY1_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY1_GPIO_PIN)
  72. #define KEY2_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY2_GPIO_PIN)
  73. #define KEY3_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY3_GPIO_PIN)
  74. #define KEY4_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY4_GPIO_PIN)
  75. #define KEY5_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY5_GPIO_PIN)
  76. #define KEY6_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY6_GPIO_PIN)
  77. #define KEY7_IN GPIO_ReadInputDataBit(KEY_GPIO_PROT,KEY7_GPIO_PIN)
  78. void key_gpio_init(void)
  79. {
  80. GPIO_InitTypeDef GPIO_InitStructure;
  81. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
  82. GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN|KEY3_GPIO_PIN|KEY4_GPIO_PIN|KEY5_GPIO_PIN|KEY6_GPIO_PIN|KEY7_GPIO_PIN;
  83. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  84. GPIO_Init(KEY_GPIO_PROT, &GPIO_InitStructure);
  85. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  86. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  87. GPIO_Init(GPIOA, &GPIO_InitStructure);
  88. }
  89. void TIMER3_Int_Init(u16 arr,u16 psc)
  90. {
  91. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
  92. NVIC_InitTypeDef NVIC_InitStructure;
  93. TIM_TimeBaseInitStrue.TIM_Period=arr;
  94. TIM_TimeBaseInitStrue.TIM_Prescaler=psc;
  95. TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;
  96. TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CounterMode_Up;
  97. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  98. TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);
  99. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3更新中断
  100. //中断优先级NVIC设置
  101. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
  102. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
  103. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
  104. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  105. NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
  106. TIM_Cmd(TIM3, ENABLE); //使能TIMx 拍另外一个吧 重复拍一个有刷单嫌疑
  107. }
  108. /*
  109. 1,照明功能与定时器模块,可以设置照明灯开启 定时关灯,设置闹钟时间,闹钟时间到蜂鸣器滴滴响报警。这里需要加入实时时钟模块
  110. 2,自动拉帘通过按钮控制,电机正反转模拟自动开合。
  111. 3,音乐播放功能通过蓝牙音频模块实现,通过蓝牙与用户手机连接播放音乐。
  112. 4,按摩功能,通过手动按键控制开关,通过振动器模拟实现按摩效果,
  113. 5,检测体表温度值,如果人体温度过高,出现发烧情况,进行蜂鸣器报警同时红色LED灯亮起,
  114. 检测环境温湿度控制是否加热和排风,当实际温度值小于设置温度值时,自动开启加热丝(这里通过继电器控制加热电阻实现),
  115. 当实际温度值大于设置值切实际湿度值大于设置湿度值,这时开启排风,这里使用小风扇实现。
  116. 6 检测心率值,当实际值大于上限值时或者小于下限值时,开启蜂鸣器报警。同时LED闪烁。\
  117. 7 液晶显示
  118. */
  119. u8 set_flag=0;//设置标志位
  120. u8 set_ok_flag=1;//设置完成标志位
  121. u8 temp_L=30,temp_H=37;//设置温度上下限值
  122. u8 humi_H=0;//湿度上限值
  123. u8 xl_L=0,xl_H=120;//设置心率值
  124. int key_Task(void)
  125. {
  126. static char key_flag=0;
  127. if(KEY1_IN==0|KEY2_IN==0|KEY3_IN==0|KEY4_IN==0|KEY5_IN==0|KEY6_IN==0|KEY7_IN==0)
  128. {
  129. if(key_flag==0)
  130. {
  131. key_flag=1;
  132. if(KEY1_IN==0)
  133. {
  134. zm_open_flag^=1;//开关控制切换
  135. }
  136. else if(KEY2_IN==0)
  137. {
  138. ln_open_flag^=1;
  139. }
  140. else if(KEY3_IN==0)
  141. {
  142. am_open_flag^=1;
  143. }
  144. else if(KEY4_IN==0)
  145. {
  146. if(set_flag++>9)
  147. {
  148. set_flag=0;
  149. }
  150. set_ok_flag=0;
  151. }
  152. else if(KEY5_IN==0)
  153. {
  154. switch(set_flag)
  155. {
  156. case 1:
  157. if(++off_time_s>23)off_time_s=0;
  158. break;
  159. case 2:
  160. if(++off_time_f>59)off_time_f=0;
  161. break;
  162. case 3:
  163. if(++set_s1>23)set_s1=0;
  164. break;
  165. case 4:
  166. if(++set_f1>59)set_f1=0;
  167. break;
  168. case 5:
  169. if(++temp_L>99)temp_L=0;
  170. break;
  171. case 6:
  172. if(++temp_H>99)temp_H=0;
  173. break;
  174. case 7:
  175. if(++humi_H>99)humi_H=0;
  176. break;
  177. case 8:
  178. if(++xl_L>150)xl_L=0;
  179. break;
  180. case 9:
  181. if(++xl_H>150)xl_H=0;
  182. break;
  183. case 10:
  184. break;
  185. }
  186. }
  187. else if(KEY6_IN==0)
  188. {
  189. switch(set_flag)
  190. {
  191. case 1:
  192. if(--off_time_s<=0)off_time_s=23;
  193. break;
  194. case 2:
  195. if(--off_time_f<=0)off_time_f=59;
  196. break;
  197. case 3:
  198. if(--set_s1<=0)set_s1=23;
  199. break;
  200. case 4:
  201. if(--set_f1<=0)set_f1=59;
  202. break;
  203. case 5:
  204. if(--temp_L<=0)temp_L=99;
  205. break;
  206. case 6:
  207. if(--temp_H>99)temp_H=99;
  208. break;
  209. case 7:
  210. if(--humi_H<=0)humi_H=99;
  211. break;
  212. case 8:
  213. if(--xl_L<=0)xl_L=150;
  214. break;
  215. case 9:
  216. if(--xl_H<=0)xl_H=150;
  217. break;
  218. case 10:
  219. break;
  220. }
  221. }
  222. else if(KEY7_IN==0)
  223. {
  224. set_ok_flag=1;
  225. }
  226. }
  227. }else
  228. {
  229. key_flag=0;
  230. }
  231. return 20;
  232. }
  233. u16 DataUpTime=0;//时间显示计数器
  234. u8 rt_flag=0;//红外人体标志位
  235. u16 rt_cnt=0;
  236. u8 seccnt=0;
  237. //IN1-PA4
  238. #define IN1_GPIO_PORT GPIOB
  239. #define IN1_GPIO_CLK RCC_APB2Periph_GPIOB
  240. #define IN1_GPIO_PIN GPIO_Pin_12
  241. //IN2-PA5
  242. #define IN2_GPIO_PORT GPIOB
  243. #define IN2_GPIO_CLK RCC_APB2Periph_GPIOB
  244. #define IN2_GPIO_PIN GPIO_Pin_13
  245. //IN3-PA6
  246. #define IN3_GPIO_PORT GPIOB
  247. #define IN3_GPIO_CLK RCC_APB2Periph_GPIOB
  248. #define IN3_GPIO_PIN GPIO_Pin_14
  249. //IN1-PA7
  250. #define IN4_GPIO_PORT GPIOB
  251. #define IN4_GPIO_CLK RCC_APB2Periph_GPIOB
  252. #define IN4_GPIO_PIN GPIO_Pin_15
  253. /* 直接操作寄存器的方法控制IO */
  254. #define digitalHi(p,i) {p->BSRR=i;} //输出为高电平
  255. #define digitalLo(p,i) {p->BRR=i;} //输出低电平
  256. /* 定义控制IO的宏 */
  257. #define IN1_HIGH digitalHi(IN1_GPIO_PORT,IN1_GPIO_PIN)
  258. #define IN1_LOW digitalLo(IN1_GPIO_PORT,IN1_GPIO_PIN)
  259. #define IN2_HIGH digitalHi(IN2_GPIO_PORT,IN2_GPIO_PIN)
  260. #define IN2_LOW digitalLo(IN2_GPIO_PORT,IN2_GPIO_PIN)
  261. #define IN3_HIGH digitalHi(IN3_GPIO_PORT,IN3_GPIO_PIN)
  262. #define IN3_LOW digitalLo(IN3_GPIO_PORT,IN3_GPIO_PIN)
  263. #define IN4_HIGH digitalHi(IN4_GPIO_PORT,IN4_GPIO_PIN)
  264. #define IN4_LOW digitalLo(IN4_GPIO_PORT,IN4_GPIO_PIN)
  265. void GPIO_Config(void)
  266. {
  267. /*定义一个GPIO_InitTypeDef类型的结构体*/
  268. GPIO_InitTypeDef GPIO_InitStructure;
  269. /*开启引脚相关的GPIO外设时钟*/
  270. RCC_APB2PeriphClockCmd( IN1_GPIO_CLK | IN2_GPIO_CLK | IN3_GPIO_CLK | IN4_GPIO_CLK , ENABLE);
  271. /*选择要控制的GPIO引脚*/
  272. GPIO_InitStructure.GPIO_Pin = IN1_GPIO_PIN;
  273. /*设置引脚模式为通用推挽输出*/
  274. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  275. /*设置引脚速率为50MHz */
  276. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  277. /*调用库函数,初始化GPIO*/
  278. GPIO_Init(IN1_GPIO_PORT, &GPIO_InitStructure);
  279. /*选择要控制的GPIO引脚*/
  280. GPIO_InitStructure.GPIO_Pin = IN2_GPIO_PIN;
  281. /*调用库函数,初始化GPIO*/
  282. GPIO_Init(IN2_GPIO_PORT, &GPIO_InitStructure);
  283. /*选择要控制的GPIO引脚*/
  284. GPIO_InitStructure.GPIO_Pin = IN3_GPIO_PIN;
  285. /*调用库函数,初始化GPIOF*/
  286. GPIO_Init(IN3_GPIO_PORT, &GPIO_InitStructure);
  287. /*选择要控制的GPIO引脚*/
  288. GPIO_InitStructure.GPIO_Pin = IN4_GPIO_PIN;
  289. /*调用库函数,初始化GPIOF*/
  290. GPIO_Init(IN4_GPIO_PORT, &GPIO_InitStructure);
  291. //所有引脚初始化为低电平
  292. IN1_LOW;
  293. IN2_LOW;
  294. IN3_LOW;
  295. IN4_LOW;
  296. }
  297. void stepper(uint8_t dir,int speed)
  298. {
  299. if(dir == 1)
  300. {
  301. IN1_HIGH;
  302. delay_ms(speed);
  303. IN1_LOW;
  304. IN2_HIGH;
  305. delay_ms(speed);
  306. IN2_LOW;
  307. IN3_HIGH;
  308. delay_ms(speed);
  309. IN3_LOW;
  310. IN4_HIGH;
  311. delay_ms(speed);
  312. IN4_LOW;
  313. }
  314. else if(dir==2)
  315. {
  316. IN1_HIGH;
  317. delay_ms(speed);
  318. IN1_LOW;
  319. IN4_HIGH;
  320. delay_ms(speed);
  321. IN4_LOW;
  322. IN3_HIGH;
  323. delay_ms(speed);
  324. IN3_LOW;
  325. IN2_HIGH;
  326. delay_ms(speed);
  327. IN2_LOW;
  328. }
  329. }
  330. void fanzhuan(void)
  331. {
  332. int i;
  333. for(i = 0;i < 220;i++) //电机反转
  334. stepper(2,5);
  335. }
  336. void zhengzhuan(void)
  337. {
  338. int i;
  339. for(i = 0;i < 220;i++) //电机正转
  340. stepper(1,5);
  341. }
  342. void zhendong_task(void) //按摩器震动轮询 开 - 关 - 开 -关 时间不同模拟按摩效果
  343. {
  344. static uint16_t cnt_time=0;//计时控制 按摩时间
  345. if(am_open_flag)
  346. {
  347. switch(cnt_time)
  348. {
  349. case 0:
  350. AM_PIN=1;//开启 2S
  351. break;
  352. case 200:
  353. AM_PIN=0;//off 1S
  354. break;
  355. case 300:
  356. AM_PIN=1;//开启
  357. break;
  358. //3S
  359. case 600:
  360. AM_PIN=0;//开启
  361. break;
  362. //1S
  363. case 700:
  364. AM_PIN=1;//开启
  365. break;
  366. //4s
  367. case 1100:
  368. AM_PIN=0;//开启
  369. break;
  370. //1s
  371. case 1200:
  372. AM_PIN=1;//开启
  373. break;
  374. case 1400:
  375. AM_PIN=0;//off
  376. break;
  377. case 1600:
  378. cnt_time=0;
  379. break;
  380. }
  381. cnt_time++;
  382. }else
  383. {
  384. cnt_time=0;
  385. AM_PIN=0;//关闭按摩 振动器
  386. }
  387. }
  388. #define Nx 5
  389. u16 value_buf[Nx];
  390. int Rx_count=0;
  391. u16 FILTER_median(char Flag) //中位值滤波 中位值平均滤波 N为采样次数,取奇数 Flag:中位值平均滤波使能 心率数据滤波用的
  392. {
  393. u16 temp=0;
  394. long sum=0;
  395. int count,i,j;
  396. for(j=0;j<Nx-1;j++) //排序
  397. {
  398. for(i=0;i<Nx-j-1;i++)
  399. {
  400. if ( value_buf[i] > value_buf[i+1] )
  401. {
  402. temp = value_buf[i];
  403. value_buf[i] = value_buf[i+1];
  404. value_buf[i+1] = temp;
  405. }
  406. }
  407. }
  408. if(Flag)
  409. {
  410. for(count=1;count<Nx-1;count++) //中位求平均 由Flag标志控制
  411. sum+=value_buf[count];
  412. return (sum/(Nx-2));
  413. }
  414. else
  415. return value_buf[(Nx-1)/2]; //中位值
  416. }
  417. int iCnt =0 ;//样本数据索引
  418. u8 CheckCnt=0;//计数器
  419. char showBuff[16]={0};//液晶显示buff
  420. u8 sendbuff[4]={0};//发送数据缓存器buff
  421. int val1=0;//记录数据变量
  422. int val2=0;//记录数据变量
  423. u8 Flag1=0;//记录数据变量
  424. void xl_sensor_task(void)
  425. {
  426. if(++CheckCnt>=2)
  427. {
  428. LastData = VitData; // 保存前一次值
  429. VitData = Get_ADC_Average_Val(); // 读取AD转换值
  430. if (((VitData - LastData) < filter_val)&&VitData>1000) // 滤除突变噪声信号干扰
  431. data[buf_index++] = VitData; // 填充缓存数组
  432. if (buf_index >= BUFF_SIZE)
  433. {
  434. buf_index = 0; // 数组填满,从头再填
  435. // 通过缓存数组获取脉冲信号的波峰、波谷值,并计算中间值作为判定参考阈值
  436. max = Get_Array_Max(data, BUFF_SIZE);
  437. min = Get_Array_Min(data, BUFF_SIZE);
  438. mid = (max + min)/2;
  439. filter_val = (max - min) / 2;
  440. }
  441. PRE_PULSE = PULSE; // 保存当前脉冲状态
  442. PULSE = (VitData > mid) ? TRUE : FALSE; // 采样值大于中间值为有效脉冲
  443. if (PRE_PULSE == FALSE && PULSE == TRUE) // 寻找到“信号上升到振幅中间位置”的特征点,检测到一次有效脉搏
  444. {
  445. pulseCount++;
  446. pulseCount %= 2;
  447. if(pulseCount == 1) // 两次脉搏的第一次
  448. {
  449. firstTimeCount = timeCount; // 记录第一次脉搏时间
  450. }
  451. if(pulseCount == 0) // 两次脉搏的第二次
  452. {
  453. secondTimeCount = timeCount; // 记录第二次脉搏时间
  454. timeCount = 0;
  455. if ( (secondTimeCount > firstTimeCount))
  456. {
  457. adjoin_val = (secondTimeCount - firstTimeCount) * SAMPLE_PERIOD; // 计算相邻两次脉搏的时间,得到 adjoin_val
  458. if(iCnt<Nx)
  459. {
  460. value_buf[iCnt++]=adjoin_val;
  461. }
  462. if(iCnt==Nx)
  463. {
  464. val2 = 60000 / FILTER_median(0); // 通过 adjoin_val 得到心率值 bmp_val
  465. if(Flag1==0)//第一次计算
  466. {
  467. if(val2>20&&val2<150)bmp_val=val2;
  468. Flag1=1;
  469. }else
  470. {
  471. if(abs(val2-val1)<20)//后面计算防止突发干扰数据对比前后两次的
  472. {
  473. if(val2>20&&val2<150)bmp_val=val2;
  474. }
  475. }
  476. // sprintf(showBuff,"BMP:%3d/min",bmp_val);//打印成字符串
  477. // OLED_ShowString(0,2,showBuff,16);//显示到液晶
  478. // sendbuff[0]='&';//标识符 发送到app的数据帧头
  479. // sendbuff[1]=0;//没用上填0
  480. // sendbuff[2]=bmp_val;//实际心率数据
  481. // sendbuff[3]=sendbuff[0]+sendbuff[1]+sendbuff[2];//计算和校验
  482. // UART3SendBuffer(sendbuff,4);//通过wifi串口发送过去
  483. iCnt=0;//计数器清零
  484. val1=val2;//保存本次值
  485. }
  486. }
  487. }
  488. }
  489. timeCount++; // 时间计数累加
  490. CheckCnt=0;
  491. }
  492. //delay_ms(20);//延时20ms延时再进行下一周期采样 这里的采样率是50*10=500HZ
  493. }
  494. void TIM3_IRQHandler(void)//中断服务程序
  495. {
  496. if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)//SET为1
  497. {
  498. GetTimer++;//采集计数器
  499. TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3的更新中断标志
  500. key_Task();//按键扫描
  501. DataUpTime++;
  502. zhendong_task();//震动控制
  503. xl_sensor_task();//检测心率功能函数
  504. if(rt_flag) //有人 开始计时计算学习时间
  505. {
  506. if(++seccnt>50)
  507. {
  508. seccnt=0;
  509. if(++cnt_m1>59)
  510. {
  511. cnt_m1=0;
  512. if(++cnt_f1>59)
  513. {
  514. cnt_f1=0;
  515. if(++cnt_s1>23)
  516. {
  517. cnt_s1=0;
  518. }
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }
  525. u8 GetFlag=0;
  526. uint8_t sendBuff[16]={0};
  527. void ShowTo(char* Pdat,char len)//字符串中的空格补 0
  528. {
  529. char ixd=0;
  530. for(ixd=0;ixd<len;ixd++)
  531. {
  532. if(Pdat[ixd]==' ')
  533. {
  534. Pdat[ixd]='0';
  535. }
  536. }
  537. }
  538. #define IO_TX_GPIO_Port PAout(7)
  539. void uartX_sendByte(uint8_t val)
  540. {
  541. int i = 0;
  542. IO_TX_GPIO_Port=0;
  543. delay_us(104);
  544. for (i = 0; i < 8; i++)
  545. {
  546. if (val & 0x01)
  547. {
  548. IO_TX_GPIO_Port=1;
  549. } else {
  550. IO_TX_GPIO_Port=0;
  551. }
  552. delay_us(104);
  553. val >>= 1;
  554. }
  555. IO_TX_GPIO_Port=1;
  556. delay_us(104);
  557. }
  558. u8 test=0;
  559. u8 ln_lock_flag=0;//拉链动作锁定标志
  560. short tb_temp=0;//体表温度
  561. int main(void)
  562. {
  563. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  564. delay_init(); //延时函数初始化
  565. LED_Init(); //初始化与连接的硬件接口
  566. uart_init(9600);
  567. delay_ms(1000);
  568. key_gpio_init();
  569. OLED_Init();//液晶初始化
  570. OLED_Clear();//液晶清屏
  571. delay_ms(10);//上电延时一会
  572. DS18B20_Init();
  573. Ds1302_Gpio_Init();
  574. Ds1302_Write_Time_All(1);
  575. ADC1_Init();
  576. TIMER3_Int_Init(10000,71);//定时器初始化 //10ms进一次中断
  577. while(1)
  578. {
  579. if(ln_open_flag) //开启拉链
  580. {
  581. if(ln_lock_flag==0) //锁定标志 转动一次就醒来
  582. {
  583. ln_lock_flag=1;
  584. zhengzhuan();//控制电机
  585. }
  586. }else //关闭拉链
  587. {
  588. if(ln_lock_flag==1)
  589. {
  590. ln_lock_flag=0;
  591. fanzhuan();
  592. }
  593. }
  594. if(GetTimer>100)//1S
  595. {
  596. GetTimer=0;
  597. if(dht11_read_data(buffer) == 0)//读取温湿度
  598. {
  599. humi = buffer[0] + buffer[1] / 10;//取湿度值
  600. temp = buffer[2] + buffer[3] / 10;//取温度值
  601. }
  602. tb_temp = DS18B20_Get_Temp();
  603. }
  604. if(DataUpTime>40) //400ms刷新一次数据
  605. {
  606. DataUpTime=0;//
  607. Ds1302_Readtime();
  608. sprintf((char*)DateShowBuf,"time:%2d:%2d:%2d", (int)ds1302Data.hour, (int)ds1302Data.min, (int)ds1302Data.sec);
  609. ShowTo(DateShowBuf,strlen(DateShowBuf));
  610. OLED_ShowString(0,0,(u8*)DateShowBuf,12);//显示实时时间
  611. sprintf((char*)DateShowBuf,"alarm:%2d:%2d", (int)set_s1, (int)set_f1);
  612. ShowTo(DateShowBuf,strlen(DateShowBuf));
  613. OLED_ShowString(0,1,(u8*)DateShowBuf,12);//显示闹钟时间
  614. sprintf((char*)DateShowBuf,"off:%2d:%2d", (int)off_time_s, (int)off_time_s);//打印字符串
  615. ShowTo(DateShowBuf,strlen(DateShowBuf));
  616. OLED_ShowString(0,2,(u8*)DateShowBuf,12);//显示关闭时间
  617. sprintf((char*)DateShowBuf,"bmp:%3d L:%3d H%3d", (int)bmp_val,xl_L,xl_H);
  618. OLED_ShowString(0,3,(u8*)DateShowBuf,12);//显示体表温度 心率值
  619. if((ds1302Data.hour==set_s1)&&(ds1302Data.min==set_f1)) //到达闹钟时间
  620. {
  621. warning_cnt|=0x01;//置为1 需要报警
  622. }
  623. else
  624. {
  625. warning_cnt&=~0x01;
  626. }
  627. if(zm_open_flag) //判断是否开启照明灯
  628. {
  629. ZM_PIN=1;
  630. if(ds1302Data.hour==off_time_s&&ds1302Data.min==off_time_s) //定时关灯时间到了
  631. {
  632. ZM_PIN=0;
  633. zm_open_flag=0;//清除标志位
  634. }
  635. }else
  636. {
  637. ZM_PIN=0;
  638. }
  639. }
  640. }
  641. }
  642. /******************** ADC通道2转换函数 ************************/
  643. u16 Get_ADC_Average_Val(void)
  644. {
  645. u8 i,j;
  646. u16 buff[10] = {0};
  647. u16 temp;
  648. for(i = 0; i < 10; i ++)
  649. {
  650. /* 开始转换 */
  651. buff[i] = Get_Adc(0); //读取转换结果
  652. }
  653. /* 把读取值的数据按从小到大的排列 */
  654. for(i = 0; i < 9; i++)
  655. {
  656. for(j = 0 ; j < 9-i; j++)
  657. {
  658. if(buff[j] > buff[j+1])
  659. {
  660. temp = buff[j];
  661. buff[j] = buff[j+1];
  662. buff[j+1] = temp;
  663. }
  664. }
  665. }
  666. /* 求平均值 */
  667. temp = 0;
  668. for(i = 1; i < 9; i++)
  669. {
  670. temp += buff[i];
  671. }
  672. return temp/8;
  673. }
  674. uint16_t Get_Array_Max(uint16_t * array, uint32_t size)//计算数组数据中最大的
  675. {
  676. uint16_t max = array[0];
  677. uint32_t i;
  678. for (i = 1; i < size; i++)
  679. {
  680. if (array[i] > max)
  681. max = data[i];
  682. }
  683. return max;
  684. }
  685. uint16_t Get_Array_Min(uint16_t * array, uint32_t size)//计算数组数据中最小的
  686. {
  687. uint16_t min = array[0];
  688. uint32_t i;
  689. for (i = 1; i < size; i++)
  690. {
  691. if (array[i] < min)
  692. min = data[i];
  693. }
  694. return min;
  695. }