include#define uint unsigned int #define uchar unsigned char unsigned char a[4]; //儲存用戶碼、用戶反碼與鍵數據碼、鍵數據反碼 unsigned int LowTime,HighTime; //儲存高、低電平的寬度 sbit led_r=P1^0; sbit led_g=P1^2; sbit led_b=P1^4; sbit IR=P3^2; sbit BEEP = P2^3; bit kg_flag; bit zb_flag; bit m_flag; bit bit_flag; uchar num,tl,tb,tm,tj; uchar number; uchar scw; uchar pwm_r,pwm_g,pwm_b; uchar pwm[3]; uchar bright,bright_t; uchar x[30]={0}; uchar type[30]={0}; void dealy(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } /*void delay1ms() { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<33;j++) ; } void delay(unsigned char n) { unsigned char i; for(i=0;i >1; //temp中的各數據位右移一位,因為先讀出的是高位數據 TH0=0; //定時器清0 TL0=0; //定時器清0 TR0=1; //開啟定時器T0 while(IR==0) //如果是低電平就等待 ; //低電平計時 TR0=0; //關閉定時器T0 LowTime=TH0*256+TL0; //保存低電平寬度 TH0=0; //定時器清0 TL0=0; //定時器清0 TR0=1; //開啟定時器T0 while(IR==1) //如果是高電平就等待 ; TR0=0; //關閉定時器T0 HighTime=TH0*256+TL0; //保存高電平寬度 if((LowTime<370)||(LowTime>640)) return 0; //如果低電平長度不在合理范圍,則認為出錯,停止解碼 if((HighTime>420)&&(HighTime<620)) //如果高電平時間在560微秒左右,即計數560/1.085=516次 temp=temp&0x7f; //(520-100=420, 520+100=620),則該位是0 if((HighTime>1300)&&(HighTime<1800)) //如果高電平時間在1680微秒左右,即計數1680/1.085=1548次 temp=temp|0x80; //(1550-250=1300,1550+250=1800),則該位是1 } a[i]=temp; //將解碼出的字節值儲存在a[i] } if(a[2]=~a[3]) //驗證鍵數據碼和其反碼是否相等,一般情況下不必驗證用戶碼 return 1; //解碼正確,返回1 } void exter_int0() interrupt 0 { EX0=0; //關閉外中斷0,不再接收二次紅外信號的中斷,只解碼當前紅外信號 TH0=0; //定時器T0的高8位清0 TL0=0; //定時器T0的低8位清0 TR0=1; //開啟定時器T0 while(IR==0); //如果是低電平就等待,給引導碼低電平計時 TR0=0; //關閉定時器T0 LowTime=TH0*256+TL0; //保存低電平時間 TH0=0; //定時器T0的高8位清0 TL0=0; //定時器T0的低8位清0 TR0=1; //開啟定時器T0 while(IR==1); //如果是高電平就等待,給引導碼高電平計時 TR0=0; //關閉定時器T0 HighTime=TH0*256+TL0; //保存引導碼的高電平長度 if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700)) { //如果是引導碼,就開始解碼,否則放棄,引導碼的低電平計時 //次數=9000us/1.085=8294, 判斷區間:8300-500=7800,8300+500=8800. if(DeCode()==1); // 執行遙控解碼功能 {// beep(); switch(a[2]) { case 0x07: {kg_flag=1; TR0=1; dealy(5); TR1=1; TR0=0; zb_flag=1; number=0; m_flag=1; bright_t=225; pwm[0]=bright_t; pwm[1]=bright_t; pwm[2]=bright_t; } //TR0=1; break; case 0x06: { //TR0=0; kg_flag=0; pwm[0]=0; pwm[1]=0; pwm[2]=0; } break; //TR0=1; case 0x04: { if((kg_flag==1)&&(m_flag==0)) { if((0<=number)&&(number<=14)) { if(bright_t!=25) { bright_t=bright_t-10; } } } } break; case 0x05: { if((kg_flag==1)&&(m_flag==0)) { if((0<=number)&&(number<=14)) { if(bright_t!=255) { bright_t=bright_t+10; } } } } break; case 0x09: { //TR0=0; //TR1=1; if(kg_flag==1) {pwm[0]=bright_t; pwm[1]=0; pwm[2]=0; } } break; //TR0=1; case 0x08: {if(kg_flag==1) {pwm[0]=0; pwm[1]=bright_t; pwm[2]=0;} }break; case 0x0A: {if(kg_flag==1) {pwm[0]=0; pwm[1]=0; pwm[2]=bright_t;} }break; } } } EX0=1; } void main() { init(); while(1); } void timer1()interrupt 1 { TH1=(65536-200)/256; TL1=(65536-200)%256; if(scw==1) { scw=0; pwm_r=pwm[0]; pwm_g=pwm[1]; pwm_b=pwm[2]; } else { if(pwm_r>0){led_r=0;pwm_r--;} else{led_r=1;} if(pwm_g>0){led_g=0;pwm_g--;} else{led_g=1;} if(pwm_b>0){led_b=0;pwm_b--;} else{led_b=1;} scw++; } 請高手指點下兩個定時器怎么回事,SCW的值加大,按遙控調光就延時,怎么回事,T1不工作 }
紅外調光RGB
#include#define uint unsigned int #define uchar unsigned char unsigned char a[4]; //儲存用戶碼、用戶反碼與鍵數據碼、鍵數據反碼 unsigned int LowTime,HighTime; //儲存高、低電平的寬度 sbit led_r=P1^0; sbit led_g=P1^2; sbit led_b=P1^4; sbit IR=P3^2; sbit BEEP = P2^3; bit kg_flag; bit zb_flag; bit m_flag; bit s_flag; bit f_flag; uchar num,tl,tb,tm,tj;tt; uchar number; uchar scw; uchar pwm_r,pwm_g,pwm_b; uchar pwm[3]; uchar bright,bright_t; uchar x[30]={0}; uchar type[30]={0}; void dealy(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void init() { TMOD=0x01; TH0=0; //定時器清0 TL0=0; EA=1; ET0=1; // IT0=1; EX0=1; //PT0=1; //PX0=0; TR0=1; TH1=(65536-1000)/256; TL1=(65536-1000)%256; ET1=1; EA=1; //IT0=1; //EX0=1; PT1=1; //PX0=0; TR1=1; scw=0; tl=20;tb=100;tm=20;tj=100; kg_flag=0; zb_flag=0; m_flag=0;s_flag=0; f_flag=0; bright=255;bright_t=255; pwm[0]=0; pwm[1]=0; pwm[2]=0; } //void beep() //蜂鳴器響一聲函數 //{ // unsigned char i; //for (i=0;i<100;i++) // { // delay1ms(); //BEEP=!BEEP; //BEEP取反 //} // BEEP=1; //關閉蜂鳴器 // delay(250); //延時 //} bit DeCode(void) { unsigned char i,j; unsigned char temp; //儲存解碼出的數據 for(i=0;i<4;i++) //連續讀取4個用戶碼和鍵數據碼 { for(j=0;j<8;j++) //每個碼有8位數字 { temp=temp>>1; //temp中的各數據位右移一位,因為先讀出的是高位數據 TH0=0; //定時器清0 TL0=0; //定時器清0 TR0=1; //開啟定時器T0 while(IR==0) //如果是低電平就等待 ; //低電平計時 TR0=0; //關閉定時器T0 LowTime=TH0*256+TL0; //保存低電平寬度 TH0=0; //定時器清0 TL0=0; //定時器清0 TR0=1; //開啟定時器T0 while(IR==1) //如果是高電平就等待 ; TR0=0; //關閉定時器T0 HighTime=TH0*256+TL0; //保存高電平寬度 if((LowTime<370)||(LowTime>640)) return 0; //如果低電平長度不在合理范圍,則認為出錯,停止解碼 if((HighTime>420)&&(HighTime<620)) //如果高電平時間在560微秒左右,即計數560/1.085=516次 temp=temp&0x7f; //(520-100=420, 520+100=620),則該位是0 if((HighTime>1300)&&(HighTime<1800)) //如果高電平時間在1680微秒左右,即計數1680/1.085=1548次 temp=temp|0x80; //(1550-250=1300,1550+250=1800),則該位是1 } a[i]=temp; //將解碼出的字節值儲存在a[i] } if(a[2]=~a[3]) //驗證鍵數據碼和其反碼是否相等,一般情況下不必驗證用戶碼 return 1; //解碼正確,返回1 } void exter_int0() interrupt 0 using 0 { EX0=0; //關閉外中斷0,不再接收二次紅外信號的中斷,只解碼當前紅外信號 TH0=0; //定時器T0的高8位清0 TL0=0; //定時器T0的低8位清0 TR0=1; //開啟定時器T0 while(IR==0); //如果是低電平就等待,給引導碼低電平計時 TR0=0; //關閉定時器T0 LowTime=TH0*256+TL0; //保存低電平時間 TH0=0; //定時器T0的高8位清0 TL0=0; //定時器T0的低8位清0 TR0=1; //開啟定時器T0 while(IR==1); //如果是高電平就等待,給引導碼高電平計時 TR0=0; //關閉定時器T0 HighTime=TH0*256+TL0; //保存引導碼的高電平長度 if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700)) { //如果是引導碼,就開始解碼,否則放棄,引導碼的低電平計時 //次數=9000us/1.085=8294, 判斷區間:8300-500=7800,8300+500=8800. if(DeCode()==1);// 執行遙控解碼功能 {// beep(); //TR1=0; //TH1=(65536-1000)/256; //TL1=(65536-1000)%256; //TR1=1; switch(a[2]) { case 0x07: {kg_flag=1; f_flag=0; s_flag=0; zb_flag=0; number=0; m_flag=0; //bright_t=225; pwm[0]=bright_t; pwm[1]=bright_t; pwm[2]=bright_t; } break; case 0x06: { kg_flag=0; pwm[0]=0; pwm[1]=0; pwm[2]=0; } break; case 0x04: { if((kg_flag==1)&&(m_flag==0)&& (s_flag==0)&& (zb_flag==0)&&(f_flag==0)) { if(bright_t!=25) { bright_t=bright_t-10; } } } break; case 0x05: { if((kg_flag==1)&&(m_flag==0)&& (s_flag==0)&& (zb_flag==0)&&(f_flag==0)) { if(bright_t!=255) { bright_t=bright_t+10; } } } break; case 0x09: { if(kg_flag==1) {pwm[0]=bright_t; pwm[1]=0; pwm[2]=0; } } break; case 0x08: {if(kg_flag==1) {pwm[0]=0; pwm[1]=bright_t; pwm[2]=0;} }break; case 0x0A: {if(kg_flag==1) {pwm[0]=0; pwm[1]=0; pwm[2]=bright_t;} }break; } } } EX0=1; } void main() { init(); while(1); } void timer1()interrupt 3 using 1 { TH1=(65536-1000)/256; TL1=(65536-1000)%256; scw++; if(scw==255) { scw=0; pwm_r=pwm[0]; pwm_g=pwm[1]; pwm_b=pwm[2]; } else { if(pwm_r>0){led_r=0;pwm_r--;} else{led_r=1;} if(pwm_g>0){led_g=0;pwm_g--;} else{led_g=1;} if(pwm_b>0){led_b=0;pwm_b--;} else{led_b=1;} 這個調了下T1工作了但還是不能調光,調光部分怎么寫請高手指點
首先可以肯定,沒人看你的代碼
你的PWM調光原理是什么?你可以用一個給定數據調光,也就是程序自動慢慢調節,用于驗證你的調光程序與硬件是否OK
其次你可以通過調試或是串口方式讀出接收到的代碼是否正確,接收到的代碼是否能得到執行?
中斷查詢解碼————意思就是 邊解碼 邊PWM循環, 例如:以50us的時基礎作為定時中斷, 時間一到就去中斷里面解碼, 以累計的方式判斷什么引導碼 用戶碼 數據碼 反碼等, 中斷函數里面最多也就是++,判斷,循環存放之類的語句,占用不了多少時間,最多十幾uS就退出中斷了,這樣就不用一直在那里等電平的變化。退出后又接著繼續主函數中的PWM循環,十幾US的執行時間根本不影響PWM調光的視覺暫留效應,這樣就看不到閃。
給你個參考——利用定時器的固定時基來查詢紅外脈沖的寬度,從而進行解碼!
可以自己去分析,至于中間的高電平是多少時間,低電平是多少時間都不用去管,只需計算兩個下降沿間隔時間就可以判斷0和1,同時也可以判斷是否是引導碼,或是結束碼,或是連續碼
定時器查看時間設置為125us,執行定時器中斷程序一次
void Timer0 interrupt 1()
{
irTime++;
if(irTime==240) // ir解碼后碼值存放時間, 240*125us = 30ms
{
irTime--;
codeCnt=0x3f;
}
if(IR_IO) Irprot_LastState=1; // 記錄IO狀態
else if(Irprot_LastState) // 有下降沿
{
Irprot_LastState = 0; // 下降沿后IO狀態記錄為0
if(irTime<24) // 小于24*125us=3ms的間隔才進行處理
{
codeCnt++;
codeCnt &= 0x1f;
IR_data[codeCnt>>3] <<= 1;
if( irTime>15)
IR_data[codeCnt>>3]++; // 大于15*125us=1.875ms的間隔為數據1
}
irTime = 0; // 下降沿處理完成,將時間清0
}
}