欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
基于51單片機聲音傳感器控制燈漸亮源程序 數值如何保持?
[打印本頁]
作者:
蘑菇超酷
時間:
2021-12-22 16:55
標題:
基于51單片機聲音傳感器控制燈漸亮源程序 數值如何保持?
想要通過光敏傳感器和聲音傳感器控制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周期的當前計數周期內燈滅
}
}
復制代碼
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1