|
本帖最后由 wulin 于 2019-11-1 20:56 編輯
原來的程序有缺陷,這是優(yōu)化過的程序。如果再把按鍵程優(yōu)化為短按加/減,長按連加/減更好。- //頭函數(shù)
- #include <reg52.h>
- //宏定義
- #define uint unsigned int
- #define uchar unsigned char
- //uchar pdata tt[51]; //定義空數(shù)組用于AD0832取平均值
- uchar data tt[51];
- uchar scale,rsd_sec; //定義占空比比例,熱釋電計(jì)時(shí)秒變量
- uchar sec;
- bit flag_auto=0,flag_rsd=0;//位定義自動切換,熱釋電動作標(biāo)志
- //uint lum; //ad0832讀出值
- uchar m;
- uchar n;
- //管腳聲明
- sbit LED = P2^5; //燈光控制輸出
- sbit rsd = P1^5; //熱釋電
- sbit qiehuan=P3^7; //手動/自動切換
- sbit add=P3^6; //增加
- sbit dec=P3^5; //減小
- sbit CS=P1^3; //CS定義腳,連接ADC0832CS腳
- sbit SCL=P1^0; //SCL定義腳,連接ADC0832SCL腳
- sbit DO=P1^1; //DO定義腳,連接ADC0832DO腳
- /*****************延時(shí)函數(shù):大約1ms************************/
- /*
- void delay(uchar i)
- {
- uchar j,k;
- for(j=i;j>0;j--)
- for(k=125;k>0;k--);
- }*/
- /***********讀數(shù)模轉(zhuǎn)換數(shù)據(jù)********************************************************/
- //請先了解ADC0832模數(shù)轉(zhuǎn)換的串行協(xié)議,再來讀本函數(shù),主要是對應(yīng)時(shí)序圖來理解,
- //本函數(shù)是模擬0832的串行協(xié)議進(jìn)行的
- uchar ad0832read(bit SGL,bit ODD)
- {
- uchar i=0,value=0,value1=0;
- SCL=0;
- DO=1;
- CS=0; //開始
- SCL=1; //第一個(gè)上升沿
- SCL=0;
- DO=SGL;
- SCL=1; //第二個(gè)上升沿
- SCL=0;
- DO=ODD;
- SCL=1; //第三個(gè)上升沿
- SCL=0; //第三個(gè)下降沿
- DO=1;
- for(i=0;i<8;i++)
- {
- SCL=1;
- SCL=0; //開始從第四個(gè)下降沿接收數(shù)據(jù)
- value<<=1;
- if(DO)
- value++;
- }
- for(i=0;i<8;i++)
- { //接收校驗(yàn)數(shù)據(jù)
- value1>>=1;
- if(DO)
- value1+=0x80;
- SCL=1;
- SCL=0;
- }
- CS=1;
- SCL=1;
- if(value==value1) //與校驗(yàn)數(shù)據(jù)比較,正確就返回?cái)?shù)據(jù),否則返回0
- return value;
- return 0;
- }
- /*****************按鍵函數(shù)*****************/
- void work()
- {
- static bit key_sign1=0,key_sign2=0,key_sign3=0; //按鍵自鎖標(biāo)志
- static uchar count1=0,count2=0,count3=0; //計(jì)數(shù)變量
- uint lum_mean,lum_all;
- uchar b,c;
- if(qiehuan==0) //自動切換按鍵按下
- {
- if(++count1==100&&key_sign1==0) //再次判斷按鍵按下
- {
- key_sign1=1;
- flag_auto=~flag_auto; //自動模式標(biāo)志位取反
- if(flag_auto==1) //當(dāng)切換到手動模式時(shí) 首先將LED發(fā)光比例設(shè)置在50%
- scale=20;
- }
- }
- else //按鍵釋放
- {
- key_sign1=0;
- count1=0;
- }
- if(flag_auto==1)
- {
- if(add==0) //加鍵按下
- {
- if(++count2==100&&key_sign2==0)
- {
- key_sign2=1;
- if(scale<41)//燈光比例++
- scale++;
- }
- }
- else //按鍵釋放
- {
- key_sign2=0;
- count2=0;
- }
- if(dec==0) //減鍵按下時(shí)
- {
- if(++count3==100&&key_sign3==0)
- {
- key_sign3=1;
- if(scale>1)//燈光比例--
- scale--;
- }
- }
- else //按鍵釋放
- {
- key_sign3=0;
- count3=0;
- }
- }
- else
- {
- if(flag_rsd==1) //有人在范圍內(nèi)時(shí)
- {
- for(b=0;b<49;b++) //將空數(shù)組tt[]內(nèi)數(shù)值整體左移一位
- {
- tt[b]=tt[b+1]; //將后一數(shù)值放到前一位置
- }
- tt[49] = ad0832read(1,0);//將讀出的ad數(shù)值放入tt[49]
- for(c=0;c<50;c++) //將tt[]內(nèi)數(shù)值相加
- {
- lum_all=lum_all+tt[c];
- }
- lum_mean=lum_all/50; //將總數(shù)/50取出平均值
- lum_all=0; //將總數(shù)清零
- if(lum_mean<=30) scale=1;//判斷取出平均值大小 小于30 發(fā)光強(qiáng)度0%
- else if(lum_mean>=150) scale=41;//大于150 發(fā)光強(qiáng)度100%
- else scale=((lum_mean-30)/3)+1;//其他值時(shí)將其計(jì)算得到發(fā)光強(qiáng)度 (計(jì)算目的是為了得到一個(gè)1-41之間的數(shù)值 控制燈光變化)
- }
- else
- {
- scale=1; //沒有人在范圍內(nèi)時(shí) 將燈光亮度調(diào)至0%
- }
- }
- }
- /*********定時(shí)器初始化函數(shù)**********/
- void init()
- {
- TMOD=0x12; //T1方式1,T0方式2
- TH1=0x3c;
- TL1=0xb0; //T1賦初值50ms
- TH0=0xce; //8位自動重載
- TL0=0xce; //T0賦初值50us
- ET0=1;
- ET1=1; //打開中斷允許開關(guān)
- EA=1; //中斷總開關(guān)
- TR0=1;
- TR1=1; //定時(shí)器定時(shí)開關(guān)
- }
- /****************主函數(shù)**********************/
- void main()
- {
- init(); //調(diào)用初始化函數(shù)
- while(1) //循環(huán)
- {
- work(); //調(diào)用函數(shù)
- }
- }
- /******************定時(shí)器T0服務(wù)函數(shù):脈沖發(fā)生函數(shù)*******************/
- void time0() interrupt 1
- {
- // TH0=0xff;
- // TL0=0xe7; //重新賦初值
- n++; //每50us n++
- if(n<scale) //n<設(shè)置比例時(shí),打開燈
- {
- LED=0;
- }
- else if(n>=scale)//n大于等于設(shè)置比例時(shí) 關(guān)閉燈
- {
- LED=1;
- }
- if(n>=40) //n==40 :50us*40=2ms 500HZ
- {
- n=0; //n=0
- }
- }
- /********************定時(shí)器T0服務(wù)函數(shù):計(jì)時(shí)和閃爍控制********************/
- void time1() interrupt 3
- {
- TH1=0x3c;
- TL1=0xb0; //重新賦初值
- if(rsd==1)
- {
- flag_rsd=1;
- rsd_sec=0;
- m=0;
- }
- else
- {
- m++; //50ms m++
- if(m==20) //到達(dá)1s時(shí)
- {
- m=0; //m=0
- rsd_sec++; //熱釋電計(jì)時(shí)秒++
- if(rsd_sec>=20) //熱釋電計(jì)時(shí)秒小于等于20 并且 熱釋電有信號時(shí)
- {
- flag_rsd=0; //標(biāo)志位置0 停止ad0832轉(zhuǎn)換 關(guān)閉燈光
- rsd_sec=0; //熱釋電計(jì)時(shí)秒清零
- }
- }
- }
- }
復(fù)制代碼
|
|