include#define uint unsigned int #define uchar unsigned char unsigned char a[4]; //儲(chǔ)存用戶碼、用戶反碼與鍵數(shù)據(jù)碼、鍵數(shù)據(jù)反碼 unsigned int LowTime,HighTime; //儲(chǔ)存高、低電平的寬度 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中的各數(shù)據(jù)位右移一位,因?yàn)橄茸x出的是高位數(shù)據(jù) TH0=0; //定時(shí)器清0 TL0=0; //定時(shí)器清0 TR0=1; //開啟定時(shí)器T0 while(IR==0) //如果是低電平就等待 ; //低電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 LowTime=TH0*256+TL0; //保存低電平寬度 TH0=0; //定時(shí)器清0 TL0=0; //定時(shí)器清0 TR0=1; //開啟定時(shí)器T0 while(IR==1) //如果是高電平就等待 ; TR0=0; //關(guān)閉定時(shí)器T0 HighTime=TH0*256+TL0; //保存高電平寬度 if((LowTime<370)||(LowTime>640)) return 0; //如果低電平長度不在合理范圍,則認(rèn)為出錯(cuò),停止解碼 if((HighTime>420)&&(HighTime<620)) //如果高電平時(shí)間在560微秒左右,即計(jì)數(shù)560/1.085=516次 temp=temp&0x7f; //(520-100=420, 520+100=620),則該位是0 if((HighTime>1300)&&(HighTime<1800)) //如果高電平時(shí)間在1680微秒左右,即計(jì)數(shù)1680/1.085=1548次 temp=temp|0x80; //(1550-250=1300,1550+250=1800),則該位是1 } a[i]=temp; //將解碼出的字節(jié)值儲(chǔ)存在a[i] } if(a[2]=~a[3]) //驗(yàn)證鍵數(shù)據(jù)碼和其反碼是否相等,一般情況下不必驗(yàn)證用戶碼 return 1; //解碼正確,返回1 } void exter_int0() interrupt 0 { EX0=0; //關(guān)閉外中斷0,不再接收二次紅外信號(hào)的中斷,只解碼當(dāng)前紅外信號(hào) TH0=0; //定時(shí)器T0的高8位清0 TL0=0; //定時(shí)器T0的低8位清0 TR0=1; //開啟定時(shí)器T0 while(IR==0); //如果是低電平就等待,給引導(dǎo)碼低電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 LowTime=TH0*256+TL0; //保存低電平時(shí)間 TH0=0; //定時(shí)器T0的高8位清0 TL0=0; //定時(shí)器T0的低8位清0 TR0=1; //開啟定時(shí)器T0 while(IR==1); //如果是高電平就等待,給引導(dǎo)碼高電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 HighTime=TH0*256+TL0; //保存引導(dǎo)碼的高電平長度 if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700)) { //如果是引導(dǎo)碼,就開始解碼,否則放棄,引導(dǎo)碼的低電平計(jì)時(shí) //次數(shù)=9000us/1.085=8294, 判斷區(qū)間:8300-500=7800,8300+500=8800. if(DeCode()==1); // 執(zhí)行遙控解碼功能 {// 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++; } 請(qǐng)高手指點(diǎn)下兩個(gè)定時(shí)器怎么回事,SCW的值加大,按遙控調(diào)光就延時(shí),怎么回事,T1不工作 }
紅外調(diào)光RGB
#include#define uint unsigned int #define uchar unsigned char unsigned char a[4]; //儲(chǔ)存用戶碼、用戶反碼與鍵數(shù)據(jù)碼、鍵數(shù)據(jù)反碼 unsigned int LowTime,HighTime; //儲(chǔ)存高、低電平的寬度 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; //定時(shí)器清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() //蜂鳴器響一聲函數(shù) //{ // unsigned char i; //for (i=0;i<100;i++) // { // delay1ms(); //BEEP=!BEEP; //BEEP取反 //} // BEEP=1; //關(guān)閉蜂鳴器 // delay(250); //延時(shí) //} bit DeCode(void) { unsigned char i,j; unsigned char temp; //儲(chǔ)存解碼出的數(shù)據(jù) for(i=0;i<4;i++) //連續(xù)讀取4個(gè)用戶碼和鍵數(shù)據(jù)碼 { for(j=0;j<8;j++) //每個(gè)碼有8位數(shù)字 { temp=temp>>1; //temp中的各數(shù)據(jù)位右移一位,因?yàn)橄茸x出的是高位數(shù)據(jù) TH0=0; //定時(shí)器清0 TL0=0; //定時(shí)器清0 TR0=1; //開啟定時(shí)器T0 while(IR==0) //如果是低電平就等待 ; //低電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 LowTime=TH0*256+TL0; //保存低電平寬度 TH0=0; //定時(shí)器清0 TL0=0; //定時(shí)器清0 TR0=1; //開啟定時(shí)器T0 while(IR==1) //如果是高電平就等待 ; TR0=0; //關(guān)閉定時(shí)器T0 HighTime=TH0*256+TL0; //保存高電平寬度 if((LowTime<370)||(LowTime>640)) return 0; //如果低電平長度不在合理范圍,則認(rèn)為出錯(cuò),停止解碼 if((HighTime>420)&&(HighTime<620)) //如果高電平時(shí)間在560微秒左右,即計(jì)數(shù)560/1.085=516次 temp=temp&0x7f; //(520-100=420, 520+100=620),則該位是0 if((HighTime>1300)&&(HighTime<1800)) //如果高電平時(shí)間在1680微秒左右,即計(jì)數(shù)1680/1.085=1548次 temp=temp|0x80; //(1550-250=1300,1550+250=1800),則該位是1 } a[i]=temp; //將解碼出的字節(jié)值儲(chǔ)存在a[i] } if(a[2]=~a[3]) //驗(yàn)證鍵數(shù)據(jù)碼和其反碼是否相等,一般情況下不必驗(yàn)證用戶碼 return 1; //解碼正確,返回1 } void exter_int0() interrupt 0 using 0 { EX0=0; //關(guān)閉外中斷0,不再接收二次紅外信號(hào)的中斷,只解碼當(dāng)前紅外信號(hào) TH0=0; //定時(shí)器T0的高8位清0 TL0=0; //定時(shí)器T0的低8位清0 TR0=1; //開啟定時(shí)器T0 while(IR==0); //如果是低電平就等待,給引導(dǎo)碼低電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 LowTime=TH0*256+TL0; //保存低電平時(shí)間 TH0=0; //定時(shí)器T0的高8位清0 TL0=0; //定時(shí)器T0的低8位清0 TR0=1; //開啟定時(shí)器T0 while(IR==1); //如果是高電平就等待,給引導(dǎo)碼高電平計(jì)時(shí) TR0=0; //關(guān)閉定時(shí)器T0 HighTime=TH0*256+TL0; //保存引導(dǎo)碼的高電平長度 if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700)) { //如果是引導(dǎo)碼,就開始解碼,否則放棄,引導(dǎo)碼的低電平計(jì)時(shí) //次數(shù)=9000us/1.085=8294, 判斷區(qū)間:8300-500=7800,8300+500=8800. if(DeCode()==1);// 執(zhí)行遙控解碼功能 {// 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;} 這個(gè)調(diào)了下T1工作了但還是不能調(diào)光,調(diào)光部分怎么寫請(qǐng)高手指點(diǎn)
首先可以肯定,沒人看你的代碼
你的PWM調(diào)光原理是什么?你可以用一個(gè)給定數(shù)據(jù)調(diào)光,也就是程序自動(dòng)慢慢調(diào)節(jié),用于驗(yàn)證你的調(diào)光程序與硬件是否OK
其次你可以通過調(diào)試或是串口方式讀出接收到的代碼是否正確,接收到的代碼是否能得到執(zhí)行?
中斷查詢解碼————意思就是 邊解碼 邊PWM循環(huán), 例如:以50us的時(shí)基礎(chǔ)作為定時(shí)中斷, 時(shí)間一到就去中斷里面解碼, 以累計(jì)的方式判斷什么引導(dǎo)碼 用戶碼 數(shù)據(jù)碼 反碼等, 中斷函數(shù)里面最多也就是++,判斷,循環(huán)存放之類的語句,占用不了多少時(shí)間,最多十幾u(yù)S就退出中斷了,這樣就不用一直在那里等電平的變化。退出后又接著繼續(xù)主函數(shù)中的PWM循環(huán),十幾US的執(zhí)行時(shí)間根本不影響PWM調(diào)光的視覺暫留效應(yīng),這樣就看不到閃。
給你個(gè)參考——利用定時(shí)器的固定時(shí)基來查詢紅外脈沖的寬度,從而進(jìn)行解碼!
可以自己去分析,至于中間的高電平是多少時(shí)間,低電平是多少時(shí)間都不用去管,只需計(jì)算兩個(gè)下降沿間隔時(shí)間就可以判斷0和1,同時(shí)也可以判斷是否是引導(dǎo)碼,或是結(jié)束碼,或是連續(xù)碼
定時(shí)器查看時(shí)間設(shè)置為125us,執(zhí)行定時(shí)器中斷程序一次
void Timer0 interrupt 1()
{
irTime++;
if(irTime==240) // ir解碼后碼值存放時(shí)間, 240*125us = 30ms
{
irTime--;
codeCnt=0x3f;
}
if(IR_IO) Irprot_LastState=1; // 記錄IO狀態(tài)
else if(Irprot_LastState) // 有下降沿
{
Irprot_LastState = 0; // 下降沿后IO狀態(tài)記錄為0
if(irTime<24) // 小于24*125us=3ms的間隔才進(jìn)行處理
{
codeCnt++;
codeCnt &= 0x1f;
IR_data[codeCnt>>3] <<= 1;
if( irTime>15)
IR_data[codeCnt>>3]++; // 大于15*125us=1.875ms的間隔為數(shù)據(jù)1
}
irTime = 0; // 下降沿處理完成,將時(shí)間清0
}
}
好一個(gè)硬件沒問題。
通常出問題也只在一小部份,也不用把所有程序都貼出來。
現(xiàn)在你都沒搞清楚是收不到數(shù)還是收到的數(shù)據(jù)不正常?還是加載時(shí)不正常?
正常情況下。如你要控制50%的占空比,那你出問題你就要找收到的是不是50%占空比數(shù)據(jù)?
是加載過程中閃還是一直閃?
做產(chǎn)品是要考慮成本,但現(xiàn)在帶PWM的片子也1塊多,你要用幾毛的片子,那我也只能呵呵了?。。?
一個(gè)定時(shí)器 邊解碼 邊輸出PWM
如:設(shè)定一個(gè)基準(zhǔn)時(shí)間50us 中斷 處理解碼和PWM
調(diào)試時(shí) 先把PWM屏蔽 測(cè)試解碼是否正常 然后把解碼屏蔽 測(cè)試PWM是否正常 然后兩個(gè)都不屏蔽測(cè)試 是否正常
調(diào)程序 要有耐心 一步一步的測(cè)試 每個(gè)人寫程序的思路是不一樣的 只要你的思路正確了 怎么都能寫出功能完整的程序
類似這種的 最好是靠定時(shí)中斷去處理 外部觸發(fā)中斷 需要速度跑出中斷 不然很容易中斷嵌套