久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6021|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

基于51單片機(jī)的聲控?zé)粼O(shè)計(jì)與protues仿真程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3.   #include<string.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
  7. sbit SDA=P1^0;  // DS1302數(shù)據(jù)線
  8. sbit CLK=P1^1;  //         DS1302時(shí)鐘線
  9. sbit RST=P1^2;  // DS1302復(fù)位線
  10. //DS18B20數(shù)據(jù)端口定義
  11. sbit DQ=P2^4;    //DS18B20數(shù)據(jù)端口
  12. sbit LCD_RS=P2^5;   // LCD寄存器選擇
  13. sbit LCD_RW=P2^6;   //         LCD讀寫/寫控制
  14. sbit LCD_EN=P2^7;   //  LCD啟用
  15. sbit K1=P3^2;   //  選擇
  16. sbit K2=P3^3;   // 確定
  17. sbit K3=P3^5;   // 加
  18. sbit K4=P3^6;  // 減


  19. sbit key_1=P3^0;        //自動(dòng)手動(dòng)切換
  20. sbit key_2=P3^1;        //關(guān)燈,按一下,關(guān)一個(gè)
  21. sbit key_3=P3^4;        //開燈,按一下,開一個(gè)
  22. uchar code zz[]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};
  23. uchar code fz[]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};  
  24. sbit R_LED=P2^0;   //紅燈
  25. sbit Y_LED=P2^1;   //黃燈
  26. sbit G_LED=P2^2;   //綠燈
  27. sbit B_LED=P2^3;   //藍(lán)燈

  28. sbit guangmin=P1^3;          //光敏電阻傳感器
  29. sbit ren1=P1^4;                  //紅外熱釋電傳感器1
  30. sbit ren2=P1^5;                  //紅外熱釋電傳感器2
  31. sbit ren3=P1^6;                  //紅外熱釋電傳感器3
  32. sbit ren4=P1^7;                  //紅外熱釋電傳感器4




  33. //溫度字符
  34. uchar code Temperature_Char[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};
  35. //溫度小數(shù)對(duì)照表
  36. uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
  37. uchar CurrentT=0; //當(dāng)前讀取溫度的整數(shù)部分
  38. uchar Temp_Value[]={0x00,0x00};         //從DS18B20讀取的溫度值
  39. uchar Display_Digit[]={0,0,0,0};//待顯示的各溫度數(shù)位
  40. bit DS18B20_IS_OK=1;//傳感器正常標(biāo)志

  41. uchar tCount=0;
  42. //一年中每個(gè)月的天數(shù),2月的天數(shù)由年份決定
  43. uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
  44. //周日,每周一到周六(0,1-6)【讀取DS1302時(shí)分別是1-7】
  45. uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};

  46. //LCD顯示緩沖
  47. uchar LCD_DSY_BUFFER1[]={"00-00-00        "};
  48. uchar LCD_DSY_BUFFER2[]={"00-00-00      "};
  49. uchar DateTime[7];  //所讀取的日期時(shí)間
  50. uchar Adjust_flag=0; //當(dāng)前調(diào)節(jié)的時(shí)間對(duì)像:秒,分,時(shí),日,月,年(1,2,3,4,5,6)
  51. uchar Change_Flag[]=" YMDHM";//(分,時(shí),日,月,年)(不調(diào)節(jié)秒與周)

  52. //延時(shí)
  53. void DelayMS(uchar x)
  54. {uchar i;
  55. while(x--)
  56. for(i=0;i<120;i++);
  57. }

  58. //向DS1302寫入一個(gè)字節(jié)
  59. void Write_A_Byte_TO_DS1302(uchar x)
  60. {uchar i;
  61. for(i=0;i<8;i++)
  62. {SDA=x&1;  CLK=1;  CLK=0; x>>=1;
  63. }
  64. }

  65. //從DS11302讀取一個(gè)字節(jié)
  66. uchar Get_A_Byte_FROM_DS1302()
  67. {uchar i,b,t;
  68. for(i=0;i<8;i++)
  69. {b>>=1; t=SDA; b|=t<<7;  CLK=1;CLK=0;
  70. }
  71. //BCD碼轉(zhuǎn)換
  72. return b/16*10+b%16;
  73. }
  74. //從DS1302指定位置讀數(shù)據(jù)
  75. uchar Read_Data(uchar addr)
  76. {uchar dat;
  77. RST=0; CLK=0; RST=1;
  78. Write_A_Byte_TO_DS1302(addr);
  79. dat=Get_A_Byte_FROM_DS1302();
  80. CLK=1;RST=0;
  81. return dat;
  82. }

  83. //向DS1302某地址寫入數(shù)據(jù)
  84. void Write_DS1302(uchar addr,uchar dat)
  85. {CLK=0;RST=1;
  86. Write_A_Byte_TO_DS1302(addr);
  87. Write_A_Byte_TO_DS1302(dat);
  88. CLK=0;RST=0;
  89. }

  90. //設(shè)置時(shí)間
  91. void SET_DS1302()
  92. { uchar i;
  93. Write_DS1302(0x8e,0x00); //寫控制字,取消寫保護(hù)
  94. //分時(shí)日月年依次寫入
  95. for(i=0;i<7;i++)
  96. {
  97. //分的起始地址10000010(0x82),后面連續(xù)依次是時(shí),日,月,周,年,寫入 地址每次增2
  98. Write_DS1302(0X80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));
  99. }
  100. Write_DS1302(0x8e,0x80);//加保護(hù)
  101. }

  102. //讀取當(dāng)前的時(shí)間
  103. void GetTime()
  104. {
  105.   uchar i;
  106.   for(i=0;i<7;i++)
  107.    {
  108.      DateTime[i]=Read_Data(0x81+2*i);
  109.    }
  110. }


  111. //LCD忙等待
  112. bit LCD_Busy_Check()
  113. {bit result;
  114. LCD_RS=0;
  115. LCD_RW=1;
  116. LCD_EN=1;
  117. delayNOP();
  118. result=(bit)(P0&0x80);
  119. LCD_EN=0;
  120. return result;
  121. }

  122. //寫指令
  123. void Write_LCD_Command(uchar cmd)
  124. {while(LCD_Busy_Check());
  125. LCD_RS=0;LCD_RW=0;LCD_EN=0;        _nop_();         _nop_();
  126. P0=cmd;
  127. delayNOP();
  128. LCD_EN=1;
  129. delayNOP();
  130. LCD_EN=0;
  131. }
  132. //寫數(shù)據(jù)
  133. void Write_LCD_Data(uchar dat)
  134. {while(LCD_Busy_Check());
  135. LCD_RS=1;LCD_RW=0;LCD_EN=0;
  136. P0=dat;
  137. delayNOP();
  138. LCD_EN=1;
  139. delayNOP();
  140. LCD_EN=0;
  141. }

  142. //初始化
  143. void Init_LCD()
  144. {Write_LCD_Command(0x01);DelayMS(5);
  145. Write_LCD_Command(0x38);DelayMS(5);
  146. Write_LCD_Command(0x0c);DelayMS(5);
  147. Write_LCD_Command(0x06);DelayMS(5);
  148. }
  149. //設(shè)置顯示位置
  150. void Set_LCD_POS(uchar pos)
  151. {        Write_LCD_Command(pos|0x80);
  152.   }

  153. //在LCD上顯示字符串
  154. void Display_LCD_String(uchar p,uchar *s)
  155. {uchar i;
  156. Set_LCD_POS(p);
  157. for(i=0;i<16;i++)
  158. {Write_LCD_Data(s[i]);
  159. DelayMS(1);
  160. }
  161. }

  162. //日期與時(shí)間值轉(zhuǎn)換為數(shù)字字符
  163. void Format_DateTime(uchar d,uchar *a)
  164. {a[0]=d/10+'0';
  165. a[1]=d%10+'0';
  166. }

  167. //判斷是否為閏年
  168. uchar isLeapYear(uint y)
  169. {return (y%4==0&&y%100!=0)||(y%400==0);
  170. }

  171. //求自2000.1.1開始的任何一天是星期幾
  172. void RefreshWeekDay()
  173. {uint i,d,w=5; //已知1999.12.31是星期五
  174. for(i=2000;i<2000+DateTime[6];i++)
  175. { d=isLeapYear(i)?366:365;
  176. w=(w+d)%7;
  177. }
  178. d=0;
  179. for(i=1;i<DateTime[4];i++)
  180. d+=MonthsDays[i];
  181. d+=DateTime[3];
  182. //保存星期,0~6表示星期日,星期一,二.....六,為了與DS1302的星期格式匹配,返回值需要加1
  183. DateTime[5]=(w+d)%7+1;
  184. }

  185. //延時(shí)函數(shù)2
  186. void Delay(uint x)
  187. {while(--x);
  188. }
  189. /***************初始化18B20溫度函數(shù)******************/
  190. uchar Init_DS18B20()
  191. {
  192.    uchar status;
  193.    DQ=1;
  194.    Delay(8);
  195.    DQ=0;
  196.    Delay(90);
  197.    DQ=1;
  198.    Delay(8);
  199.    status=DQ;
  200.    Delay(100);
  201.    DQ=1;
  202.    return status;
  203. }

  204. //讀一字節(jié)
  205. uchar ReadOneByte()
  206. {uchar i,dat=0;
  207. DQ=1;_nop_();
  208. for(i=0;i<8;i++)
  209. {DQ=0;dat>>=1;DQ=1;_nop_();_nop_();
  210. if(DQ)dat|=0x80;
  211. Delay(30);
  212. DQ=1;
  213. }
  214. return dat;
  215. }

  216. //寫一字節(jié)
  217. void WriteOneByte(uchar dat)
  218. {uchar i;
  219. for(i=0;i<8;i++)
  220. { DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
  221. }
  222. }

  223. //讀取溫度值
  224. void Read_Temperature()
  225. {
  226. //延時(shí)值與負(fù)數(shù)標(biāo)識(shí)
  227. uchar t=150,ng=0;
  228. //高5位全為1(0xf8)則為負(fù)數(shù),為負(fù)數(shù)時(shí)取反加1,并設(shè)置負(fù)數(shù)標(biāo)識(shí)

  229. if(Init_DS18B20()==1)  //DS18B20故障
  230. DS18B20_IS_OK=0;
  231. else
  232. {WriteOneByte(0xcc);   //跳過序列號(hào)
  233. WriteOneByte(0x44);//啟動(dòng)溫度轉(zhuǎn)換
  234. Init_DS18B20();
  235. WriteOneByte(0xcc);   //跳過序列號(hào)
  236. WriteOneByte(0xBE);//讀取溫度寄存器
  237. Temp_Value[0]=ReadOneByte();  //溫度低8位
  238. Temp_Value[1]=ReadOneByte();  //溫度高8位
  239. DS18B20_IS_OK=1;
  240. if((Temp_Value[1]&0xf8)==0xf8)
  241. {
  242. Temp_Value[1]=~Temp_Value[1];
  243. Temp_Value[0]=~Temp_Value[0]+1;
  244. if(Temp_Value[0]==0x00)
  245. Temp_Value[1]++;
  246. //負(fù)數(shù)標(biāo)志置1
  247. ng=1;
  248. }
  249. //查表得到溫度的小數(shù)部分
  250. Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];
  251. //獲取溫度整數(shù)部分(高字節(jié)中的低三位與低字節(jié)中的高4位,無符號(hào))
  252. CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0X07)<<4);
  253. //將整數(shù)部分分解為3位待顯示數(shù)字
  254. Display_Digit[3]=CurrentT/100;
  255. Display_Digit[2]=CurrentT%100/10;
  256. Display_Digit[1]=CurrentT%10;

  257. //刷新LCD顯示緩沖
  258. LCD_DSY_BUFFER2[13]= Display_Digit[0]+'0';
  259. LCD_DSY_BUFFER2[12]='.'        ;
  260. LCD_DSY_BUFFER2[11]=Display_Digit[1]+'0';
  261. LCD_DSY_BUFFER2[10]=Display_Digit[2]+'0';
  262. LCD_DSY_BUFFER2[9]=Display_Digit[3]+'0';
  263. //高位為0時(shí)不顯示
  264. if(Display_Digit[3]==0)         LCD_DSY_BUFFER2[9]=' ';
  265. //高位為0,且次高位為0時(shí),次高位不顯示
  266. if(Display_Digit[2]==0&&Display_Digit[3]==0)
  267. LCD_DSY_BUFFER2[10]=' ';

  268. //負(fù)數(shù)符號(hào)顯示在恰當(dāng)?shù)奈恢?br />
  269. if(ng)
  270. {if(LCD_DSY_BUFFER2[10]==' ')
  271. LCD_DSY_BUFFER2[10]='-';
  272. else
  273. if(LCD_DSY_BUFFER2[9]==' ')
  274. LCD_DSY_BUFFER2[9]='-';
  275. else
  276.   LCD_DSY_BUFFER2[8]='-';
  277. }
  278. }
  279. }


  280. //鍵盤中斷 0
  281. void EX_INT0() interrupt 0
  282. {if(K1==0)  //選擇調(diào)整對(duì)象(Y M D H M)
  283. { while(K1==0);
  284. Adjust_flag++;
  285. LCD_DSY_BUFFER1[13]='[';
  286. LCD_DSY_BUFFER1[14]=Change_Flag[Adjust_flag];
  287. LCD_DSY_BUFFER1[15]=']';
  288. if(Adjust_flag==6)
  289. {Adjust_flag=0;
  290. LCD_DSY_BUFFER1[13]=' ';
  291. LCD_DSY_BUFFER1[14]=' ';
  292. LCD_DSY_BUFFER1[15]=' ';

  293. }
  294. }
  295. }

  296. //鍵盤中斷1
  297. void EX_INT1() interrupt 2
  298. {
  299. while(K2==0);
  300. SET_DS1302();//將調(diào)整后的時(shí)間寫入DS1302
  301. LCD_DSY_BUFFER1[13]=' ';
  302. LCD_DSY_BUFFER1[14]=' ';
  303. LCD_DSY_BUFFER1[15]=' ';
  304. Adjust_flag=0;//操作索引重設(shè)為-1,時(shí)間繼續(xù)正常顯示
  305. }


  306. //定時(shí)器0每秒刷新LCD顯示
  307. void T0_INT() interrupt 1
  308. { uchar i;
  309. TH0=-50000/256;
  310. TL0=-50000%256;
  311. Set_LCD_POS(0X4e);Write_LCD_Data(0Xdf);
  312. Set_LCD_POS(0X4f);Write_LCD_Data('C');
  313. if(++tCount!=2) return;
  314. tCount=0;
  315. Read_Temperature();
  316. //按指定的格式生成待顯示的日期時(shí)間串
  317. Format_DateTime(DateTime[6],LCD_DSY_BUFFER1);
  318. Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+3);
  319. Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+6);
  320. //星期
  321. strcpy(LCD_DSY_BUFFER1+9,WEEK[DateTime[5]-1]);
  322. //時(shí)分秒
  323. Format_DateTime(DateTime[2],LCD_DSY_BUFFER2);
  324. Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+3);
  325. Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+6);
  326. //顯示年月日,星期,時(shí)分秒
  327. Display_LCD_String(0x00,LCD_DSY_BUFFER1);
  328. Set_LCD_POS(0x40);
  329. for(i=0;i<14;i++)
  330. {
  331. Write_LCD_Data(LCD_DSY_BUFFER2[i]);
  332. DelayMS(1);
  333. }
  334. }

  335. //手動(dòng)按鍵控制燈函數(shù)
  336. void key_LED()
  337. {
  338.   R_LED=1;
  339.   Y_LED=1;
  340.   G_LED=1;
  341.   B_LED=1;
  342.   if(key_2==0)
  343.    {
  344.        R_LED=0;
  345.        Y_LED=0;
  346.        G_LED=0;
  347.        B_LED=0;  
  348.    }
  349.   if(key_3==0)
  350.    {
  351.        R_LED=1;
  352.        Y_LED=1;
  353.        G_LED=1;
  354.        B_LED=1;  
  355.    }

  356. }


  357. //主程序
  358. void main()
  359. {
  360. Init_LCD();//液晶初始化
  361. IE=0X87;//允許INT0,T0中斷
  362. IP=0X05;
  363. IT0=0X01;
  364. IT1=0X01;
  365. TMOD=0X01;
  366. TH0=-50000/256;
  367. TL0=-50000%256;
  368. TR0=1;
  369. while(1)
  370. {  
  371.   R_LED=Y_LED=G_LED=B_LED=1;
  372.   if(key_1==0)        //手動(dòng)模式
  373.    {
  374.             key_LED();         //按鍵控制燈函數(shù)
  375.    }
  376.   else
  377.    {
  378.             if(DateTime[2]>18||DateTime[2]<6||guangmin==0)
  379.       {
  380.             if(ren1==0)
  381.                  {
  382.                    R_LED=0;
  383.                Y_LED=1;
  384.                G_LED=1;
  385.                B_LED=1;
  386.                  }
  387.                 if(ren2==0)
  388.                  {
  389.                    R_LED=0;
  390.                Y_LED=0;
  391.                G_LED=1;
  392.                B_LED=1;
  393.                  }
  394.             if(ren3==0)
  395.                  {
  396.                    R_LED=0;
  397.                Y_LED=0;
  398.                G_LED=0;
  399.                B_LED=1;
  400.                  }
  401.                 if(ren4==0)
  402.                  {
  403.                    R_LED=0;
  404.                Y_LED=0;
  405.                G_LED=0;
  406.                B_LED=0;         
  407.                  }
  408.           }

  409.    }
  410. switch(Adjust_flag)
  411. {
  412. case 0:GetTime(); break;
  413. case 1:
  414. if(K3==0&&DateTime[6]<99)
  415. {
  416. while(K3==0);
  417. DateTime[6]++;}

  418. if(K4==0&&DateTime[6]>0)
  419. {
  420. while(K4==0);
  421. DateTime[6]--;
  422. }
  423. MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  424. //如果年份變化后當(dāng)前月份的天數(shù)大于上限則設(shè)為上限
  425. if(DateTime[3]>MonthsDays[DateTime[4]])
  426. DateTime[3]=MonthsDays[DateTime[4]];
  427. RefreshWeekDay();//刷新星期
  428. break;

  429. case 2:
  430. if(K3==0&&DateTime[4]<12)
  431. {
  432. while(K3==0);
  433. DateTime[4]++;}

  434. if(K4==0&&DateTime[4]>1)
  435. {
  436. while(K4==0);
  437. DateTime[4]--;
  438. }
  439. //獲取2月份天數(shù)
  440. MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  441. //如果變化后當(dāng)前月份的天數(shù)大于上限則設(shè)為上限
  442. if(DateTime[3]>MonthsDays[DateTime[4]])
  443. DateTime[3]=MonthsDays[DateTime[4]];
  444. RefreshWeekDay();//刷新星期
  445. break;

  446. case 3://日00-28/29/30/31,調(diào)節(jié)之前首先根據(jù)年份得出該年中2月的天數(shù)
  447. MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  448. //根據(jù)當(dāng)前的月份決定調(diào)節(jié)日期的上限
  449. if(K3==0&&DateTime[3]<MonthsDays[DateTime[4]])
  450. {
  451. while(K3==0);
  452. DateTime[3]++;}
  453. if(K4==0&&DateTime[3]>0)
  454. {
  455. while(K4==0);
  456. DateTime[3]--;
  457. }
  458. break;

  459. case 4://時(shí)
  460. if(K3==0&&DateTime[2]<23)
  461. {
  462. while(K3==0);
  463. DateTime[2]++;}
  464. if(K4==0&&DateTime[2]>0)
  465. {
  466. while(K4==0);
  467. DateTime[2]--; }
  468. break;
  469. case 5://分
  470. if(K3==0&&DateTime[1]<59)
  471. { while(K3==0);
  472. DateTime[1]++;   }
  473. if(K4==0&&DateTime[1]>0)
  474. {while(K4==0);
  475. DateTime[1]--;        
  476. }
  477. break;
  478. }
  479. }}
復(fù)制代碼
全部資料51hei下載地址:
仿真與程序.rar (222.13 KB, 下載次數(shù): 111)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1067911 發(fā)表于 2023-4-9 20:20 | 只看該作者
為什么LCD屏幕不能顯示
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久亚洲一区 | 国产精品欧美一区二区三区 | 日本一二三区电影 | 伊人网综合 | 成人免费三级电影 | 中文字幕在线观看一区二区 | 国产一区亚洲二区三区 | 久久激情视频 | 中文字幕综合在线 | 日韩欧美天堂 | 91av在线看 | 日韩一区二区三区精品 | 国产精品久久久久久久久图文区 | 69亚洲精品| 在线免费国产 | 91最新视频| 97人人草| 亚洲传媒在线 | 国产一区不卡 | 国产丝袜一区二区三区免费视频 | 国内精品久久久久久久影视简单 | 久久99国产精品久久99果冻传媒 | 久久久久久久香蕉 | 成人免费视频网站在线看 | 成人综合视频在线观看 | 宅女噜噜66国产精品观看免费 | 区一区二区三在线观看 | 三级成人在线 | 日韩av在线一区 | 丁香婷婷成人 | 青青草华人在线视频 | 在线视频a| 日韩精品一区二区三区在线播放 | 黄色大片免费播放 | 一区二区三区欧美 | 国产一区二区三区在线看 | 亚洲人在线| 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 久久大香| h片在线看 | 男女视频在线观看免费 |