- /*預處理命令*/
- #include<reg52.h> //包含單片機寄存器的頭文件
- #include<intrins.h> //包含_nop_()函數定義的頭文件
- #define uchar unsigned char
- #define uint unsigned int
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- sbit LED1 = P1^0; //定義LED燈,通過LED顯示調光效果
- sbit LED2 = P1^1; //用來對比PWM
- sbit LED3 = P1^2;
- sbit IRIN= P3^2; //紅外接收器數據線
- sbit rs=P0^7;
- sbit rw=P0^6;
- sbit lcden=P0^5;
- unsigned char time; //定義周期 該數字X基準定時時間 如果是10 則占空比是10 x 0.01ms /1ms
- void delay(unsigned char x) ;
- void delay_ms(uint z);
- char code dis []={"Countdown set:"};
- uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
- 0xf8,0x80,0x90};
- uchar IRCOM[7];
- uchar count,aa,sec=59,min,hour,ss,sg,ms,mg,hs,hg;
- //以下是1602程序
- void write_com(uchar com)
- {
- rs=0;
- lcden=0;
- P2=com;
- delay_ms(5);
- lcden=1;
- delay_ms(5);
- lcden=0;
- }
- void write_date(uchar date)
- {
- rs=1;
- lcden=0;
- P2=date;
- delay_ms(5);
- lcden=1;
- delay_ms(5);
- lcden=0;
- }
- void lcd_init()
- {
- rw=0;
- lcden=0;
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- }
- void write_fm(uchar add,uchar data1,uchar data2)
- {
- write_com(0x80+0x40+add);
- write_date(0x30+data1);
- write_date(0x30+data2);
- }
- //1602程序到此結束
- void Countup() //設置關斷時間
- {
- if(min == 60)
- {
- min = 0;
- hour++;
- if(hour == 24)
- {
- hour =0;
- }
- }
- }
- void init()
- {
- IRIN=1; //紅外接收器數據初始化為高電平
- EX0 = 1; //使能 INT0 外部中斷
- IT0 = 1; //觸發方式為脈沖負邊沿觸發 相當于IT0=1;
-
- TMOD =0x11; //定時器設置 0.01ms in 12M crystal
- TH0=0xff;
- TL0=0xa4; //定時器0定時0.01mS
-
- TH1 = (65535-50000)/256;
- TL1 = (65535-50000)%256; //定時器1定時50mS
- ET0 = 1;
- ET1 = 1; //開啟定時器中斷
- TR0 = 1;
- TR1 = 0; //定時器1暫不開啟
- EA =1; //允許總中斷中斷,
- }
- /*******************************************************************/
- void main()
- {
- char i;
- time = 10; // 時間可以調整 這個是10調整 8位PWM就是256步
- init();
- lcd_init();
- write_com(0x80); //顯示初始界面
- i=0;
- while (dis [i]!='\0')
- {
- write_date(dis [i]);
- i++;
- }
- write_fm(4,hs,hg); //顯示初始時間
- write_date(':');
- write_fm(7,ms,mg);
- write_date(':');
- write_fm(10,ss,sg);
-
- while(!TR1); //等待紅外啟動
-
- while(TR1)
- {
- write_fm(0,IRCOM[5],IRCOM[6]); //顯示紅外鍵值
- Countup();
- ss = sec/10;
- sg = sec%10;
- ms = min/10;
- mg = min%10;
- hs = hour/10;
- hg = hour%10;
- write_fm(4,hs,hg);
- write_date(':');
- write_fm(7,ms,mg);
- write_date(':');
- write_fm(10,ss,sg); //1602顯示時間00:00:59
- if(sec == 0 && min == 0 && hour == 0)
- {
- TR1 = 0; //停止計時
- LED1 = 1; //PWM燈關閉
- }
- }
- }
- /**********************************************************/
- void IR_IN() interrupt 0 using 0 //外部中斷觸發,接收到紅外信號
- {
- unsigned char j,k,N=0;
- unsigned char q=0;
- EX0 = 0;
- delay(15);
- if (IRIN==1)
- {
- EX0 =1;
- return;
- }
- //確認IR信號出現
- while (!IRIN) //等IR變為高電平,跳過9ms的前導低電平信號。
- delay(1);
-
- for (j=0;j<4;j++) //收集四組數據
- {
- for (k=0;k<8;k++) //每組數據有8位
- {
- while (IRIN) //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
- {delay(1);}
- while (!IRIN) //等 IR 變為高電平
- delay(1);
- while (IRIN) //計算IR高電平時長
- {
- delay(1);
- N++;
- if (N>=30) //超時數據接收完畢
- {
- EX0=1;
- return;
- } //0.14ms計數過長自動離開。
- } //高電平計數完畢
- IRCOM[j]=IRCOM[j] >> 1; //數據最高位補“0” 位操作
- if(N>=8)
- {
- IRCOM[j] = IRCOM[j] | 0x80; //數據最高位補“1”
- }
- N=0;
- }
- }
-
- if(IRCOM[2]!=~IRCOM[3])
- {
- EX0=1;
- return;
- }
-
- IRCOM[5]=IRCOM[2] & 0x0F; //取鍵碼的低四位
- IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位變為低四位
-
- if(IRCOM[5]>9)
- {
- IRCOM[5]=IRCOM[5]+0x37;
- }
- else
- IRCOM[5]=IRCOM[5]+0x30;
-
- if(IRCOM[6]>9)
- {
- IRCOM[6]=IRCOM[6]+0x37;
- }
- else
- IRCOM[6]=IRCOM[6]+0x30;
- q= (((IRCOM[6]&0x0f)<<4) + (IRCOM[5]&0x0f));
-
- switch(q) //判斷按鍵鍵碼值
- {
- case 0x16:
- time = 99;break; //串口發送0
- case 0x03:
- time = 10;break; //串口發送01
- case 0x18:
- min = min+2;break; //串口發送02 設置關斷時間
- case 0x55:
- time = 30;break; //串口發送03
- case 0x08:
- ET1=1;TR1=1;break; //串口發送04 計時開始
- case 0x13:
- time = 50;break; //串口發送05
- case 0x51:
- LED1 = 1;break; //串口發送06 關斷LED1;
- case 0x42:
- time = 70;break; //串口發送07
- case 0x52:
- LED1 = 0;break; //串口發送08 開啟LED1
- case 0x41:
- time = 90;break; //串口發送09
-
- default :
- break;
- }
- EX0 = 1;
- }
- //定時器0中斷函數
- void tim0(void) interrupt 1 using 1
- {
- TH0=0xff;
- TL0=0xa4; //設置中斷時間0.01mS
- count++;
- if(count<=time)
- {
- LED1 = 0;
- }
- else
- {
- LED1 =1;
- }
- if(count>=100) //周期1ms
- {
- count =0;
- }
- }
- void timer3() interrupt 3 using 3
- {
- TH1 = (65535-50000)/256;
- TL1 = (65535-50000)%256;
- aa++;
- if(aa == 20)
- {
- aa = 0;
- sec--;
- if(sec == 0)
- {
- sec = 59;
- min--;
- if(min == 0)
- {
- min = 59;
- hour--;
- if(hour == 0)
- {
- hour =0;
- }
- }
- }
- }
- }
- /***************延時函數*****************************/
- void delay(unsigned char x) //x*0.14MS
- {
- unsigned char i;
- while(x--)
- {
- for (i = 0; i<13; i++) {}
- }
- }
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
復制代碼 |