TQ322 数字PIR特性:
双元单通数字输出
热释电红外传感器
我使用中断读取的方式即时获取数字PIR传感器内最新的数据具体时序如下:
单片机IO 模拟时序程序如下: (代码中NOP数量根据单片机主频和型号自行调整)
/*-------------------------------------------------* 函数名:DelayUs* 功能: 短延时函数 --16M-4T--大概快1%左右.* 输入: Time延时时间长度 延时时长Time*2Us* 输出: 无 -------------------------------------------------*/ void DelayUs(unsigned char Time) {unsigned char a;for(a=0;a<Time;a++){NOP();} } /*------------------------------------------------- * 函数名:DelayMs* 功能: 短延时函数 快1%* 输入: Time延时时间长度 延时时长Time ms* 输出: 无 -------------------------------------------------*/ void DelayMs(unsigned char Time) {unsigned char a,b;for(a=0;a<Time;a++){for(b=0;b<5;b++){DelayUs(98); }} } /*-------------------------------------------------* 函数名:POWER_INITIAL* 功能: 上电系统初始化* 输入: 无* 输出: 无--------------------------------------------------*/ void POWER_INITIAL (void) { OSCCON = 0B01110001; //16MHz 1:1INTCON = 0; //暂禁止所有中断 OPTION = 0;}#define NUM_PIR_IO PA2void NUM_PIR_IO_OUTPUT() {TRISA &=0xFB; //配置 PA2为输出 }void NUM_PIR_IO_INPUT_PU() {WPUA |=0X04; //配置PA2弱上拉开启TRISA |=0X04; //配置 PA2为输入模式 }void NUM_PIR_IO_INPUT_Hi_Z() {WPUA &=0XFB; //关闭上拉电阻TRISA |=0X04; //配置 PA2为输入模式 }//初始化PIR IO void NUM_PIR_IO_Init() {NUM_PIR_IO_OUTPUT();NUM_PIR_IO =0; //拉低 数字PIR 接口 DelayMs(1); //等待1 ms }void NUM_PIR_Rest() //强制复位 PIR传感器 {NUM_PIR_IO_OUTPUT();NUM_PIR_IO =1;DelayUs(200);NUM_PIR_IO =0;DelayUs(7);NUM_PIR_IO_INPUT_Hi_Z(); }uchar PIR_Receive_data =0; //收集起始位,用于判断PIR 数据有效 uchar PIR_Dat_Flag=0; //数据有效标志位,置1说明收到了一组有效的数据
//获取到有效的PIR数据时 对 PIR_Dat_Flag 置1 并返回对应数值否则返回 0 int NUM_PIR_Dat_Read() {uint i;int dat;dat =0;DelayUs(80);PIR_Receive_data =0;for(i =0;i<19;i++){NUM_PIR_IO =0; //设置输出为0NUM_PIR_IO_OUTPUT(); //设置为输出模式//DelayUs(5); NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NUM_PIR_IO =1; //设置输出为1 NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();NUM_PIR_IO_INPUT_Hi_Z(); //配置为高阻抗输入等待数据 NOP(); NOP();NOP(); NOP();NOP(); NOP();NOP(); NOP();if((i>1)&&(i<18)){dat<<=1;if(NUM_PIR_IO==1) //读取到1时,置位数据 {dat|=0x01;}}else{PIR_Receive_data<<=1;if(NUM_PIR_IO==1){PIR_Receive_data |=1;} } }NUM_PIR_IO =0;NUM_PIR_IO_OUTPUT();DelayUs(2);NUM_PIR_IO_INPUT_Hi_Z();DelayUs(2);NUM_PIR_IO =0;if(PIR_Receive_data==0x04){PIR_Dat_Flag =1; //pir数据有效标志位 }else{PIR_Dat_Flag =0; //pir数据无效 }if(dat>=0)return dat;elsereturn 0;return 0; }#define NUM_PIR_Buff_Len 12 //PIR 数据缓存 uint NUM_PIR_Buff[NUM_PIR_Buff_Len]; //PIR数据缓存 uchar Num_PIR_Buff_Dat_Num =0; //数字PIR缓存数据数量 uchar NUM_PIR_Dat_Run_Flag =0; //表示从NUM PIR数据滤波中输出了一个有效的 PIR 数据/******************************************** @函数名称: NUM_PIR_Dat_Run* @输入: Num_PIR_Dat_IN 新输入的 数字PIR 传感器数据值** @函数功能: 输入数据并缓存,当数据总量符合预设Buff数量时进行排列取中位数* @NOTE: 一般建议输出值大于35左右时触发,可根据实际工况微调*******************************************/uint NUM_PIR_Dat_Run(uint Num_PIR_Dat_IN) {uchar i,it;uint Dat =0;if(Num_PIR_Buff_Dat_Num<NUM_PIR_Buff_Len){if(PIR_Dat_Flag==1){NUM_PIR_Buff[(uchar)Num_PIR_Buff_Dat_Num++] = Num_PIR_Dat_IN;PIR_Dat_Flag =0;}}else{for(i =0;i<NUM_PIR_Buff_Len;i++){for(it =0;it<NUM_PIR_Buff_Len;it++){if(NUM_PIR_Buff[i]<NUM_PIR_Buff[it]){Dat = NUM_PIR_Buff[it];NUM_PIR_Buff[it] = NUM_PIR_Buff[i];NUM_PIR_Buff[i] = Dat;}}}Dat = NUM_PIR_Buff[NUM_PIR_Buff_Len/2];NUM_PIR_Dat_Run_Flag =1;return Dat;}return 0; }void NUM_PIR_INT_Init() {NUM_PIR_IO_INPUT_Hi_Z(); //配置 数字PIR IO 为高阻抗输入 OPTION = 0B01001000; // 配置中断为上升沿,分配分配电路给WDT后分配器 MSCON = 0B00000000; }//开启外部中断 void NUM_PIR_INT_EN() {NUM_PIR_IO_INPUT_Hi_Z();INTEDG =1; //配置PA2 INT 为上升沿触发INTF =0; //清除PA2 INT 中断标志位INTE =1;GIE =1; }#define PIR_High_Trigger_Dat 30 //设定触发值 uchar LEDOP =0; uint Num_PIR_OUT_Dat =0; uint PIR_Dat =0; void interrupt ISR(void) {if(INTE && INTF){ INTE =0; //暂先禁止PA2中断GIE =0; //关闭总中断 Num_PIR_OUT_Dat = (uint)NUM_PIR_Dat_Read();if(PIR_Dat_Flag==1){PIR_Dat = NUM_PIR_Dat_Run(Num_PIR_OUT_Dat); //将获取到的有效数据放入滤波缓存 }if(NUM_PIR_Dat_Run_Flag==1) //滤波是否有数据输出 {NUM_PIR_Dat_Run_Flag =0; //清空标志位if(PIR_Dat<PIR_High_Trigger_Dat) //符合触发值 {PA4 =0;}else{PA4 =1;}}INTF =0;INTE =1; //重新开启外部中断GIE =1; //开启总中断 } }/*-------------------------------------------------* 函数名:main * 功能: 主函数* 输入: 无* 输出: 无--------------------------------------------------*/ void main() {POWER_INITIAL(); //系统初始化 NUM_PIR_IO_Init();NUM_PIR_Rest();NUM_PIR_INT_Init();NUM_PIR_Dat_Read();NUM_PIR_INT_EN();TRISA4 =0;while(1){SLEEP();} }