或者有人知道怎么改這個程序讓它響30S嗎?比如說在6點30分響后讓它響30S
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define KEY_IO P3
- #define LCD_IO P0
- //以下是C調(diào)低音的音頻宏定義
- #define L1 262 //將"L1"宏定義為低音"1"的頻率262Hz 時間是1/262=3826/2 us 取半周期
- #define L2 286 //將"L2"宏定義為低音"2"的頻率286Hz
- #define L3 311 //將"L3"宏定義為低音"3"的頻率311Hz
- #define L4 349 //將"L4"宏定義為低音"4"的頻率349Hz
- #define L5 392 //將"L5"宏定義為低音"5"的頻率392Hz
- #define L6 440 //將"l_a"宏定義為低音"6"的頻率440Hz
- #define L7 494 //將"L7"宏定義為低音"7"的頻率494Hz
- //以下是C調(diào)中音的音頻宏定義
- #define Z1 523 //將"Z1"宏定義為中音"1"的頻率523Hz
- #define Z2 587 //將"Z2"宏定義為中音"2"的頻率587Hz
- #define Z3 659 //將"Z3"宏定義為中音"3"的頻率659Hz
- #define Z4 698 //將"Z4"宏定義為中音"4"的頻率698Hz
- #define Z5 784 //將"Z5"宏定義為中音"5"的頻率784Hz
- #define Z6 880 //將"Z6"宏定義為中音"6"的頻率880Hz
- #define Z7 987 //將"Z7"宏定義為中音"7"的頻率523H
- //以下是C調(diào)高音的音頻宏定義
- #define H1 1046 //將"H1"宏定義為高音"1"的頻率1046Hz
- #define H2 1174 //將"H2"宏定義為高音"2"的頻率1174Hz
- #define H3 1318 //將"H3"宏定義為高音"3"的頻率1318Hz
- #define H4 1396 //將"H4"宏定義為高音"4"的頻率1396Hz
- #define H5 1567 //將"H5"宏定義為高音"5"的頻率1567Hz
- #define H6 1760 //將"H6"宏定義為高音"6"的頻率1760Hz
- #define H7 1975 //將"H7"宏定義為高音"7"的頻率1975Hz
- sbit k4=P3^3;
- sbit sound=P1^6; //蜂鳴器
- unsigned int C; //儲存定時器的定時常數(shù)
- sbit LCD_RS = P2^0;
- sbit LCD_RW = P2^1;
- sbit LCD_EN = P2^2;
- sbit LED = P2^4;
- void music(void);
- unsigned char u,t;
- bit new_s, modify = 0;
- char t0, sec = 40, min = 29, hour = 6;
- char code LCD_line1[] = "HAPPY EVEDAY";
- char code LCD_line2[] = "Timer: 00:00:00 ";
- char Timer_buf[] = "23:59:50";
- //---------------------------------------------------
- void delay(uint z)
- {
- uint x, y;
- for(x = z; x > 0; x--) for(y = 100; y > 0; y--);
- }
- void delay1()
- {
- unsigned char i,j;
- for(i=0;i<100;i++)
- for(j=0;j<250;j++)
- ;
- }
- //---------------------------------------------------
- void W_LCD_Com(uchar com) //寫指令
- {
- LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都為低電平時,寫入指令
- LCD_EN = 1; delay(5); LCD_EN = 0; //用EN輸入一個高脈沖
- }
- //---------------------------------------------------
- void W_LCD_Dat(uchar dat) //寫數(shù)據(jù)
- {
- LCD_RS = 1; LCD_IO = dat; // LCD_RS為高、R/W為低時,寫入數(shù)據(jù)
- LCD_EN = 1; delay(5); LCD_EN = 0; //用EN輸入一個高脈沖
- }
- //---------------------------------------------------
- void W_LCD_STR(uchar *s) //寫字符串
- {
- while(*s) W_LCD_Dat(*s++);
- }
- //---------------------------------------------------
- void W_BUFF(void) //填寫顯示緩沖區(qū)
- {
- Timer_buf[7] = sec % 10 + 48;/*秒除以10,并取余數(shù)*/ Timer_buf[6] = sec / 10 + 48; /*秒除以10,并取整數(shù)*/
- Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;
- Timer_buf[1] = hour % 10 + 48; Timer_buf[0] = hour / 10 + 48;
- W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);
- }
- //---------------------------------------------------
- uchar read_key(void) //按鍵 判斷
- {
- uchar x1, x2;
- KEY_IO = 255;
- x1 = KEY_IO; // if (new_s) {
- if (x1 != 255) { // new_s = 0; sec++; sec %= 60;
- delay(100); // if(!sec) { min++; min %= 60;
- x2 = KEY_IO; // if(!min) { hour++; hour %= 24;}
- if (x1 != x2) return 255; // }
- while(x2 != 255) x2 = KEY_IO; // W_BUFF();
- if (x1 == 0x7f) return 0;
- else if (x1 == 0xbf) return 1;
- else if (x1 == 0xdf) return 2;
- else if (x1 == 0xef) return 3;
-
- }
- return 255;
- }
- //---------------------------------------------------
- void Init()
- {
- LCD_RW = 0;
- W_LCD_Com(0x38); delay(50);
- W_LCD_Com(0x0c);
- W_LCD_Com(0x06);
- W_LCD_Com(0x01);
- W_LCD_Com(0x80); W_LCD_STR(LCD_line1);
- W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);
- TMOD = 0x01; //T0定時方式1 16位
- TH0 = 0x4c;
- TR0 = 1; //啟動T0
-
- ET0 = 1;
- ET1=1;
- EA = 1;
- }
- //-----------------------------------------------------------
- void music(void)
- {
-
- //以下是《天空之城》簡譜 //每行對應一小節(jié)音符
- unsigned int code f[]={ Z6,Z7,/**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,/**/Z5,Z3,Z3, /**/Z4,Z3,Z4,H1,
- Z3,H1,H1,H1,/**/Z7,Z4,Z4,Z7,/**/Z7,Z6,Z7, /**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,
- Z5, Z3,/**/Z4,H1,Z7,H1,/**/H2,H2,H2,H1,/**/H1,Z6,Z7,Z5,/**/Z6,H1,H2, /**/H3,H2,H3,H5,
- H2,Z5,Z5, /**/H1,Z7,H1,H3,/**/H3, /**/Z6,H1,Z7,H2,/**/H1,Z5,Z5, /**/H4,H3,H2,H1,
- H3, /**/Z3,H3, /**/H6,H5,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,H5,/**/H3,H3,
- H6,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,Z7,/**/Z6,Z6,Z7, /**/Z6,
- 0xff }; //以0xff作為音符的結束標志
- //以下是簡譜中每個音符的節(jié)拍
- //"4"對應4個延時單位,"2"對應2個延時單位,"1"對應1個延時單位
- unsigned char code JP[ ]={ 4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,4,12,
- 20,4,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8,
- 32, 4, /**/8,4,6,8, /**/4,4,4,16, /**/8,4,6,8, /**/24,4,4, /**/12,4,8,8,
- 24,4,4, /**/4,4,8,8, /**/32, /**/4,8,8,6, /**/12,4,16, /**/8,8,8,8,
- 30, /**/20,8, /**/16,8,8, /**/4,4,16,8, /**/8,4,4,8, /**/20,8,
- 16,16, /**/4,20,8, /**/8,4,4,8, /**/20,4,4, /**/32,
- };
- EA=1; //開總中斷
- ET1=1; //定時器T1中斷允許
- TMOD &= 0x0f;
- TMOD |= 0x00; // 使用定時器T1的模式1(13位計數(shù)器)
- TR1=1;
- while(1) //無限循環(huán)
- {
- u=0; //從第1個音符f[0]開始播放
- while(f[u]!=0xff) //只要沒有讀到結束標志就繼續(xù)播放
- {
- C=460830/f[u]; //
- TH1=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法 5
- TL1=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法
- TR1=1; //啟動定時器T0
- for(t=0;t<JP[u];t++) //控制節(jié)拍數(shù)
- delay1(); //延時1個節(jié)拍單位
- TR1=0; //關閉定時器T1
- u++; //播放下一個音符
- if(k4==0) //暫停按鍵
- { delay(2);
- if(k4==0)
- {
- ET1=0; // 關 允許T1,相當于關音樂
- }
- break;
- }
- ET1=1; //為了不影響第二次播放音樂,再 開 允許T1
- }
- sound=0;
-
- break;
- }
- }
- //---------------------------------------------------
- void main()
- {
- uchar Key;
- Init();
- while(1)
- {
- //-------------------------------
-
- //-------------------------------
- if (!sec && min==30 && hour==6)
- { //整點報時 // 可以自己定鬧鐘
- music();
- }
-
- //-------------------------------
- Key = read_key(); //讀出按鍵
- switch(Key)
- { //分別處理四個按鍵
- case 0: modify = 1; break;
- case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}
- case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}
- case 3: modify = 0; break;
- }
- }
- }
- //---------------------------------------------------
- void timer0(void) interrupt 1 //T0中斷函數(shù), 50ms執(zhí)行一次 T0中斷等級是1 注意
- {
- TH0 = 0x4c;
- t0++; t0 %= 20; //20, 一秒鐘
- if(t0 == 0) {new_s = 1; LED = ~LED;}
- if (new_s)
- { //如果出現(xiàn)了新的一秒, 修改時間
- new_s = 0; sec++; sec %= 60;
- if(!sec) // 如果SEC為零,說明滿了60秒, 進入下一步
- { min++; min %= 60;
- if(!min) // 如果MIN為零,說明滿了60分鐘,進入下一步
- { hour++; hour %= 24;
- }
- }
- W_BUFF(); //寫顯示
- if(modify) LED = 0;
- }
- }
- void Time1(void ) interrupt 3 //T1定時器的中斷等級要注意 是3
- {
- sound=!sound; //將P3.7引腳輸出電平取反,形成方波
- TH1=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法
- TL1=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法
- }
復制代碼
|