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