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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1479|回復: 0
打印 上一主題 下一主題
收起左側(cè)

單片機音樂發(fā)生器 proteus仿真

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:782260 發(fā)表于 2021-3-26 13:34 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include <reg51.h>
  2. #include <string.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit SDA=P1^0;          //DS1302 數(shù)據(jù)線
  6. sbit CLK=P1^1;          //DSB1302 時鐘線
  7. sbit RST=P1^2;          //DS1302 復位線
  8. sbit RS=P2^0;           //LCD 寄存器選擇
  9. sbit RW=P2^1;          //LCD 讀/寫控制
  10. sbit EN=P2^2;          //LCD 啟用
  11. sbit K1=P3^4;          //選擇
  12. sbit K2=P3^5;          //加
  13. sbit K3=P3^6;          //減
  14. sbit K4=P3^7;          //確定
  15. uchar tCount=0;
  16. uchar dat;             //定義參數(shù)
  17. //一年中每個月的天數(shù),二月的天數(shù)由年份決定
  18. uchar MonthsDays[]={31,0,31,30,31,30,31,31,30,31,30,31};
  19. //周日,周一到周六{0,1-6} [讀取 DS1302 時分別是 1-7]
  20. uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};
  21. //LCD 顯示緩沖
  22. uchar LCD_DSY_BUFFER1[]={"0019 00-00-00  "};
  23. uchar LCD_DSY_BUFFER2[]={"HWW   00:00:00 "};
  24. uchar DateTime[7]; //所讀取的日期時間
  25. char Adjust_Index=-1;//當前調(diào)節(jié)的時間對象:秒,分,時,日,月,年(0,1,2,3,4,6)
  26. uchar Change_Flag[]="-MHDM-Y";
  27. //(分,時,日,月,年) (不調(diào)節(jié)秒周)
  28. //延時,向 DS1302 寫、讀一字節(jié)以及從 DS1302 指定位置度、寫數(shù)據(jù)的程序
  29. //延時---------------------------------------------------
  30. void DelayMS(uint x)
  31. {
  32.   uchar i;
  33.   while(x--)  for(i=0;i<120;i++);
  34. }
  35. //向 DS1302 寫入一個字節(jié)
  36. void Write_A_Byte_TO_DS1302(uchar x)
  37. {
  38.   uchar i;
  39.   for(i=0;i<8;i++)
  40.   {
  41.      SDA=x&1;CLK=1; CLK=0; x>>=1;
  42.   }
  43. }
  44. //從 DA1302 讀取一字節(jié)---------------------------------------
  45. uchar Get_A_Byte_FROM_DS1302()
  46. {
  47.   uchar i,b,t;
  48.   for(i=0;i<8;i++)
  49.   {
  50.      b>>=1; t=SDA;b|=t<<7;CLK=1;CLK=0;
  51.   }
  52.   //BCD 碼轉(zhuǎn)換
  53.   return b/16*10+b%16;
  54. }
  55. //從 DS1302 指定的位置讀數(shù)據(jù)--------------------------------------
  56. uchar Read_Data(uchar addr)
  57. {
  58.   uchar dat;
  59.   RST=0;CLK=0;RST=1;
  60.   Write_A_Byte_TO_DS1302(addr);
  61.   dat=Get_A_Byte_FROM_DS1302();
  62.   CLK=1;RST=0;
  63.   return dat;
  64. }
  65. // 向 DS1302 某地址寫入數(shù)據(jù)-------------------------------------------
  66. void Write_DS1302(uchar addr,uchar dat)
  67. {
  68.   CLK=0;RST=1;
  69.   Write_A_Byte_TO_DS1302(addr);
  70.   Write_A_Byte_TO_DS1302(dat);
  71.   CLK=0;RST=0;
  72. }
  73. //-------------------------------------------
  74. //------設(shè)置時間-------------------------------------
  75. void SET_DS1302()
  76. {
  77. uchar i;
  78. Write_DS1302(0x8E,0x00); //寫控制字,取消寫保護
  79. for(i=1;i<7;i++) //分時日月年依次寫入
  80. {
  81.   //分的起始地址 10000010(0x82),后面續(xù)依次是時.日.月.周.年.寫入地址每次遞增 2  
  82.   Write_DS1302(0x80+ 2*i,(DateTime[i]/10<<4)|(DateTime[i]%10)); }
  83.   Write_DS1302(0x8E,0x80);//加保護
  84. }
  85. //---------------------------------------------------
  86. //讀取當前日期時間
  87. //---------------------------------------------------
  88. void GetTime()
  89. {
  90.   uchar i;
  91.   for(i=0;i<7;i++)
  92.   {
  93.    DateTime[i]=Read_Data(0x81+2*i);
  94.   }
  95. }
  96. //---------------------------------------------------
  97. //1602LCD 的若干顯示控制代碼
  98. //uchar Read_LCD_State() 讀 LCD 狀態(tài)
  99. uchar Read_LCD_State()
  100. {
  101.   uchar state;
  102.   RS=0;RW=1;EN=1;DelayMS(1);state=P0;EN=0;DelayMS(1);
  103.   return state;
  104. }
  105. //void LCD_Busy_Wait() 忙等待

  106. void LCD_Busy_Wait()
  107. {
  108.   while((Read_LCD_State()&0x80)==0x80);
  109.   DelayMS(5);
  110. }
  111. //void  Write_LCD_Data(uchar dat) 向 LCD 寫數(shù)據(jù)
  112. void Write_LCD_Data(uchar dat)
  113. {
  114.   LCD_Busy_Wait();
  115.   RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;
  116. }
  117. //void  Write_LCD_Command(uchar cmd) 寫 LCD 指令
  118. void  Write_LCD_Command(uchar cmd)
  119. {
  120.   LCD_Busy_Wait();
  121.   RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1);EN=0;
  122. }
  123. // Void  Init_LCD()  LCD 初始化
  124. void  Init_LCD()
  125. {
  126.   Write_LCD_Command(0x38);DelayMS(1);
  127.   Write_LCD_Command(0x01);DelayMS(1);
  128.   Write_LCD_Command(0x06);DelayMS(1);
  129.   Write_LCD_Command(0x0c);DelayMS(1);
  130. }
  131. //void Set_LCD_POS(uchar P) 設(shè)置液晶顯示位置
  132. void Set_LCD_POS(uchar p)
  133. {
  134.   Write_LCD_Command(p|0x80);
  135. }
  136. //------------------------------------------------------
  137. //在 LCD 上顯示字符串
  138. void Display_LCD_String(uchar p,uchar *s)
  139. {
  140.   uchar i;
  141.   Set_LCD_POS(p);
  142.   for(i=0;i<16;i++)
  143.   {
  144.   Write_LCD_Data(s[i]); DelayMS(1);
  145.   }
  146. }
  147. //-----------------------------------------------------------
  148. //日期與時間值轉(zhuǎn)換為數(shù)字字符
  149. void Format_DateTime(uchar d,uchar *a)
  150. {
  151.   a[0]=d/10+'0';a[1]=d%10+'0';
  152. }
  153. //----------------------------------------------------------
  154. //判斷是否為閏年
  155. uchar isLeapYear(uint y)
  156. {
  157.   return(y%4==0&y%100!=0)||(y%400==0);
  158. }
  159. //-----------------------------------------------------------
  160. //求自 2000.1.1 開始的任何一天是星期幾
  161. //函數(shù)沒有通過,求出總天數(shù)后再求星期幾
  162. //因為求總天數(shù)可能會超越 uint 的范圍
  163. void RefreshWeekDay()
  164. {  
  165.   uint i,d,w=5;
  166.   //已知 1999.12.31 是周五
  167.   for(i=2000;i<2000+DateTime[6];i++)
  168.   {
  169.         d=isLeapYear(i)?366:365;
  170.         w=(w+d)%7;
  171.   }
  172. d=0;
  173. for(i=1;i<DateTime[4];i++) d+=MonthsDays[i];
  174. d+=DateTime[3];
  175. //保存星期,0~6 表示星期日至周六,為了與DS1302 的星期格式匹配,返回值需要加 1 DateTime[5]=(w+d)%7+1;
  176. }
  177. //----------------------------------------------------------
  178. void DateTime_Adjust(char x)
  179. {
  180.   switch(Adjust_Index)
  181.   {
  182.     case 6://年 00-99
  183.          if(x==1&DateTime[6]<99) DateTime[6]++;
  184.          if(x==-1&DateTime[6]>0) DateTime[6]--;
  185.          //獲取 2 月天數(shù)
  186.          MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  187.          //如果年份變化后當前月份的天數(shù)大于上限則設(shè)為上限
  188.          if(DateTime[3]>MonthsDays[DateTime[4]])
  189.          DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay();
  190.          //刷新星期
  191.         break;
  192.     case 4:
  193.         //月 01-12
  194.         if(x==1&DateTime[4]<12)  DateTime[4]++;
  195.         if(x==-1&DateTime[4]>1)  DateTime[4]--;
  196.         //獲取 2 月天數(shù)
  197.          MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  198.          //如果月份變化后當前月份的天數(shù)大于上限則設(shè)為上限
  199.          if(DateTime[3]>MonthsDays[DateTime[4]])
  200.          DateTime[3]=MonthsDays[DateTime[4]];
  201.          RefreshWeekDay();
  202.          //刷新星期
  203.          break;
  204.         case 3://日00-28/29/30/31;調(diào)節(jié)之前首先根據(jù)年份得出該年中2月的天數(shù)        
  205.               MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
  206.           //根據(jù)當前月份決定調(diào)節(jié)日期的上限
  207.           if(x==1&DateTime[3]<MonthsDays[DateTime[4]])  DateTime[3]++;
  208.           if(x==-1&DateTime[3]>0)  DateTime[3]--;
  209.           RefreshWeekDay();//刷新星期
  210.           break;
  211.     case 2://時
  212.           if(x==1&DateTime[2]<23) DateTime[2]++;
  213.           if(x==-1&DateTime[2]>0) DateTime[2]--;
  214.           break;
  215.     case 1://分
  216.           if(x==1&DateTime[1]<59)  DateTime[1]++;
  217.           if(x==-1&DateTime[1]>0)  DateTime[1]--;
  218.           break;
  219.   }
  220. }
  221. //---------------------------------------------------------
  222. //定時器 0 每秒刷新 LCD 顯示
  223. void T0_INT() interrupt 1
  224. {
  225.   TH0=-50000/256;
  226.   TL0=-50000%256;
  227.   if(++tCount!=2) return;
  228.   tCount=0;
  229.   //按指定的格式生成待顯示的日期時間串
  230.   Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);   
  231.   Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);   
  232.   Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);
  233.   //星期 strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]);
  234.   //時分秒
  235.   Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5);   
  236.   Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8);  
  237.   Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11);
  238.   //顯示年月日,星期,時分秒
  239.   Display_LCD_String(0x00,LCD_DSY_BUFFER1);  
  240.   Display_LCD_String(0x40,LCD_DSY_BUFFER2);
  241. }
  242.   //---鍵盤中斷(INT0)-----------------------------------------
  243. void EX_INT0() interrupt 0
  244. {
  245.   if(K1==0) //選擇調(diào)整對象(Y M D H M)
  246.   {
  247.     while(K1==0);
  248.         if(Adjust_Index==-1||Adjust_Index==1) Adjust_Index=7;
  249.         Adjust_Index--;
  250.     if(Adjust_Index==5) Adjust_Index=4;//跳過對星期的調(diào)節(jié)
  251.     LCD_DSY_BUFFER2[13]='[';
  252.     LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index];
  253.         LCD_DSY_BUFFER2[15]=']';
  254.         }
  255.         else if(K2==0)//加
  256.    {
  257.      while(K2==0); DateTime_Adjust(1);
  258.    }
  259.    else if(K3==0)//減
  260.    {
  261.      while(K3==0); DateTime_Adjust(-1);
  262.    }
  263.    else if(K4==0)//確定
  264. {
  265.   while(K4==0); SET_DS1302(); //將調(diào)整后的時間寫入 1302
  266.   LCD_DSY_BUFFER2[13]=' ';
  267.   LCD_DSY_BUFFER2[14]=' ';
  268.   LCD_DSY_BUFFER2[15]=' ';
  269.   Adjust_Index=-1;
  270. //操作索引重設(shè)為-1,時間繼續(xù)正常顯示
  271. }
  272. }
  273. //---------------------------------------------------------------
  274. //主程序 void main()
  275. void main()
  276. {
  277.   Init_LCD();//液晶初始化
  278.   IE=0x83; //允許INT0,T0中斷
  279.   IP=0x01;
  280.   IT0=0x01;
  281.   TMOD=0x01;
  282.   TH0=-50000/256;
  283.   TL0=-50000%256;
  284.   TR0=1;
  285.   while(1)
  286.   {
  287.   //如果為執(zhí)行調(diào)整操作則正常讀取當前時間
  288.   if(Adjust_Index==-1) GetTime();
  289.   }
  290. }
復制代碼

新建 WinRAR 壓縮文件.rar

14.79 KB, 下載次數(shù): 5, 下載積分: 黑幣 -5

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

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人免费片 | 综合精品在线 | 国产免费观看视频 | 一级在线| 欧美视频免费 | 亚洲视频免费 | 日本久草 | 欧美日韩国产精品一区 | 欧美亚洲另类丝袜综合网动图 | 欧美精品一区二区三区一线天视频 | 亚洲精品888| 久久毛片| 成人国产一区二区三区精品麻豆 | 亚洲免费高清 | 欧美性视频在线播放 | 自拍第一页| 伊人影院在线观看 | 丁香五月网久久综合 | 免费特级黄毛片 | 国产精品网址 | 国产黄色av网站 | 玩丰满女领导对白露脸hd | 国产精品一区二区三区久久 | www.av在线 | 美女毛片免费看 | 免费观看一级特黄欧美大片 | 久久久国产精品视频 | 91精品午夜窝窝看片 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 亚洲精品电影 | 欧美成人猛片aaaaaaa | 成人福利网 | 国产精品一区二区久久 | 在线观看国产 | 美女天天操| 中文字幕亚洲视频 | 欧美精品99 | 美美女高清毛片视频免费观看 | 欧美一区二区三区四区视频 | 91欧美激情一区二区三区成人 | 91精品久久久久久久久久 |