|
想要通過(guò)光敏傳感器和聲音傳感器控制led漸亮,如果光小于某個(gè)值并且檢測(cè)到聲音的話(huà),讓led像呼吸燈一樣漸漸亮起來(lái)
但是我的代碼只能在串口接收到數(shù)值,led不能漸漸亮起來(lái),并且漸亮以后,怎么能在下一次獲得傳感器數(shù)值之前保持住呢?
單片機(jī)源程序如下:
- #include "stc8a.h" //頭文件
- #include "stdio.h"
- #include "intrins.h"
- typedef unsigned char u8; //別名
- u8 Tcount, dutyfactor=0, direct; //一個(gè)PWM周期內(nèi)的:周期計(jì)數(shù),占空比,方向
- sbit LED = P2^0; //位定義,led燈引腳
- unsigned int dat;
- char y=0;
- float ftemp1,ftemp2;
- float miniftemp=2.0;
- float ratio=0.1;
- float d_value;
- float buf1=0.0,buf2=0.0;
- char str[10];
- int i,t;
- void InterruptInit(); //中斷初始化配置的函數(shù)聲明
- void Time0(); //定時(shí)器0中斷的函數(shù)聲明
- void display( );
- void breatheLED(); //呼吸燈主程序的函數(shù)聲明
- int dec,inc;
- void delay(int b)
- {
- while(b--);
- }
- void UartInit(void) //9600bps@11.0592MHz
- {
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x40; //定時(shí)器1時(shí)鐘為Fosc,即1T
- AUXR &= 0xFE; //串口1選擇定時(shí)器1為波特率發(fā)生器
- TMOD &= 0x0F; //設(shè)定定時(shí)器1為16位自動(dòng)重裝方式
- TL1 = 0xE0; //設(shè)定定時(shí)初值
- TH1 = 0xFE; //設(shè)定定時(shí)初值
- ET1 = 0; //禁止定時(shí)器1中斷
- TR1 = 1; //啟動(dòng)定時(shí)器1
- }
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- //主函數(shù)
- void main() {
- //InterruptInit(); //初始化中斷配置
- UartInit();
- //循環(huán)實(shí)現(xiàn)呼吸燈功能
- //PWM周期:20ms;占空比:0~100;占空比每一份:200us;一次呼吸燈效果(暗->亮->暗):4s
- while(1) {
- P1M0 = 0x00; //設(shè)置P1.0為ADC口
- P1M1 = 0x01;
- ADCCFG = 0x2f; //設(shè)置ADC時(shí)鐘為系統(tǒng)時(shí)鐘/2/16/16
- ADC_CONTR = 0x80; //使能ADC模塊 1000 0000
- ADC_CONTR |= 0x40; //啟動(dòng)AD轉(zhuǎn)換 P1.0 1000 0000 || 0100 0000=1100 0000
- _nop_();
- _nop_();
- while (!(ADC_CONTR & 0x20)); //查詢(xún)ADC完成標(biāo)志
- ADC_CONTR &= ~0x20; //清完成標(biāo)志
- //ADC_RES(高4位) ADC_RESL(低8位); //讀取ADC結(jié)果
- dat=ADC_RES*256+ADC_RESL;
- buf1=ftemp1;//保存上一次的值
- ftemp1=dat;
- ftemp1=ftemp1*3.3/4096;//此時(shí)環(huán)境的暗亮程度
- // printf("The intensity is ");
- sprintf(str,"%.2f\r\n\0",ftemp1);
- i=0;
- while(str[i]!=0)
- {
- SBUF=str[i];
- while(!TI);
- TI=0;
- i++;
- }
- Delay1000ms();
-
- ADC_CONTR = 0x81; //使能ADC模塊 1000 0000
- ADC_CONTR |= 0x40; //啟動(dòng)AD轉(zhuǎn)換 P1.0 1000 0000 || 0100 0000=1100 0000
- _nop_();
- _nop_();
- while (!(ADC_CONTR & 0x20)); //查詢(xún)ADC完成標(biāo)志
- ADC_CONTR &= ~0x20; //清完成標(biāo)志
- //ADC_RES(高4位) ADC_RESL(低8位); //讀取ADC結(jié)果
- dat=ADC_RES*256+ADC_RESL;
- buf2=ftemp2;//保存上一次的值
- ftemp2=dat;
- ftemp2=ftemp2*3.3/4096;//此時(shí)環(huán)境的暗亮程度
- // printf("The noise is ");
- sprintf(str,"%.2f\r\n\0",ftemp2);
- i=0;
- while(str[i]!=0)
- {
- SBUF=str[i];
- while(!TI);
- TI=0;
- i++;
- }
- Delay1000ms();
-
-
- if(ftemp1 < miniftemp && ftemp2 > 0.0)
- {
- breatheLED();
- } //呼吸燈效果實(shí)現(xiàn)
- else LED=1;
- }
- }
- //中斷初始化配置
- void InterruptInit() {
- TMOD &= 0xf0; //定時(shí)器0設(shè)置清除
- TMOD |= 0x02; //定時(shí)器0,8位自動(dòng)重裝載
-
- //初值
- TH0 = 0x9C; //100us定時(shí),2^8-11.0592M / 12 * 200us
- TL0 = 0x9C; //自動(dòng)重裝載,低八位等于高八位
-
- ET0 = 1; //打開(kāi)定時(shí)器0中斷允許
- EA = 1; //打開(kāi)總中斷
-
- TR0 = 1; //啟動(dòng)定時(shí)器0
- }
- //定時(shí)器0中斷
- void Time0() interrupt 1 {
- //200us初值重裝
- TH0 = 0x9C;
- TL0 = 0x9C;
-
- Tcount++; //一個(gè)PWM周期內(nèi),計(jì)數(shù)
- }
- //呼吸燈主程序
- void breatheLED( ) {
- if(Tcount >= 100) { //一個(gè)PWM周期(4000次*100us)
- Tcount = 0; //下一個(gè)PWM周期內(nèi),重新計(jì)數(shù)
-
-
- //根據(jù)占空比值判斷方向是否需要改變
- if(ftemp2 > buf2) { //占空比減少到0
- direct = 1; //正方向,占空比開(kāi)始增加
- } else if(ftemp2 < buf2) { //占空比增加到100
- direct = 0; //負(fù)方向,占空比開(kāi)始減少
- }
-
- //根據(jù)方向判斷占空比增加或減少
- if(direct == 1) { //正方向,占空比增
- d_value=(ftemp2-buf2)/ratio;
- inc=floor(d_value);
- dutyfactor=dutyfactor+inc; //下一個(gè)PWM周期,占空比增加1
- // dutyfactor++;
- } else if(direct == 0) { //負(fù)方向,占空比減少
- d_value=(buf2-ftemp2)/ratio;
- dec=floor(d_value);
- dutyfactor=dutyfactor-dec; //下一個(gè)PWM周期,占空比減少1
- dutyfactor--;
- }
- }
-
- //占空比:通電時(shí)間相對(duì)于總時(shí)間所占的比例(此程序中:低電平時(shí)間相對(duì)于PWM周期所占的比例)
- //一個(gè)PWM周期計(jì)數(shù)100次,占空比相當(dāng)于低電平的計(jì)數(shù)周期次數(shù)。即:0~占空比:低電平,燈亮;占空比~100:高電平,燈滅
- //在一個(gè)PWM周期內(nèi),根據(jù)周期計(jì)數(shù)是否小于占空比,判斷LED燈的亮滅
- if(Tcount < dutyfactor) { //周期計(jì)數(shù)值<占空比
- LED = 0; //當(dāng)前PWM周期的當(dāng)前計(jì)數(shù)周期內(nèi)燈亮
- } else {
- LED = 1; //當(dāng)前PWM周期的當(dāng)前計(jì)數(shù)周期內(nèi)燈滅
- }
- }
復(fù)制代碼
|
|