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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3080|回復: 1
收起左側

51單片機定時器LCD顯示加音樂程序

[復制鏈接]
ID:230208 發表于 2017-9-5 17:56 | 顯示全部樓層 |閱讀模式
51單片機定時器LCD顯示加音樂

單片機源程序如下:

  1. #include<reg51.h>       //調用51單片機的頭文件
  2. #define uchar unsigned char
  3. #define uint  unsigned  int
  4. //---------------------------------------
  5. //1602液晶相關I/O設置
  6. //sbit E=P2^3;               //1602液晶的E腳接在P2.3口上
  7. //sbit RW=P2^4;              //1602液晶的RW腳接在P2.4口上
  8. //sbit RS=P2^5;              //1602液晶的RS腳接在P2.5口上
  9. sbit E=P2^7;               //1602液晶的E腳接在P2.3口上
  10. sbit RW=P2^5;              //1602液晶的RW腳接在P2.4口上
  11. sbit RS=P2^6;              //1602液晶的RS腳接在P2.5口上
  12. sbit Busy=P0^7;

  13. //按鍵相關I/O設置
  14. sbit key1=P3^0;
  15. sbit key2=P3^1;
  16. sbit key3=P3^2;

  17. //sbit beep = P1^3;
  18. sbit beep = P1^5;

  19. uchar code word1[]={"   TIME  STOP   "};
  20. uchar code word2[]={"   TIME  SET!   "};
  21. uchar code word3[]={"   TIME  START  "};
  22. //---------------------------------------
  23. unsigned char i;
  24. unsigned char menu;
  25. signed int Time_bai,Time_ge;
  26. bit Adjust;
  27. //---------------------------------------
  28. //1602液晶寄存器設置
  29. unsigned int  DISbuf_ge,DISbuf_bai;     //設置16位的unsigend int型寄存器用來暫存1602要顯示的內容
  30. //---------------------------------------
  31. uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,

  32. 212,212,106,126,159,169,190,119,119,126,159,142,159,0};


  33. uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,

  34. 9,3,12,12,12,12,12,9,3,12,12,12,24,0};
  35. void Display();
  36. void DelayMS(uint ms)
  37. {
  38.         uchar t;
  39.         while(ms--)
  40.         {
  41.                  for(t=0;t<120;t++);
  42.         }
  43. }
  44. void PlayMusic()

  45. {

  46.         uint i=0,j,k;
  47.        
  48.         while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
  49.        
  50.         { //播放各個音符,SONG_LONG 為拍子長度
  51.        
  52.                 for(j=0;j<SONG_LONG[i]*20;j++)
  53.                
  54.                 {
  55.                
  56.                         beep=~beep;
  57.                         if(Adjust==1)
  58.                                 break;
  59.                        
  60.                         //SONG_TONE 延時表決定了每個音符的頻率
  61.                        
  62.                         for(k=0;k<SONG_TONE[i]/3;k++);
  63.                
  64.                 }
  65.                
  66.                  DelayMS(70);
  67.                  i++;
  68.        
  69.         }

  70. }
  71. void led()
  72. {
  73.         P2 = P2 << 1;           //第一次循環,led1亮,其他都不亮
  74.         if(P2 == 0x00)     //全部移出
  75.         P2 = 0x01;
  76. }
  77. //---------------------------------------
  78. //名稱:1602液晶用延時函數
  79. //---------------------------------------
  80. void Delay1602(unsigned int t)
  81. {
  82.      unsigned int k;      //定義一個16位寄存器用來做延時用
  83.      for(k=0;k<t;k++);    //延時
  84. }

  85. //---------------------------------------
  86. //名稱:1602液晶忙檢測函數
  87. //---------------------------------------
  88. void LCD1602_busy(void)
  89. {
  90.      Busy=1;              //將P0.7置1,為讀狀態做準備
  91.      RS=0;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  92.      RW=1;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  93.      E=1;                 //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
  94.      while(Busy==1);      //由P0.7讀入1,表示1602液晶忙,需要等待
  95.      E=0;                 //讀完以后,恢復E的電平
  96. }

  97. //---------------------------------------
  98. //名稱:1600寫命令函數
  99. //適用:給力者GL9單片機開發學習系統
  100. //公司:寧波芯動電子有限公司
  101. //網址:www.MovingChip.com
  102. //日期:20120914
  103. //---------------------------------------
  104. void LCD1602_Write_com(unsigned char combuf)
  105. {
  106.      RS=0;                //選擇指令寄存器
  107.      RW=0;                //選擇寫狀態
  108.      P0=combuf;           //將命令字通過P0口送至DB
  109.      E=1;                 //E高電平將命令字寫入1602液晶
  110.      E=0;                 //寫完以后,恢復E的電平
  111. }

  112. //---------------------------------------
  113. //名稱:1602寫命令函數(帶忙檢測)
  114. //---------------------------------------
  115. void LCD1602_Write_com_busy(unsigned char combuf)
  116. {
  117.      LCD1602_busy();            //調用忙檢測函數
  118.      LCD1602_Write_com(combuf); //調用忙檢測函數
  119. }

  120. //---------------------------------------
  121. //名稱:1602寫數據函數(帶忙檢測)
  122. //---------------------------------------
  123. void LCD1602_Write_data_busy(unsigned char databuf)
  124. {
  125.      LCD1602_busy();      //調用忙檢測函數
  126.      RS=1;                //選擇數據寄存器
  127.      RW=0;                //選擇寫狀態
  128.      P0=databuf;          //將命令字通過P0口送至DB
  129.      E=1;                 //E高電平將命令字寫入1602液晶
  130.      E=0;                 //寫完以后,恢復E的電平
  131. }

  132. //---------------------------------------
  133. //名稱:1602液晶顯示地址寫函數
  134. //適用:給力者GL9單片機開發學習系統
  135. //公司:寧波芯動電子有限公司
  136. //網址:www.MovingChip.com
  137. //日期:20120914
  138. //---------------------------------------
  139. void LCD1602_Write_address(unsigned char x,unsigned char y)
  140. {
  141.      x&=0x0f;             //列地址限制在0-15間
  142.      y&=0x01;             //行地址限制在0-1間
  143.      if(y==0)             //如果是第一行
  144.          LCD1602_Write_com_busy(x|0x80);        //將列地址寫入
  145.      else                 //如果是第二行
  146.          LCD1602_Write_com_busy((x+0x40)|0x80); //將列地址寫入
  147. }

  148. //---------------------------------------
  149. //名稱:1602液晶初始化函數
  150. //---------------------------------------
  151. void LCD1602_init(void)
  152. {
  153.      Delay1602(1500);               //調用延時函數
  154.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  155.      Delay1602(500);                //調用延時函數
  156.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  157.      Delay1602(500);                //調用延時函數
  158.      LCD1602_Write_com(0x38);       //8位數據總線,兩行顯示模式,5*7點陣顯示
  159.      LCD1602_Write_com_busy(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  160.      LCD1602_Write_com_busy(0x08);  //顯示功能關,無光標
  161.      LCD1602_Write_com_busy(0x01);  //清屏
  162.      //LCD1602_Write_com_busy(0x06);  //寫入新的數據后,光標右移,顯示屏不移動
  163.      LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標
  164. }

  165. //---------------------------------------
  166. //名稱:1602液晶指定地址顯示函數
  167. //---------------------------------------
  168. void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
  169. {
  170.      LCD1602_Write_address(x,y);    //先將地址信息寫入
  171.      LCD1602_Write_data_busy(buf);  //再寫入要顯示的數據
  172. }

  173. //---------------------------------------
  174. //名稱:1602液晶將字符輸出到液晶顯示
  175. //---------------------------------------
  176. void Print(unsigned char x,unsigned char y,unsigned char *str)
  177. {
  178.     LCD1602_Write_address(x,y);
  179.         while(*str!='\0')
  180.     {
  181.         LCD1602_Write_data_busy(*str);
  182.         str++;
  183.     }
  184. }
  185. //---------------------------------------
  186. //名稱:Delay10ms延時10毫秒函數
  187. //---------------------------------------
  188. void Delay10ms(void)   //誤差 0us
  189. {
  190.     unsigned char a,b,c;
  191.     for(c=1;c>0;c--)
  192.         for(b=38;b>0;b--)
  193.             for(a=130;a>0;a--);
  194. }
  195. void keyscan()
  196. {
  197.         if(key1==0)                //檢測按鍵K1是否按下
  198.         {
  199.                 Delay10ms();        //消除抖動
  200.                 while(key1==0);
  201.                 menu++;
  202.                 if(menu==3)
  203.                         menu=1;
  204.                 Adjust=1;
  205.         }
  206.         if(menu==1)
  207.         {       
  208.                 Print(0,0,word2);
  209.                 DISbuf_bai=0;
  210.                 DISbuf_ge=0;
  211.                 LCD1602_Disp(2,1,DISbuf_bai/1000+'0');       //在第1行的第1列顯示千位
  212.               LCD1602_Disp(3,1,(DISbuf_bai%1000)/100+'0'); //在第1行的第2列顯示百位
  213.                   LCD1602_Disp(4,1,':');
  214.               LCD1602_Disp(5,1,(DISbuf_ge%100)/10+'0');   //在第1行的第3列顯示十位
  215.                LCD1602_Disp(6,1,DISbuf_ge%10+'0');         //在第1行的第4列顯示個位
  216.                 if(key2==0)                //檢測按鍵K1是否按下
  217.                 {
  218.                         Delay10ms();        //消除抖動
  219.                         while(key2==0);
  220.                         Time_ge++;
  221.                         if(Time_ge>59)
  222.                         {
  223.                                 Time_ge=0;
  224.                                 Time_bai++;
  225.                         }       
  226.                 }
  227.                 if(key3==0)                //檢測按鍵K1是否按下
  228.                 {
  229.                         Delay10ms();        //消除抖動
  230.                         while(key3==0);
  231.                         Time_ge--;
  232.                         if(Time_ge<0)
  233.                         {
  234.                                 Time_ge=59;
  235.                                 Time_bai--;
  236.                         }
  237.                
  238.                 }
  239.         }
  240.         if(menu==2)
  241.         {       
  242.                 if(key2==0)                //檢測按鍵K1是否按下
  243.                 {
  244.                         Delay10ms();        //消除抖動
  245.                         while(key2==0);
  246.                         Print(0,0,word3);
  247.                         Adjust=0;       
  248.                 }
  249.                 if(key3==0)                //檢測按鍵K1是否按下
  250.                 {
  251.                         Delay10ms();        //消除抖動
  252.                         while(key3==0);
  253.                         Print(0,0,word1);
  254.                         Adjust=1;
  255.                
  256.                 }
  257.                 if(Adjust==0)
  258.                 {
  259.                         Print(0,0,word3);       
  260.                 }
  261.                 else
  262.                 {
  263.                         Print(0,0,word1);
  264.                 }
  265.         }
  266.         LCD1602_Disp(9,1,Time_bai/10+'0');       //在第1行的第1列顯示千位
  267.     LCD1602_Disp(10,1,Time_bai%10+'0'); //在第1行的第2列顯示百位
  268.           LCD1602_Disp(11,1,':');
  269.     LCD1602_Disp(12,1,Time_ge/10+'0');   //在第1行的第3列顯示十位
  270.     LCD1602_Disp(13,1,Time_ge%10+'0');         //在第1行的第4列顯示個位       
  271. }
  272. void Display()
  273. {
  274.         LCD1602_Disp(2,1,DISbuf_bai/10+'0');       //在第1行的第1列顯示千位
  275.            LCD1602_Disp(3,1,DISbuf_bai%10+'0'); //在第1行的第2列顯示百位
  276.         LCD1602_Disp(4,1,':');
  277.            LCD1602_Disp(5,1,DISbuf_ge/10+'0');   //在第1行的第3列顯示十位
  278.            LCD1602_Disp(6,1,DISbuf_ge%10+'0');         //在第1行的第4列顯示個位
  279.         if(DISbuf_ge==Time_ge && DISbuf_bai==Time_bai)
  280.                                 Adjust=1;
  281. }
  282. //---------------------------------------
  283. //名稱: 主函數
  284. //---------------------------------------
  285. void main(void)            //主函數,單片機開機后就是從這個函數開始運行
  286. {

  287.     LCD1602_init();        //調用1602液晶初始化函數

  288.     //***定時器Timer0初始化***
  289.     TMOD&=0xF0;            //將TMOD的低4位定時器0控制部分清零
  290.     TMOD|=0x01;            //設置定時器0為方式1
  291.     TL0=0xFF;              //設置定時器0初值低8位
  292.     TH0=0x4B;              //設置定時器0初值高8位
  293.     TR0=1;                 //啟動定時器0
  294.     ET0=1;                 //Timer0中斷允許
  295.     //**********************

  296.     //***開全局中斷設置****
  297.     //定時器Timer0設置了中斷允許,此處要開全局中斷
  298.     EA=1;                  //開全局中斷
  299.     //*********************
  300.         menu=2;
  301.         Adjust=1;
  302.         Time_bai=1;
  303.         Time_ge=0;
  304.         DISbuf_bai=0;
  305.         DISbuf_ge=0;
  306.         Print(0,0,word1);
  307.         LCD1602_Disp(2,1,DISbuf_bai/10+'0');       //在第1行的第1列顯示千位
  308.            LCD1602_Disp(3,1,DISbuf_bai%10+'0'); //在第1行的第2列顯示百位
  309.         LCD1602_Disp(4,1,':');
  310.     LCD1602_Disp(5,1,DISbuf_ge/10+'0');   //在第1行的第3列顯示十位
  311.     LCD1602_Disp(6,1,DISbuf_ge%10+'0');         //在第1行的第4列顯示個位
  312.         beep=1;
  313.         P0 = 0x01;
  314.     while(1)               //死循環,單片機初始化后,將一直運行這個死循環
  315.     {
  316.                   
  317.             if(Adjust==0)                         //非調節模式下顯示時間和控制燈
  318.                 {
  319.                 Display();
  320.                          PlayMusic(); //播放生日快樂

  321.                         //DelayMS(500); //播放完后暫停一段時間
  322.                 }
  323.                 else
  324.                 {
  325.                         beep = 1;
  326. ……………………

  327. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
Project8.zip (53.13 KB, 下載次數: 25)
回復

使用道具 舉報

ID:337484 發表于 2019-1-25 09:19 | 顯示全部樓層
好東西就要分享,謝了
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品观看 | 精品一区电影 | 久久伊人在 | 亚洲一区视频 | 国产在线www | 岛国在线免费观看 | 国产精品成人国产乱一区 | 久久99精品国产自在现线小黄鸭 | 亚洲一区国产精品 | 日韩一区二区在线视频 | 一色一黄视频 | 国产一区二区精品在线 | 日韩成人免费视频 | 中文字幕第十一页 | 男女羞羞视频网站 | 日韩电影a | 国产激情综合五月久久 | 99久久免费精品国产男女高不卡 | 伊人中文网 | 午夜天堂精品久久久久 | 国产精品久久久久久福利一牛影视 | 成人羞羞国产免费视频 | 午夜免费看视频 | 日韩午夜一区二区三区 | 天天操天天怕 | 国产精品久久午夜夜伦鲁鲁 | 黄色片网站在线观看 | 精品久久久久久亚洲综合网站 | 久久久免费电影 | 国产在线精品免费 | 欧美综合一区二区 | 欧美成人在线影院 | 欧美一区二区黄 | 国产成人精品999在线观看 | 亚洲毛片在线观看 | 欧美在线a | 久久精品中文 | 日本天天操 | 国产视频二区 | av中文字幕网 | 毛片a级毛片免费播放100 |