当前位置:   article > 正文

基于51单片机的智能晾衣架

基于51单片机的智能晾衣架

目录

一、项目功能

二、原理图

三、仿真图

 四、实物照片

 五、程序


资料下载地址:基于51单片机智能晾衣架

一、项目功能

1、实时测量DHT11温湿度传感器的数据并在LCD1602液晶屏上显示

2、实时检测光照强度传感器的数据并在LCD1602液晶屏上显示

3、无线遥控模块可以控制晾衣架分为自动模式和手动模式

自动模式下:当光照强度、温湿度在一定范围内时,电机正传,否则电机反转,实现自动晾衣和收回。

手动模式下:可以遥控电机正传,反转。实现手动晾衣和收回。

二、原理图

三、仿真图

 自动模式界面

手动模式界面

 四、实物照片

 五、程序

部分程序

  1. /*******************************************************************************
  2. * 函 数 名 : LcdWriteCom
  3. * 函数功能 : 向LCD写入一个字节的命令
  4. * 输 入 : u8com
  5. * 输 出 : 无
  6. *******************************************************************************/
  7. void lcd_wri_com(unsigned char com) //写入命令
  8. {
  9. E = 0; //使能清零
  10. RS = 0; //选择写入命令
  11. RW = 0; //选择写入
  12. DB = com;
  13. delay_ms(1);
  14. E = 1; //写入时序
  15. delay_ms(5);
  16. E = 0;
  17. }
  18. /*******************************************************************************
  19. * 函 数 名 : LcdWriteData
  20. * 函数功能 : 向LCD写入一个字节的数据
  21. * 输 入 : u8dat
  22. * 输 出 : 无
  23. *******************************************************************************/
  24. void lcd_wri_data(unsigned char dat)//写入数据
  25. {
  26. E = 0; //使能清零
  27. RS = 1; //选择写入数据
  28. RW = 0; //选择写入
  29. DB = dat;
  30. delay_ms(1);
  31. E = 1; //写入时序
  32. delay_ms(5);
  33. E = 0;
  34. }
  35. /*******************************************************************************
  36. * 函 数 名 : WriString
  37. * 函数功能 : 刷新屏幕显示
  38. * 输 入 : hang,add,*p
  39. * 输 出 : 无
  40. *******************************************************************************/
  41. void wri_string(unsigned char y,unsigned char x,unsigned char *p)
  42. {
  43. if(y==1)//如果选择第一行
  44. lcd_wri_com(0x80+x);//选中地址
  45. else
  46. lcd_wri_com(0xc0+x);//选中地址
  47. while(*p)
  48. {
  49. lcd_wri_data(*p);//写入数据
  50. p++;
  51. }
  52. }
  53. /*******************************************************************************
  54. * 函 数 名 : lcd_write_char
  55. * 函数功能 :
  56. * 输 入 :
  57. * 输 出 : 无
  58. *******************************************************************************/
  59. void lcd_write_char(unsigned char y, unsigned char x, unsigned char dat) //列x=0~15,行y=0,1
  60. {
  61. unsigned char temp_l, temp_h;
  62. if(y==1)//如果选择第一行
  63. lcd_wri_com(0x80+x);//选中地址
  64. else
  65. lcd_wri_com(0xc0+x);//选中地址
  66. temp_l = dat % 10;
  67. temp_h = dat / 10;
  68. lcd_wri_data(temp_h + 0x30); //convert to ascii
  69. lcd_wri_data(temp_l + 0x30);
  70. }
  71. /*********************光标控制***********************/
  72. void lcd1602_guanbiao(unsigned char y, unsigned char x,unsigned char on_off)
  73. {
  74. if(on_off == 1) //开光标
  75. {
  76. if(y==1)//如果选择第一行
  77. lcd_wri_com(0x80+x);
  78. else
  79. lcd_wri_com(0xc0+x);//将光标移动到秒个位
  80. lcd_wri_com(0x0f);//显示光标并且闪烁
  81. }
  82. else
  83. {
  84. if(y==1)//如果选择第一行
  85. lcd_wri_com(0x80+x);
  86. else
  87. lcd_wri_com(0xc0+x);//将光标移动到秒个位
  88. lcd_wri_com(0x0c); //关光标
  89. }
  90. }
  91. /*******************************************************************************
  92. * 函 数 名 : LcdInit()
  93. * 函数功能 : 初始化LCD屏
  94. * 输 入 : 无
  95. * 输 出 : 无
  96. *******************************************************************************/
  97. void lcd_init(void) //LCD初始化子程序
  98. {
  99. lcd_wri_com(0x38);//置功能8位双行
  100. lcd_wri_com(0x0c);//显示开关光标
  101. lcd_wri_com(0x06);//字符进入模式屏幕不动字符后移
  102. delay_ms(5);//延时5ms
  103. lcd_wri_com(0x01); //清屏
  104. wri_string(2,0,times);//初始化显示
  105. wri_string(2,6,date);
  106. wri_string(1,0,"H: %RH T: C ");//初始化显示
  107. }
  108. void DHT11_delay_us(unsigned char n)
  109. {
  110. while(--n);
  111. }
  112. void DHT11_delay_ms(unsigned int z)
  113. {
  114. unsigned int i,j;
  115. for(i=z;i>0;i--)
  116. for(j=110;j>0;j--);
  117. }
  118. void DHT11_start()
  119. {
  120. Data=1;
  121. DHT11_delay_us(2);
  122. Data=0;
  123. DHT11_delay_ms(30); //延时18ms以上
  124. Data=1;
  125. DHT11_delay_us(30);
  126. }
  127. unsigned char DHT11_rec_byte() //接收一个字节
  128. {
  129. unsigned char i,dat=0;
  130. for(i=0;i<8;i++) //从高到低依次接收8位数据
  131. {
  132. while(!Data); 等待50us低电平过去
  133. DHT11_delay_us(8); //延时60us,如果还为高则数据为1,否则为0
  134. dat<<=1; //移位使正确接收8位数据,数据为0时直接移位
  135. if(Data==1) //数据为1时,使dat加1来接收数据1
  136. dat+=1;
  137. while(Data); //等待数据线拉低
  138. }
  139. return dat;
  140. }
  141. void DHT11_receive() //接收40位的数据
  142. {
  143. unsigned char R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  144. DHT11_start();
  145. if(Data==0)
  146. {
  147. while(Data==0); //等待拉高
  148. DHT11_delay_us(40); //拉高后延时80us
  149. R_H=DHT11_rec_byte(); //接收湿度高八位
  150. R_L=DHT11_rec_byte(); //接收湿度低八位
  151. T_H=DHT11_rec_byte(); //接收温度高八位
  152. T_L=DHT11_rec_byte(); //接收温度低八位
  153. revise=DHT11_rec_byte(); //接收校正位
  154. DHT11_delay_us(25); //结束
  155. if((R_H+R_L+T_H+T_L)==revise) //校正
  156. {
  157. RH=R_H;
  158. RL=R_L;
  159. TH=T_H;
  160. TL=T_L;
  161. }
  162. humi_value = RH;
  163. temp_value = TH;
  164. }
  165. }
  166. void AlarmJudge(void)
  167. {
  168. // if(temp_value>AlarmTH)// 温度是否过高
  169. // {
  170. // LedTH_P=0;
  171. // LedTL_P=1;
  172. // }
  173. // else if(temp_value<AlarmTL)// 温度是否过低
  174. // {
  175. // LedTL_P=0;
  176. // LedTH_P=1;
  177. // }
  178. // else// 温度正常
  179. // {
  180. // LedTH_P=1;
  181. // LedTL_P=1;
  182. // }
  183. if(humi_value>AlarmHH)// 湿度是否过高
  184. {
  185. LedHH_P=0;
  186. LedHL_P=1;
  187. }
  188. else if(humi_value<AlarmHL) // 湿度是否过低
  189. {
  190. LedHL_P=0;
  191. LedHH_P=1;
  192. }
  193. else // 湿度正常
  194. {
  195. LedHH_P=1;
  196. LedHL_P=1;
  197. }
  198. // if((LedHH_P==0)||(LedHL_P==0)||(LedTH_P==0)||(LedTL_P==0)) // 蜂鸣器判断,只要至少1个报警灯亮,蜂鸣器就报警
  199. // {
  200. // for(i=0;i<3;i++)
  201. // {
  202. // beep=0;
  203. // delay_ms(20);
  204. // beep=1;
  205. // delay_ms(20);
  206. // }
  207. // }
  208. }
  209. void key_handle(void)
  210. {
  211. }
  212. void key_scan(void)
  213. {
  214. static unsigned char key_in_flag = 0;//按键按下标志
  215. unsigned char key_l;//存储扫描到行列值。
  216. // key_value = 20;//按键值清除
  217. // if((P3 | 0xf0) != 0xf0)//按键按下
  218. // {
  219. // delay_ms(1);//按键消抖动
  220. // if(((P3 | 0xf0) != 0xf0) && (key_in_flag == 1))
  221. // {
  222. // key_in_flag = 0;//松手检测防止一直触发
  223. // P3 = 0xf0;
  224. // //delay_ms(1);//按键消抖动
  225. // key_l = P3;//扫描得到按键值
  226. // switch(key_l)
  227. // {
  228. // //获取按键值
  229. // case 0xf1:
  230. // {
  231. // key_value = 1;
  232. // }
  233. // break;
  234. // case 0xf2:
  235. // {
  236. // key_value = 2;
  237. // }
  238. // break;
  239. // case 0xf4:
  240. // {
  241. // key_value = 3;
  242. // }
  243. // break;
  244. // //case 0x70:
  245. // //break;
  246. // }
  247. // }
  248. // }
  249. // else
  250. // {
  251. // key_in_flag = 1;//(按键松开标志)
  252. // }
  253. if(KEY1 == 1)
  254. {
  255. delay_ms(5);
  256. if(KEY1 == 1)
  257. {
  258. mode = 0;
  259. wri_string(2,12,"Auto");//初始化显示
  260. while(KEY1);
  261. }
  262. }
  263. if(KEY2 == 1)
  264. {
  265. delay_ms(5);
  266. if(KEY2 == 1)
  267. {
  268. mode = 1;
  269. wri_string(2,12,"Manu");//初始化显示
  270. while(KEY2);
  271. }
  272. }
  273. if(KEY3 == 1)
  274. {
  275. delay_ms(5);
  276. if(KEY3 == 1)
  277. {
  278. motor_direc = 0;//正转
  279. if(motor_mode == 0)
  280. {
  281. motor_mode = 1;
  282. }
  283. else
  284. {
  285. motor_mode = 0;
  286. }
  287. while(KEY3);
  288. }
  289. }
  290. if(KEY4 == 1)
  291. {
  292. delay_ms(5);
  293. if(KEY4 == 1)
  294. {
  295. motor_direc = 1;
  296. if(motor_mode == 0)
  297. {
  298. motor_mode = 1;
  299. }
  300. else
  301. {
  302. motor_mode = 0;
  303. }
  304. while(!KEY4);
  305. }
  306. }
  307. }
  308. /******************************************************
  309. ** 函数名:key_service
  310. ** 描述 :按键服务函数
  311. ** 输入 :无
  312. ** 输出 :无
  313. ** 调用 :主程序
  314. ******************************************************/
  315. void key_service(void)
  316. {
  317. switch (now_window)
  318. {
  319. case normal_mode:
  320. {
  321. if (key_value == 1)
  322. {
  323. now_window = set_mode;
  324. curr_menu = 0;
  325. wri_string(1,0,"T: - ");//初始化显示
  326. wri_string(2,0,"H: - ");//初始化显示
  327. lcd_write_char(1,2,AlarmTL);
  328. lcd_write_char(1,6,AlarmTH);
  329. lcd_write_char(2,2,AlarmHL);
  330. lcd_write_char(2,6,AlarmHH);
  331. lcd1602_guanbiao(1,3,1);
  332. }
  333. }
  334. break;
  335. case set_mode:
  336. {
  337. if (key_value == 1)
  338. {
  339. ++curr_menu;
  340. if (curr_menu==1)
  341. {
  342. lcd1602_guanbiao(1,7,1);
  343. }
  344. else if(curr_menu==2)
  345. {
  346. lcd1602_guanbiao(2,3,1);
  347. }
  348. else if(curr_menu==3)
  349. {
  350. lcd1602_guanbiao(2,7,1);
  351. }
  352. if(curr_menu>3)
  353. {
  354. curr_menu = 0;
  355. lcd1602_guanbiao(2,7,0);
  356. now_window = normal_mode;
  357. wri_string(2,0,times);//初始化显示
  358. wri_string(2,6,date);
  359. wri_string(2,0," ");//初始化显示
  360. wri_string(1,0,"H: %RH T: C ");//初始化显示
  361. lcd_write_char(1,2,humi_value);
  362. lcd_write_char(1,11,temp_value);
  363. // lcd_wri_com(0xcd);
  364. // lcd_wri_data(0xdf);
  365. }
  366. }
  367. if (key_value == 2)
  368. {
  369. if(curr_menu==0)
  370. {
  371. if(++AlarmTL>99)
  372. {
  373. AlarmTL = 0;
  374. }
  375. lcd_write_char(1,2,AlarmTL);
  376. lcd1602_guanbiao(1,3,1);
  377. }
  378. else if (curr_menu==1)
  379. {
  380. if(++AlarmTH>99)
  381. {
  382. AlarmTH = 0;
  383. }
  384. lcd_write_char(1,6,AlarmTH);
  385. lcd1602_guanbiao(1,7,1);
  386. }
  387. else if(curr_menu==2)
  388. {
  389. if(++AlarmHL>99)
  390. {
  391. AlarmHL = 0;
  392. }
  393. lcd_write_char(2,2,AlarmHL);
  394. lcd1602_guanbiao(2,3,1);
  395. }
  396. else if(curr_menu==3)
  397. {
  398. if(++AlarmHH>99)
  399. {
  400. AlarmHH = 0;
  401. }
  402. lcd_write_char(2,6,AlarmHH);
  403. lcd1602_guanbiao(2,7,1);
  404. }
  405. }
  406. if (key_value == 3)
  407. {
  408. if(curr_menu==0)
  409. {
  410. if(--AlarmTL<0)
  411. {
  412. AlarmTL = 99;
  413. }
  414. lcd_write_char(1,2,AlarmTL);
  415. lcd1602_guanbiao(1,3,1);
  416. }
  417. else if (curr_menu==1)
  418. {
  419. if(--AlarmTH<0)
  420. {
  421. AlarmTH = 99;
  422. }
  423. lcd_write_char(1,6,AlarmTH);
  424. lcd1602_guanbiao(1,7,1);
  425. }
  426. else if(curr_menu==2)
  427. {
  428. if(--AlarmHL<0)
  429. {
  430. AlarmHL = 99;
  431. }
  432. lcd_write_char(2,2,AlarmHL);
  433. lcd1602_guanbiao(2,3,1);
  434. }
  435. else if(curr_menu==3)
  436. {
  437. if(--AlarmHH<0)
  438. {
  439. AlarmHH = 99;
  440. }
  441. lcd_write_char(2,6,AlarmHH);
  442. lcd1602_guanbiao(2,7,1);
  443. }
  444. }
  445. }
  446. break;
  447. }
  448. }
  449. /******************************************************
  450. ** 函数名:alm
  451. ** 描述 :定时闪烁函数
  452. ** 输入 : 无
  453. ** 输出 :无
  454. ** 调用 :中断调用
  455. ******************************************************/
  456. void main(void)
  457. {
  458. init_all_hardware();//初始化硬件,IO和定时器
  459. while(1)
  460. {
  461. key_scan();//按键扫描
  462. key_handle();
  463. time_service();//时间处理函数
  464. Get_Light();
  465. }
  466. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/455976
推荐阅读
相关标签
  

闽ICP备14008679号