目前用于读取负压的场景如下所示:
监测系统状态:负压读数用于监控系统是否正常运行,确保压力维持在设定范围内。
保障安全:在医疗、实验室等环境中,负压能防止有害物质外泄,保护人员安全。
优化性能:在工业设备中,负压监测有助于调整运行参数,提升效率和产品质量。
故障诊断:负压异常可提示系统问题,如泄漏或堵塞,便于及时排查和修复。
满足合规要求:某些行业对负压有严格规定,监测数据用于确保符合标准,避免违规。
支持科研:在科研中,负压数据用于实验控制和结果分析,确保实验条件准确。
总结来说,读取负压的目的是为了确保系统安全、高效运行,并满足相关规范要求。
一:硬件设计
1.1 主控的选择
这里为了节约成本,调试方便,当时选择了STC8A的芯片,不过现在看来选择STC带有USB功能的芯片更加的好一些;
这里在硬件设计的时候需要注意下,STC8芯片的UCAP 引脚需要并联一个0.1uf电容,否则芯片不能正常工作。
1.2 采集电路如下所示:
采用两路的放大,将传感器的输出的信号进行一个放大,以便STC内的ADC采集到。
低功耗:适合电池供电设备,静态电流低。
宽电源电压范围:单电源(3V至32V)或双电源(±1.5V至±16V)均可工作,适应性强。
高增益:开环增益高,适合需要高放大倍数的应用。
共模输入范围宽:输入电压范围可低至地电位,适合处理接近地电位的信号。
输出摆幅大:输出电压可接近电源电压,充分利用电源范围。
稳定性高:内部频率补偿,无需外部元件,简化设计。
成本低:价格低廉,适合成本敏感的应用。
应用广泛:可用于信号放大、滤波、比较器、振荡器等多种电路。
温度稳定性好:在较宽温度范围内性能稳定,适合工业环境。
易于使用:引脚配置简单,设计方便。
凭借着LM358凭借低功耗、宽电压范围、高增益、低成本等优点,在本次项目中,我选择该款放大芯片。
传感器模块信息如下所示:
XGZP系列是一款适用于生物医学、气象等领域的压力传感器一颗利用MEMS技术加工的压力传感器芯片其核心部分,
该压由一个弹性膜及集成在膜上的四个电阻组成。
四个就电阻形成了惠斯通电桥结构,当有压力作用在弹性膜上时电应生一个与所加压力成线性比例关系的电压输出信号。
1.3 显示电路如下所示:
采用2个四位的共阴极数码管进行显示,当前的压力数据、工作时间等等数据信息。
共阴极数码管通常由7段LED组成,分别标记为a、b、c、d、e、f、g,有时还包括一个小数点(dp)。这些段通过不同的组合可以显示0-9的数字以及一些字母。
a、b、c、d、e、f、g:这7段LED分别控制数码管的不同部分,通过点亮不同的段可以显示不同的数字或字符。dp:小数点,用于显示小数部分。
工作原理:
在共阴极数码管中,所有LED的阴极连接在一起并接地(GND)。要显示某个数字或字符,需要在对应的阳极上施加正电压(通常为3.3V或5V),使得相应的LED段点亮。
例如,要显示数字“8”,需要点亮所有的段(a、b、c、d、e、f、g)。要显示数字“0”,则点亮除了g段之外的所有段。
这里我采用直接驱动的方式:微控制器的I/O口直接连接到数码管的阳极,通过控制I/O口的高低电平来控制数码管的显示。
使用时候的注意事项:
限流电阻:为了防止LED过流损坏,通常需要在每个阳极上串联一个限流电阻。
电压匹配:确保驱动电压与数码管的工作电压匹配,避免损坏数码管。
1.4 电源电路、报警电路
采用贴片L7805,把外部供电电压DC12V,降至DC5V,由于本款电路板功耗较低,没有大功率元器件,该款模块完全满足要求。
报警电路采用 DC5V 无源蜂鸣器,当到达时间时候,做出提示。
二:软件部分如下所示:
2.1:LED驱动以及自建部分:
//======================================================================== // 函数: void DsipFresh(void) // 描述: 刷新各个数码管,在定时0中被调用,每1ms执行一次 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-01 //======================================================================== void DsipFresh(void) { BIT0 = 0 ; BIT1 = 0 ; BIT2 = 0 ; BIT3 = 0 ; BIT4 = 0; BIT5 = 0 ; BIT6 = 0 ; BIT7 = 0 ; ucDisPoint++; if(ucDisPoint > 8) ucDisPoint = 0; DataPort = ~ ucDispBuf[ucDisPoint]; //数组里面数码管为共阴极模式,故此处做取反操作 //DataPort = ucDispBuf[ucDisPoint]; switch(ucDisPoint) { case 0: BIT0 = 1; break; case 1: BIT1 = 1; break; case 2: BIT2 = 1; break; case 3: BIT3 = 1; break; case 4: BIT4 = 1; break; case 5: BIT5 = 1; break; case 6: BIT6 = 1; break; case 7: BIT7 = 1; break; default: break; }
2.2 数码管自检函数:
//======================================================================== // 函数: void DispCheckLed(void) // 描述: 程序开始时用于自检各个数码管的段选,判断数码管是否正常. // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-01 //======================================================================== void DispCheckLed(void) { uchar i; /*数码段测试*/ for(i=0;i<9;i++) //数码管自检, { ucDispBuf[0] = LED_START[i]; ucDispBuf[1] = LED_START[i]; ucDispBuf[2] = LED_START[i]; ucDispBuf[3] = LED_START[i]; ucDispBuf[4] = LED_START[i]; ucDispBuf[5] = LED_START[i]; ucDispBuf[6] = LED_START[i]; ucDispBuf[7] = LED_START[i]; ucDispBuf[8] = LED_START[i]; ucDispBuf[9] = LED_START[i]; ucDispBuf[10] = 0xff; //关闭所有数码管 delay_ms(200); } }
2.3 工作界面显示
//======================================================================== // 函数: void DispVer(void) // 描述: 显示当前的负压值和剩余实验室检查 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-01 //======================================================================== void DispWork(void) { /*显示当前检测气压值*/ UintToBcd(iSampleData) ; ucDispBuf[0] = Led_strokes[ucBcdBuf[3]].stroke ;// // 显示环境温度 ucDispBuf[1] = Led_strokes[ucBcdBuf[2]].stroke ; ucDispBuf[2] = Led_strokes[ucBcdBuf[1]].stroke ; ucDispBuf[3] = Led_strokes[ucBcdBuf[0]].stroke ; /*试验状体下,显示剩余工作时间*/ if(ucTestState ==0) UintToBcd(iTestTime) ; else UintToBcd(iCurrentTime) ; ucDispBuf[4] = Led_strokes[ucBcdBuf[3]].stroke ; ucDispBuf[5] = Led_strokes[ucBcdBuf[2]].stroke ; ucDispBuf[6] = Led_strokes[ucBcdBuf[1]].stroke ;// ucDispBuf[7] = Led_strokes[ucBcdBuf[0]].stroke ;// }
2.4设置界面如下所示:
//======================================================================== // 函数: void DispVer(void) // 描述: 设置试验时间界面,同时显示负压值 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-01 //======================================================================== void SetTimePage(void) { // UintToBcd(2345) ; ucDispBuf[0] = 0x6D ; // S // 显示设置试件 ucDispBuf[1] = 0x79 ; // E ucDispBuf[2] = 0x78 ; // T ucDispBuf[3] = 0x00 ; // 关闭 UintToBcd(iTestTime); // if( ucDisPosition == 0) { ucDispBuf[4] = Led_strokes[ucBcdBuf[3]].stroke ; ucDispBuf[5] = Led_strokes[ucBcdBuf[2]].stroke ; ucDispBuf[6] = Led_strokes[ucBcdBuf[1]].stroke ;// if( ucDisFlicker == 1 ) { ucDispBuf[7] = Led_strokes[ucBcdBuf[0]].stroke ;// } else { ucDispBuf[7] = 0x00 ;// } } else if( ucDisPosition == 1) { ucDispBuf[4] = Led_strokes[ucBcdBuf[3]].stroke ; ucDispBuf[5] = Led_strokes[ucBcdBuf[2]].stroke ; if( ucDisFlicker == 1 ) { ucDispBuf[6] = Led_strokes[ucBcdBuf[1]].stroke ;// } else { ucDispBuf[6] = 0x00 ;// } ucDispBuf[7] = Led_strokes[ucBcdBuf[0]].stroke ;// } else if( ucDisPosition == 2 ) { ucDispBuf[4] = Led_strokes[ucBcdBuf[3]].stroke ; if( ucDisFlicker == 1 ) { ucDispBuf[5] = Led_strokes[ucBcdBuf[2]].stroke ; } else { ucDispBuf[5] = 0x00 ;// } ucDispBuf[6] = Led_strokes[ucBcdBuf[1]].stroke ;// ucDispBuf[7] = Led_strokes[ucBcdBuf[0]].stroke ;// } else if( ucDisPosition == 3 ) { if( ucDisFlicker == 1 ) { ucDispBuf[4] = Led_strokes[ucBcdBuf[3]].stroke ; } else { ucDispBuf[4] = 0x00 ;// } ucDispBuf[5] = Led_strokes[ucBcdBuf[2]].stroke ; ucDispBuf[6] = Led_strokes[ucBcdBuf[1]].stroke ;// ucDispBuf[7] = Led_strokes[ucBcdBuf[0]].stroke ;// } }
2.5 STC的ADC 数据采集以及处理功能:
///*************************************************************************** //完成数字滤波 //计算压力值 ////***************************************************************************/ int CalculatePress(void) { u8 i; long lsum; int itemp; long itemp2; float Ki; unsigned int max , min ; lsum = 0; for(i=0;i<Filter;i++) { lsum += iSampleData; if(max < iSampleData ) max = iSampleData ; if(min > iSampleData ) min = iSampleData ; } lsum = (lsum - max -min )/ ( Filter - 2 ); //求得平均值 //lsum = lsum / NUM ; //进行真空度压力零点修正 itemp2 = iZeroCorrection; itemp = (lsum - ZEROSAMPLE)*SCAL; itemp = itemp + itemp2; //进行真空度满度校正 Ki = iFullCorrection; Ki = Ki/1000.0; itemp = itemp * Ki; //清零计算 itemp = itemp - iCurrPressZero; return itemp; }
2.6 键值处理函数如下:
//======================================================================== // 函数: void ThreeKeyDeal(void) // 描述: 处理按键 键值函数 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-02 //1 :设定 2:清除 3: 增加 4 :减少 5 :启动/停止 //======================================================================== void ThreeKeyDeal(void) { switch(ucDisplayPage) { case 0: break; case 1: if (ucDisPosition == 0 ) { if(iTestTime <9999) iTestTime ++ ; } else if(ucDisPosition == 1 ) {if(iTestTime <9999) iTestTime = iTestTime +10 ; } else if(ucDisPosition == 2 ) {if(iTestTime <9999) iTestTime = iTestTime +100 ; } else if(ucDisPosition == 3 ) {if(iTestTime <9999) iTestTime = iTestTime +1000 ; } break; case 2 : if (ucDisPosition == 0 ) { if(iZeroCorrection <9999) iZeroCorrection ++ ; } else if(ucDisPosition == 1 ) {if(iZeroCorrection <9999) iZeroCorrection = iZeroCorrection +10 ; } else if(ucDisPosition == 2 ) {if(iZeroCorrection <9999) iZeroCorrection = iZeroCorrection +100 ; } else if(ucDisPosition == 3 ) {if(iZeroCorrection <9999) iZeroCorrection = iZeroCorrection +1000 ; } break ; case 3 : if (iFullCorrection == 0 ) { if(iFullCorrection <9999) iFullCorrection ++ ; } else if(ucDisPosition == 1 ) {if(iFullCorrection <9999) iFullCorrection = iFullCorrection +10 ; } else if(ucDisPosition == 2 ) {if(iFullCorrection <9999) iFullCorrection = iFullCorrection +100 ; } else if(ucDisPosition == 3 ) {if(iFullCorrection <9999) iFullCorrection = iFullCorrection +1000 ; } break ; default: break; } } //======================================================================== // 函数: void FourKeyDeal(void) // 描述: 处理按键 键值函数 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-02 //1 :设定 2:清除 3: 增加 4 :减少 5 :启动/停止 //======================================================================== void FourKeyDeal(void) { switch(ucDisplayPage) { case 0: break; case 1: if (ucDisPosition == 0 ) { if(iTestTime >0) iTestTime -- ; } else if(ucDisPosition == 1 ){ if(iTestTime >10) iTestTime = iTestTime -10 ; } else if(ucDisPosition == 2 ){ if(iTestTime >100)iTestTime = iTestTime -100 ; } else if(ucDisPosition == 3 ){ if(iTestTime >1000) iTestTime = iTestTime -1000 ; } break; case 2 : if (ucDisPosition == 0 ) { if(iZeroCorrection >0) iZeroCorrection -- ; } else if(ucDisPosition == 1 ){ if(iZeroCorrection >10) iZeroCorrection = iZeroCorrection -10 ; } else if(ucDisPosition == 2 ){ if(iZeroCorrection >100)iZeroCorrection = iZeroCorrection -100 ; } else if(ucDisPosition == 3 ){ if(iZeroCorrection >1000) iZeroCorrection = iZeroCorrection -1000 ; } break ; case 3 : if (ucDisPosition == 0 ) { if(iFullCorrection >0) iFullCorrection -- ; } else if(ucDisPosition == 1 ){ if(iFullCorrection >10) iFullCorrection = iFullCorrection -10 ; } else if(ucDisPosition == 2 ){ if(iFullCorrection >100)iFullCorrection = iFullCorrection -100 ; } else if(ucDisPosition == 3 ){ if(iFullCorrection >1000) iFullCorrection = iFullCorrection -1000 ; } break ; default: break; } } //======================================================================== // 函数: void FiveKeyDeal(void) // 描述: 处理按键 键值函数 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-02 //1 :设定 2:清除 3: 增加 4 :减少 5 :启动/停止 //======================================================================== void FiveKeyDeal(void) { switch(ucDisplayPage) { case 0: if( ucTestState == 0 ) { ucTestState = 1 ; // iCurrentTime = iTestTime ; // LEDStart = 0 ; LEDStop = 1 ; BSP_JDQ = 1 ; } else { ucTestState = 0 ; LEDStart = 1 ; // LEDStop = 0 ; iCurrentTime = iTestTime ; } break; case 1: SaveTestParameter(); break; case 2 : SaveTestParameter(); break ; case 3 : SaveTestParameter(); break ; default: break; } } //======================================================================== // 函数: void DealKey(void) // 描述: 处理按键 键值函数 // 参数: None. // 返回: None. // 版本: V1.0, 2023-07-02 //1 :设定 2:清除 3: 增加 4 :减少 5 :启动/停止 //======================================================================== void DealKey(void) { ScanKey(); if(!b_KeyPush) return; b_KeyPush = 0; switch(ucKeyValue) { case 1: ucDisplayPage++; ucDisPosition = 0 ; if(ucDisplayPage >3) ucDisplayPage = 0 ; break; case 2: SencondKeyDeal(); break; case 3 : ThreeKeyDeal(); break ; case 4 : FourKeyDeal(); break ; case 5 : FiveKeyDeal(); break ; default: break; } BSP_BZ = 1 ; BSP_BZ_Time = 2 ; //运行间隔100MS ucPushPoint = ucPushCout ; //每次 }
三:实物图片如下所示:
四:实物视频如下所示:
EETV链接:https://v.eepw.com.cn/video/play/id/16245
基于STC8H制作的负压采集装置_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1MxQ1Y5EKK/?vd_source=fb5a6d1a3332aab1989e0f3e24f2afc1
感兴趣的朋友可观看视频~