|
本帖最后由 das 于 2015-4-5 00:36 編輯
- //*************************************************************************************//
- //--P3.4口采樣過零信號(hào),每10ms采樣到一個(gè)過零高電平,用于PWM0的時(shí)鐘信號(hào)--//
- //--P1.2口采樣電位器的輸出調(diào)光電壓,并進(jìn)行8bit的A/D轉(zhuǎn)換--//
- /*P3.7口輸出PWM信號(hào),PWM信號(hào)的頻率和相位角應(yīng)該自動(dòng)能根據(jù)P1.6口的過零信號(hào)和P1.2口的模擬信號(hào),
- 進(jìn)行計(jì)算分析,輸出時(shí)實(shí)的控制信號(hào),以控制可控硅的導(dǎo)通時(shí)間,達(dá)到調(diào)光的目的; */
- /*P3.2口利用外部中斷功能,實(shí)現(xiàn)紅外線遙控器的解碼,以實(shí)現(xiàn)遙控功能. */
- //P1.6是AT24C01的數(shù)據(jù)端;P1.7是AT24C01的時(shí)鐘端,用于存儲(chǔ)紅外搖器的解碼值,達(dá)到記憶亮度的效果//
- //P1.0接LED指示燈//
- // 2013-9-13 /楊旭
- //*************************************************************************************//
- #include <stc12c2052ad.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit LED=P1^0;
- sbit IR_RE=P3^2;
- sbit SDA=P1^6; //AT24C01數(shù)據(jù)端
- sbit SCL=P1^7; //AT24C01時(shí)鐘端
- //--------------------------------紅外線解碼用變量
- static uchar date[]={0,0,0,0};
- static uchar qinlong;
- //--------------------------------AD轉(zhuǎn)換用變量
- static uchar AD_dat_over0,AD_dat_over1;
- static uchar j=0; //AD中斷計(jì)數(shù)器
- //--------------------------------------------------------------------------/
- void delayms(uint a)
- {
- uint b;
- for(b=0;b<a;b++);
- }
- //--------------------------------------------------------------------------//
- void delay882()
- {
- uchar i,j;
- i=35;
- do{j=68;
- do{j--;}
- while(j);
- i--;
- }while(i);
- }
- //-------------------------
- void delay1000()
- {
- uchar i,j;
- i=39;
- do{j=70;
- do{j--;}
- while(j);
- i--;
- }while(i);
- }
- //-------------------------
- void delay2400()
- {
- uchar i,j;
- i=93;
- do{j=70;
- do{j--;}
- while(j);
- i--;
- }while(i);
- }
- //--------------------------------------------------------------------------//
- /*名稱:初始化端口程序
- 功能:系統(tǒng)初始化,檢測芯片運(yùn)行
- */
- /*********************初始化LED程序******************************************/
- void int_LED(void) //LED閃爍3次表示初始化正常
- {
- uchar a;
- for(a=0;a<3;a++)
- {
- LED=0;
- delayms(1000);
- LED=1;
- }
- }
- //--------------------初始化端口程序-----------------------------------------/
- void int_cushi(void)
- {
- P1=1;
- P3=1;
- int_LED();
- }
- //--------------------------------------------------------------------------//
- /*名稱:EEROM通信程序
- 功能:完成摸擬I2C功能,完成AT24C01的讀和寫操作
- */
- //----------
- void delay()
- { ; ; }
- //----------
- void start()//啟始信號(hào)
- {
- SDA=1;
- delay();
- SCL=1;
- delay();
- SDA=0;
- delay();
- }
- //----------
- void stop()//終止信號(hào)
- {
- SDA=0;
- delay();
- SCL=1;
- delay();
- SDA=1;
- delay();
- }
- //----------
- void respons() //應(yīng)答信號(hào),等待或者發(fā)送一個(gè)應(yīng)答信號(hào)
- {
- uchar i;
- SCL=1;
- delay();
- while((SDA==1)&&(i<250))i++;
- SCL=0;
- delay();
- }
- //----------
- void I2C_init()//初始化
- {
- SDA=1;
- SCL=1;
- }
- //----------
- void write_byte(uchar date)//寫一字節(jié)
- {
- uchar i;
- SCL=0;
- for(i=0;i<8;i++)
- {
- date=date<<1;
- SDA=CY;
- SCL=1;
- delay();
- SCL=0;
- delay();
- }
- }
- //----------
- uchar read_byte() //讀數(shù)據(jù)(也就是接收從器件傳來的數(shù)據(jù))
- {
- uchar i,k;
- for(i=0;i<8;i++)
- {
- SCL=1;
- delay();
- k=(k<<1)|SDA;
- SCL=0;
- delay();
- }
- return k;
- }
- //----------
- void delay1(uchar x)
- {
- uchar a,b;
- for(a=x;a>0;a--)
- for(b=100;b>0;b--);
- }
- //----------
- void write_add(uchar address,uchar date) //寫數(shù)據(jù)_調(diào)用層
- {
- start();
- write_byte(0xa0); //寫器件地址
- respons(); //應(yīng)答
- write_byte(address); //寫器件內(nèi)部存儲(chǔ)地址
- respons();
- write_byte(date); //寫入數(shù)據(jù)
- respons();
- stop(); //停止
- }
- //----------
- read_add(uchar address) //讀數(shù)據(jù)_調(diào)用層
- {
- uchar date;
- start();
- write_byte(0xa0);
- respons();
- write_byte(address);
- respons();
- //------------------
- start();
- write_byte(0xa1);
- respons();
- date=read_byte();
- stop();
- return date;
- }
- //----------
- uchar I2C_data() //主函數(shù)初始化后讀EEROM中的亮度值
- {
- uchar a;
- I2C_init();
- delay1(250);
- a=read_add(23);
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- return a;
- }
- //--------------------------------------------------------------------------/
- /*名稱:系統(tǒng)程序設(shè)置
- 功能:PWM0設(shè)置,外部中斷0設(shè)置,AD中斷設(shè)置
- */
- void lcall_sezhi()
- {
- //-----------------------------------PWM設(shè)置
- CMOD=0x86; //------PCA模塊PWM設(shè)置
- CCON=0x00; //CMOD=0X84為T0為信號(hào)源,這時(shí)將T0設(shè)置段落打開//0X80時(shí)則用12分頻時(shí)鐘信號(hào)
- CL=0x00; //CMOD=0X86使用外部脈沖信號(hào),從P3.4腳加入信號(hào)
- CH=0x00;
- CCAPM1=0x42; //0X42=01000010B 允許比較器功能位P1.4腳輸出PWM脈寬信號(hào)
- PCA_PWM1=0x00;//EPC1L和EPC1H在PWM模式下的值是0X00.
- CR=1; //啟動(dòng)計(jì)數(shù)器
- //====================================外部中斷0設(shè)置
- EX0=1; //允許外部中斷0
- IT0=1; //下降沿觸發(fā)
- //====================================AD
- EADC_SPI=1; //允許ADC中斷標(biāo)志位
- AUXR|=0x10; //允許ADC中斷
- P1M0=0x20;
- P1M1=0x00; //設(shè)置P1.2為AD輸入
- ADC_CONTR=0xe2;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- //-----------------------------------------------------------------------//
- EA=1; //開總中斷
- }
- //===============================lcall_AD====================================//
- void lcall_AD(void)
- {
- ADC_CONTR=0xea; //啟動(dòng)AD轉(zhuǎn)換
- }
- //---------------------------------------------------------------------------//
- /*名稱:紅外線解碼數(shù)據(jù)計(jì)算處理
- 功能:開/并功能,鍵值檔位計(jì)算,EEROM存儲(chǔ)功能,給CCAP0H和CCAP0L送值
- */
- void IR_jiema_data(void)
- {
- if(qinlong==0x00) //0檔位
- {//向CCAP0H,CCAP0L輸入比較器的初值,以和CL CH計(jì)數(shù)器的值進(jìn)行比較實(shí)現(xiàn)PWM調(diào)寬
- I2C_init();
- delay1(250);
- write_add(23,256-250);//寫入EEROM地址23H,存儲(chǔ)數(shù)據(jù)256-250
- CCAP0H=(256-250);
- CCAP0L=(256-250); //給PWM0傳送脈寬值
- qinlong=0xff;
- }
- else if(qinlong==0x01) //1檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-240);
- CCAP0H=(256-240);
- CCAP0L=(256-240);
- qinlong=0xff;
- }
- else if(qinlong==0x02) //2檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-220);
- CCAP0H=(256-220);
- CCAP0L=(256-220);
- qinlong=0xff;
- }
- else if(qinlong==0x03) //3檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-200);
- CCAP0H=(256-200);
- CCAP0L=(256-200);
- qinlong=0xff;
- }
- else if(qinlong==0x04) //4檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-180);
- CCAP0H=(256-180);
- CCAP0L=(256-180);
- qinlong=0xff;
- }
- else if(qinlong==0x05) //5檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-160);
- CCAP0H=(256-160);
- CCAP0L=(256-160);
- qinlong=0xff;
- }
- else if(qinlong==0x06) //6檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-150);
- CCAP0H=(256-150);
- CCAP0L=(256-150);
- qinlong=0xff;
- }
- else if(qinlong==0x07) //7檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-100);
- CCAP0H=(256-100);
- CCAP0L=(256-100);
- qinlong=0xff;
- }
- else if(qinlong==0x08) //8檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-50);
- CCAP0H=(256-50);
- CCAP0L=(256-50);
- qinlong=0xff;
- }
- else if(qinlong==0x09) //9檔位
- {
- I2C_init();
- delay1(250);
- write_add(23,256-10);
- CCAP0H=(256-10);
- CCAP0L=(256-10);
- qinlong=0xff;
- }
- }
- //---------------------------------------------------------------------------//
- /*名稱:AD數(shù)碼轉(zhuǎn)換
- 功能:將電位器信號(hào)轉(zhuǎn)換成8位數(shù)據(jù),并用于EEROM存儲(chǔ)和送入CCAP0H和CCAP0L中,從而
- 調(diào)節(jié)PWM0的輸出
- */
- //---------------------------------------------------------------------------//
- void AD_jiema_data(void)
- { //AD轉(zhuǎn)換后的數(shù)據(jù)處理
- if((AD_dat_over0<(AD_dat_over1+5))&&(AD_dat_over0>(AD_dat_over1-5)))
- { //如果在范圍內(nèi)(+5/-5)說明沒調(diào)電位器,應(yīng)使用存儲(chǔ)值
- //給出+-5的范圍是防止輸入電壓稍有變動(dòng),引起的判斷錯(cuò)誤
- I2C_init();
- delay1(250);
- CCAP0H=read_add(23);
- }
- else
- {
- CCAP0H=(256-AD_dat_over0); //有調(diào)動(dòng)電位器,應(yīng)使用電位器AD值
- I2C_init();
- delay1(250);
- write_add(23,AD_dat_over0); //刷新EEROM中的值
- }
- }
- //**********************************************************************************//
- /*名稱:主函數(shù)
- 功能:完成系統(tǒng)的初始化和紅外解碼數(shù)據(jù)處理;AD轉(zhuǎn)換數(shù)據(jù)處理;最終達(dá)到存儲(chǔ)數(shù)據(jù)和調(diào)節(jié)PWM0.
- */
- //******************************主函數(shù)**********************************************//
- void main()
- {
- uchar a;
- lcall_sezhi(); //調(diào)用系統(tǒng)設(shè)置
- int_cushi(); //初始化系統(tǒng)檢查
- lcall_AD(); //啟動(dòng)AD
- a=I2C_data(); //讀I2C的數(shù)據(jù)
- while(1)
- {
- CCAP0H=(256-a);
- IR_jiema_data(); //紅外解碼數(shù)據(jù)處理
- AD_jiema_data(); //AD數(shù)據(jù)處理
- }
- }
- //***************************************************************************//
- /*名稱:紅外解碼_外部中斷0
- 功能:完成紅外線的數(shù)據(jù)解碼功能,解碼后的數(shù)據(jù)處理由主程序中的子程序處理.
- */
- //---------------------------------------------------------------------------//
- void int0_hongwai() interrupt 0 using 0
- {
- uchar i,j,k,n;
- EX0=0;
- for(n=0;n<10;n++)
- {
- delay882();
- if(IR_RE==1)break;
- }
- while(IR_RE==0){};
- //------------------------
- //當(dāng)遙控器持續(xù)按下則接收到一個(gè)9ms的低電平引導(dǎo)脈沖
- //以及一個(gè)2.2ms的高電平脈沖,和一個(gè)0.7ms的低電平脈沖,和一個(gè)96ms的高電平脈沖
- //以下是連續(xù)碼的檢測判斷程序和4.5ms高電平判斷
- //------------------------
- for(j=0;j<2;j++)
- {
- delay2400();
- if(IR_RE==0)break;
- }
- //-------------------------讀取數(shù)字信號(hào)----------
- for(i=0;i<4;i++)
- {
- for(k=0;k<8;k++)
- {
- while(IR_RE==0){};
- delay882();
- if(IR_RE==0)
- {
- date[i]>>=1;
- date[i]=date[i]|0x00;
- }
- else if(IR_RE==1)
- {
- delay1000();
- date[i]>>=1;
- date[i]=date[i]|0x80;//0x80=10000000b
- }
- }
- }
- //-----------------------------------------------
- if(date[0]=~date[1]) //用戶碼和數(shù)據(jù)碼判斷
- {
- if(date[2]=~date[3])
- qinlong=date[2];
- }
- EX0=1;
- }
- //**********************************************************//
- /*名稱:AD轉(zhuǎn)換_AD中斷程序
- 功能:完成AD轉(zhuǎn)換數(shù)據(jù)傳輸,并同時(shí)清零AD中斷標(biāo)志位
- */
- //==========================================================//
- void AD_DAT12() interrupt 5 using 1
- {
- EADC_SPI=0; //允許ADC中斷標(biāo)志位
- j++;
- if(j==1)AD_dat_over0=ADC_DATA; //讀數(shù)據(jù)
- else if(j==2)
- {
- AD_dat_over1=ADC_DATA; //
- j=0; //計(jì)數(shù)器歸零
- }
- ADC_CONTR=0xea; //AD中斷標(biāo)志清零
- EADC_SPI=1;
- }
- //-----------------------END File---------------------------//
復(fù)制代碼
|
|