#include "all.h"
// STC15W404AS
#define uchar unsigned char
#define uint unsigned int
uchar ADC_Val[11] ;
uchar VAL,Bandgap,VAL_Coul;
uchar LumFlag = 0; // 亮度
uchar Long8hFlag = 0;
uchar OutputFlag = 0;
uchar NormaFlag = 1;
uchar RunMode = 0;
uint Num = 0;
uchar Time6mscnt = 0;
uint Timecnt = 0;
uchar Uart1_InDat = 0x00;
unsigned char SBUFOver_Flag = 0;
unsigned char ucKeySec=0; //被触发的按键编号
unsigned char uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned int uiKeyTimeCnt2=0; //按键去抖动延时计数器
unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
unsigned char ucKeyFlag=0; //按键触发后自锁的变量标志
sbit PIRIN= P3^7; //主照明灯
sbit CTR_JDQ = P1^2; //电量显示按键
sbit L1IN = P1^3; //主照明按键
sbit TxetBin = P1^4; //主照明按键
void Delay5ms(void);
void IO_Init(void);
void ADC_Init(void);
void T0_Init(void);
uchar ADC_Value(void);
void SendData(unsigned char dat);
void Uart1_Init(void);
void ADC_Pro(char CHKIO); // AD检测处理
void Key_Service(); //按键服务的应用程序
void Key_Scan(); //按键扫描函数 放在定时中断里
void main(void)
{
IO_Init();
T0_Init();
CTR_JDQ = 1;
Uart1_Init();
ADC_Init();
while(NormaFlag);
while(1)
{
Key_Service();
if(OutputFlag)
{
CTR_JDQ = 1;
}
else
{
CTR_JDQ = 0;
}
}
}
void ADC_Pro(char CHKIO)
{
uchar i;
if(CHKIO)
{
for(i = 0; i<15 ; i++ )
{
ADC_Ch01();
VAL = ADC_Value(); // 再次储存
ADC_Val[i] = VAL;
// SendData(VAL);
Num += ADC_Val[i]; //求和
}
}
else
{
for(i = 0; i<15 ; i++ )
{
ADC_Ch00();
VAL = ADC_Value(); // 再次储存
ADC_Val[i] = VAL;
// SendData(VAL);
Num += ADC_Val[i]; //求和
}
}
Bandgap = Num/15;
// SendData(Bandgap);
Num = 0;
}
void Key_Scan()//按键扫描函数 放在定时中断里
{
/* 注释二:
* 独立按键扫描的详细过程:
* 第一步:平时没有按键被触发时,按键的自锁标志,去抖动延时计数器一直被清零。
* 第二步:一旦有按键被按下,去抖动延时计数器开始在定时中断函数里累加,在还没累加
到
* 阀值 const_key_time1 时,如果在这期间由于受外界干扰或者按键抖动,而使
* IO 口突然瞬间触发成高电平,这个时候马上把延时计数器 uiKeyTimeCnt1
* 清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。这是我实战中摸索
出来的。
* 以后凡是用到开关感应器的时候,都可以用类似这样的方法去干扰。
* 第三步:如果按键按下的时间超过了阀值 const_key_time1,则触发按键,把编号 ucKeySec
赋值。
* 同时,马上把自锁标志 ucKeyLock1 置位,防止按住按键不松手后一直触发。
* 第四步:等按键松开后,自锁标志 ucKeyLock1 及时清零,为下一次自锁做准备。
* 第五步:以上整个过程,就是识别按键 IO 口下降沿触发的过程。
*/
if(PIRIN == 0 )//IO 是低电平,说明信号没有,这时要及时清零一些标志位
{
ucKeyLock1 = 0; //信号自锁标志清零
uiKeyTimeCnt1 = 0;//信号稳定计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
else if(ucKeyLock1 == 0)//有信号,且是第一次被信号
{
uiKeyTimeCnt1 ++; //累加定时中断次数
if(uiKeyTimeCnt1 > const_key_time1) //是有效信号,稳定时间大于1500ms
{
uiKeyTimeCnt1 = 0;
ucKeyLock1 = 1; //自锁按键置位,避免一直触发
ucKeySec = 2; //触发 2 号键
}
}
if(L1IN == 0)
{
ucKeyLock2 = 0; //信号自锁标志清零
uiKeyTimeCnt2 = 0;//信号稳定计数器清零,此行非常巧妙,是我实战中摸索出来的。
if(ucKeyFlag == 1)
{
ucKeySec = 1; //触发 2 号键
ucKeyFlag = 0;
}
}
else if(ucKeyLock2 == 0)
{
uiKeyTimeCnt2++; //累加定时中断次数
if(uiKeyTimeCnt2 > 4) //是有效信号,稳定时间大于20ms
{
uiKeyTimeCnt2 = 0;
ucKeyLock2 = 1; //自锁按键置位,避免一直触发
ucKeyFlag = 1;
//ucKeySec = 1; //触发 2 号键
}
}
}
void Key_Service() //第三区 按键服务的应用程序
{
switch(ucKeySec) //按键服务状态切换
{
case 1:
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
Long8hFlag = 1;
Time6mscnt = 0;
Timecnt = 0;
TxetBin = 1;
break;
case 2:
ADC_Pro(LUX_CHK);
if(Bandgap<=0xd1) //2.5V=193=c1 2.7=209=d1
{
LumFlag = 0; //黑夜
}
else if(Bandgap>0xd1)
{
LumFlag = 1; //白天
OutputFlag = 0;
Long8hFlag = 0;
}
ADC_Pro(TIME_CHK);
if((Bandgap>=0x70)) // 1.8 text
{
RunMode = 1;
OutputFlag = 1;
}
else if((Bandgap<0x70)&&(Bandgap>=0x40)&&(LumFlag == 0)) // 1.4 5
{
RunMode = 2;
OutputFlag = 1;
}
else if((Bandgap<0x40)&&(Bandgap>=0x0f)&&(LumFlag == 0)) // 0.7 10
{
RunMode = 3;
OutputFlag = 1;
}
else if((Bandgap<0x0f)&&(LumFlag == 0)) // 000 20
{
RunMode = 4;
OutputFlag = 1;
}
Time6mscnt = 0;
Timecnt = 0;
ucKeySec = 0;
break;
default:
break;
}
}
void IO_Init(void)
{
// IO_Mode(PORT1,BIT0,Input_High); // P1.0 TIME= 高祖输入1
// IO_Mode(PORT1,BIT1,Input_High); // P1.1 LUX= 高祖输入1
// IO_Mode(PORT1,BIT2,Output_High); // P1.2 JDQ= 强输出0
// IO_Mode(PORT1,BIT3,Output_High); // P1.3 L1 = 高祖输入1
// P1.4 ceshi= 强输出0
P1M1 = 0x0b; // 0000 1011
P1M0 = 0x1f; // 0001 1111
P1 = 0x0b; // 0000 1011
// IO_Mode(PORT3,BIT7,Input_Low); //P3.7 = 低输入0//
P3M1 = 0x00; // 0000 0000
P3M0 = 0x00; // 0000 0000
P3 = 0x8f;
}
uchar ADC_Value()
{
ADC_CONTR |= ADC_START ;
Delay5ms();
while(!(ADC_CONTR&ADC_FLAG));
ADC_CONTR&=~ADC_FLAG;
return ADC_RES;
}
void Uart1_Init(void)
{
// AUXR = 0x00;
SCON = 0x00;
PCON = 0x00;
SCON = 0x50 ; //8位可变波特率 ,校验位为0
T2L = (65536-(FOSC/4/BAUD));
T2H = (65536-(FOSC/4/BAUD))>>8;
AUXR |= 0x01; // T2为uart1 波特率发生器
AUXR |= 0x14; //T2为1T模式,启动T2
ES = 1;
EA = 1;
}
void SendData(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
void Delay5ms(void) // 5ms
{
unsigned char i, j;
i = 60;
j = 200;
do
{
while (--j);
} while (--i);
}
/*void ADC_isr(void) interrupt 5 using 1 // ADC 中断
{
ADC_CONTR &=!ADC_FLAG;
VAL = ADC_RES ;
// P14 =!P14;
}
*/
void T0_IRQ(void) interrupt 1 using 1 // T0 中断 6mS
{
if(NormaFlag == 1)
{
Time6mscnt++;
if(Time6mscnt == 250) //1.5s
{
Time6mscnt = 0;
Timecnt++;
if(Timecnt == 15 ) //23S
{
NormaFlag = 0;
Timecnt = 0;
CTR_JDQ = 0;
}
}
}
else
{
Key_Scan();
if(Long8hFlag == 1) //---------8h
{
Time6mscnt++;
if(Time6mscnt == 250) //1.5s
{
Time6mscnt = 0;
Timecnt++;
if(Timecnt == 40 ) //19200
{
OutputFlag = 0;
Timecnt = 0;
}
}
}
else if(OutputFlag == 1)
{
Time6mscnt++;
if(Time6mscnt >= 250) //1s
{
Time6mscnt = 0;
Timecnt++;
}
switch(RunMode)
{
case 1: //------5S
if(Timecnt >= 4 ) //800
{
OutputFlag = 0;
Timecnt = 0;
// CTR_JDQ= 0;
}
break;
case 2: //------5M
if(Timecnt >= 7 ) //800
{
OutputFlag = 0;
Timecnt = 0;
// CTR_JDQ= 0;
// RunMode = 0;
}
break;
全智芯 -YD-PIR-DCMod-8位AD -L改进.rar_pir_全智芯_热释电_热释电红外
版权申诉
171 浏览量
2022-09-23
20:55:34
上传
评论
收藏 69KB RAR 举报
JonSco
- 粉丝: 70
- 资源: 1万+