想要通过光敏传感器和声音传感器控制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周期的当前计数周期内灯灭
- }
- }
复制代码
|