基于STC89C52单片机空气PM2.5系统设计资料

news2024/11/15 3:41:44

  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char //宏定义
  5. sbit RS=P1^6;//液晶接口
  6. sbit EN=P1^7;
  7. sbit LED = P2^0;//粉尘传感器控制接口
  8. sbit ADCS = P3^7;//AD0832接口
  9. sbit ADCLK =P3^5;
  10. sbit ADDI = P3^6;
  11. sbit ADDO = P3^6;                  
  12. sbit SET= P1^1;//按键接口
  13. sbit ADD= P1^2;
  14. sbit DEC= P1^3;
  15. sbit BEEP=P2^1;//蜂鸣器接口
  16. uchar set_st;
  17. uchar tab[5];
  18. uint DUST_SET=150; //固体颗粒的阈值
  19. //bit shanshuo_st; //闪烁间隔标志
  20. bit beep_st; //蜂鸣器间隔标志
  21. uchar x=4; //计数器
  22. //定义标识
  23. uchar FlagStart = 0;
  24. float DUST_Value;
  25. uint DUST;
  26. uchar num=0;
  27. uchar mm;
  28. uchar abc;
  29. uchar ADC_Get[10]={0}; //定义AD采样数组
  30. uchar str[5]={0};
  31. /*****初始化定时器0*****/
  32. void InitTimer(void)
  33. {
  34.         TMOD = 0x01;
  35.         TL0 = (65536-10000)/256; //定时10ms
  36.         TH0 = (65536-10000)%256;
  37.         TR0 = 1;
  38.         ET0 = 1;
  39.         EA = 1;
  40. }
  41. /*************************lcd1602程序**************************/
  42. void delay1ms(uint ms)//延时1毫秒
  43. {
  44.     uint i,j;
  45.         for(i=0;i<ms;i++)
  46.         for(j=0;j<100;j++);
  47. }
  48. void wr_com(uchar com)//写指令//
  49. {
  50.     delay1ms(1);
  51.         RS=0;
  52. //        RW=0;
  53.         EN=0;
  54.         P0=com;
  55.         delay1ms(1);
  56.         EN=1;
  57.         delay1ms(1);
  58.         EN=0;
  59. }
  60. void wr_dat(uchar dat)//写数据//
  61. {
  62.     delay1ms(1);;
  63.         RS=1;
  64. //        RW=0;
  65.         EN=0;
  66.         P0=dat;
  67.         delay1ms(1);
  68.         EN=1;
  69.         delay1ms(1);
  70.         EN=0;
  71. }
  72. /*****************************液晶初始化
  73. *********************************************/
  74. void lcd_init()//初始化设置//
  75. {
  76.         delay1ms(15);
  77.         wr_com(0x38);
  78.         delay1ms(5);
  79.         wr_com(0x01);
  80.         delay1ms(5);
  81.         wr_com(0x06);
  82.         delay1ms(5);
  83.         wr_com(0x0c);
  84.         delay1ms(5);
  85.         wr_com(0x80);
  86.         wr_dat('P');//
  87.         wr_com(0x81);
  88.         wr_dat('M');//:
  89.         wr_com(0x82);
  90.         wr_dat('2');//
  91.         wr_com(0x83);
  92.         wr_dat('.');//:
  93.         wr_com(0x84);
  94.         wr_dat('5');//:
  95.         wr_com(0x85);
  96.         wr_dat(':');
  97.         wr_com(0x8b);
  98.         wr_dat('m');
  99.         wr_com(0x8c);
  100.         wr_dat('g');
  101.         wr_com(0x8d);
  102.         wr_dat('/');
  103.         wr_com(0x8e);
  104.         wr_dat('m');
  105.         wr_com(0x8f);
  106.         wr_dat('3');
  107.        
  108. /
  109.         wr_com(0xc0);
  110.         wr_dat('A');
  111.         wr_com(0xc1);
  112.         wr_dat('l');
  113.         wr_com(0xc2);
  114.         wr_dat('a');
  115.         wr_com(0xc3);
  116.         wr_dat('r');
  117.         wr_com(0xc4);
  118.         wr_dat('m');
  119.         wr_com(0xc5);
  120.         wr_dat(':');
  121.         wr_com(0xcb);
  122.         wr_dat('m');
  123.         wr_com(0xcc);
  124.         wr_dat('g');
  125.         wr_com(0xcd);
  126.         wr_dat('/');
  127.         wr_com(0xce);
  128.         wr_dat('m');
  129.         wr_com(0xcf);
  130.         wr_dat('3');
  131. }
  132. /*****************显示函数******************************/
  133. void disp(unsigned int Data)//PM2.5值显示
  134. {
  135.         uint Temp;
  136.         Temp=Data%10000;
  137.         str[0]=Temp/1000+0x30; //千位
  138.         Temp%=1000;
  139.         str[1]='.';
  140.         str[2]=Temp/100+0x30; //百位
  141.         Temp%=100;
  142.         str[3]=Temp/10+0x30; //十位
  143.         str[4]=Temp%10+0x30; //个位
  144.         wr_com(0x86);
  145.         wr_dat(str[0]);
  146.         wr_com(0x87);
  147.         wr_dat(str[1]);
  148.         wr_com(0x88);
  149.         wr_dat(str[2]);
  150.         wr_com(0x89);
  151.         wr_dat(str[3]);
  152.         wr_com(0x8a);
  153.         wr_dat(str[4]);
  154. }
  155. /************************报警值显示************************************/
  156. void baojing()
  157. {
  158.         wr_com(0xc6);
  159.         wr_dat(tab[0]+0x30);
  160.         wr_com(0xc7);
  161.         wr_dat(tab[1]);
  162.         wr_com(0xc8);
  163.         wr_dat(tab[2]+0x30);
  164.         wr_com(0xc9);
  165.         wr_dat(tab[3]+0x30);
  166.         wr_com(0xca);
  167.         wr_dat(tab[4]+0x30);
  168. }
  169. /*****延时子程序*****/
  170. void Delay(uint num)
  171. {
  172. while( --num );
  173. }
  174. /**************************按键检测
  175. *******************************************/
  176. void checkkey()
  177. {
  178.         if(SET==0)
  179.         {
  180.         Delay(2000);
  181.         do{}while(SET==0);
  182.         set_st++;
  183.         if(set_st>1)set_st=0;
  184.         }
  185.         if(set_st==0)
  186.         {
  187.         }
  188.         else if(set_st==1)
  189.         {
  190.         if(DEC==0)
  191.         {
  192.         Delay(2000);
  193.         do{}while(DEC==0);
  194.         if(DUST_SET>0)DUST_SET--;
  195.         if(DUST_SET==0)DUST_SET=0;
  196.         }
  197.         if(ADD==0)
  198.         {
  199.         Delay(2000);
  200.         do{}while(ADD==0);
  201.         DUST_SET++;
  202.         if(DUST_SET>800)DUST_SET=800;
  203.         }
  204.         }
  205.         tab[0]=DUST_SET/1000;
  206.         tab[1]='.';
  207.         tab[2]=DUST_SET%1000/100;
  208.         tab[3]=DUST_SET%100/10;
  209.         tab[4]=DUST_SET%10;
  210. }
  211. /*****报警子程序*****/
  212. void Alarm()
  213. {
  214.         if(x>=10){beep_st=~beep_st;x=0;}
  215.         if(DUST>DUST_SET&&beep_st==1)BEEP=0;
  216.         else BEEP=1;
  217. //        if(DUST>0&&DUST<100){LED2=0;LED3=1;LED4=1;}
  218. //        if(DUST>=10&&DUST<300){LED2=1;LED3=0;LED4=1;}
  219. //        if(DUST>=300){LED2=1;LED3=1;LED4=0;}
  220.         }
  221. /**************************AD0832转换程序
  222. ***********************************************/
  223. uchar ADC0832(bit mode,bit channel) //AD转换,返回结果
  224. {
  225.         uchar i,dat,ndat;
  226.         ADCS = 0;//拉低CS端
  227.         _nop_();
  228.         _nop_();
  229.         ADDI = 1; //第1个下降沿为高电平
  230.         ADCLK = 1;//拉高CLK端
  231.         _nop_();
  232.         _nop_();
  233.         ADCLK = 0;//拉低CLK端,形成下降沿1
  234.         _nop_();
  235.         _nop_();
  236.         ADDI = mode; //低电平为差分模式,高电平为单通道模式。
  237.         ADCLK = 1;//拉高CLK端
  238.         _nop_();
  239.         _nop_();
  240.         ADCLK = 0;//拉低CLK端,形成下降沿2
  241.         _nop_();
  242.         _nop_();
  243.         ADDI = channel; //低电平为CH0,高电平为CH1
  244.         ADCLK = 1;//拉高CLK端
  245.         _nop_();
  246.         _nop_();
  247.         ADCLK = 0;//拉低CLK端,形成下降沿3
  248.         ADDI = 1;//控制命令结束(经试验必需)
  249.         dat = 0;
  250.         //下面开始读取转换后的数据,从最高位开始依次输出(D7~D0)
  251.         for(i = 0;i < 8;i++)
  252.         {
  253.         dat <<= 1;
  254.         ADCLK=1;//拉高时钟端
  255.         _nop_();
  256.         _nop_();
  257.         ADCLK=0;//拉低时钟端形成一次时钟脉冲
  258.         _nop_();
  259.         _nop_();
  260.         dat |= ADDO;
  261.         }
  262.         ndat = 0; //记录D0
  263.         if(ADDO == 1)
  264.         ndat |= 0x80;
  265.         //下面开始继续读取反序的数据(从D1到D7)
  266.         for(i = 0;i < 7;i++)
  267.         {
  268.         ndat >>= 1;
  269.         ADCLK = 1;//拉高时钟端
  270.         _nop_();
  271.         _nop_();
  272.         ADCLK=0;//拉低时钟端形成一次时钟脉冲
  273.         _nop_();
  274.         _nop_();
  275.         if(ADDO==1)
  276.         ndat |= 0x80;
  277.         }
  278.         ADCS=1;//拉高CS端,结束转换
  279.         ADCLK=0;//拉低CLK端
  280.         ADDI=1;//拉高数据端,回到初始状态
  281.         if(dat==ndat)
  282.         return(dat);
  283.         else
  284.         return 0;
  285. }
  286. /*****定时器0中断服务程序*****/
  287. void timer0(void) interrupt 1
  288. {
  289.         uint j;
  290.         TL0 = (65536-10000)/256; //定时10ms
  291.         TH0 = (65536-10000)%256;
  292.         LED=1; //开启传感器的LED
  293.         x++;
  294.         for (j=0;j<30;j++); //0.28ms //延时0.28ms
  295.         abc=ADC0832(1,0); //开启ADC采集
  296.         FlagStart=1;
  297.         TR0 = 0; //先关闭定时器0
  298.         EA = 0;
  299.         LED=0;//关闭传感器LED
  300. }
  301. //中值滤波
  302. //算法:先进行排序,然后将数组的中间值作为当前值返回。
  303. uchar Error_Correct(uchar *str,uchar num)
  304. {
  305.         unsigned char i=0;
  306.         unsigned char j=0;
  307.         unsigned char Temp=0;
  308.         //排序
  309.         for(i=0;i<num-1;i++)
  310.         {
  311.         for(j=i+1;j<num;j++)
  312.         {
  313.            if(str[i]<str[j])
  314.                 {
  315.                 Temp=str[i];
  316.                 str[i]=str[j];
  317.                 str[j]=Temp;
  318.                 }
  319.         }
  320. }
  321.         //去除误差,取中间值
  322.         return str[num/2];
  323. }
  324. /*****主函数*****/
  325. void main(void)
  326. {
  327.         InitTimer(); //初始化定时器
  328.         BEEP=1;
  329.         lcd_init();//初始化显示
  330.         delay1ms(500);
  331.         while(1)
  332.         {
  333.          checkkey();//按键检测
  334.         if(set_st==0)
  335.         {
  336.                 //wr_com(0x0c);
  337.                 if(FlagStart==1) //1次数据采集完成
  338.                 {
  339.                 num++;
  340.                 ADC_Get[num]=abc;
  341.                 if(num>9)
  342.                 {
  343.                 num=0;
  344. //                DUST=Error_Correct(ADC_Get,10); //求取10次AD采样的值
  345. //                DUST_Value=(DUST/256.0)*5000; //转化成电压值MV
  346. //                DUST_Value=DUST_Value*0.17-100; //固体悬浮颗粒浓度计算 Y=0.17*X-0.1 X--采样电压V
  347.        
  348.                 DUST=Error_Correct(ADC_Get,10);
  349.             DUST_Value=(DUST/256.0)*5;//转化成电压值
  350.             DUST_Value=(DUST_Value*0.17-0.1)*1000;//固体悬浮颗粒浓度计
  351.        
  352.                 if(DUST_Value<0) DUST_Value=0;
  353.                 if(DUST_Value>760) DUST_Value=760; //限位
  354.                 DUST=(uint)DUST_Value;
  355.                 }
  356.                 TL0 = (65536-10000)/256;
  357.                 TH0 = (65536-10000)%256;
  358.                 TR0 = 1; //开启定时器0
  359.                 EA = 1;
  360.                 FlagStart=0;
  361.                 }
  362.                 Alarm(); //报警检测
  363.         }
  364.         disp(DUST);//显示粉尘浓度值
  365.         baojing();//显示报警值
  366.                 if(set_st==1)//报警值闪动
  367.                 {
  368.                 wr_com(0xca);
  369.                 wr_com(0x0d);
  370.                 delay1ms(150);
  371.                 }
  372.         }
  373. }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1793308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】Python报错 RuntimeError: No CUDA GPUs are available

本文摘要&#xff1a;本文已解决 Python FileNotFoundError 的相关报错问题&#xff0c;并总结提出了几种可用解决方案。同时结合人工智能GPT排除可能得隐患及错误。 &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领…

使用cesiumLab使shp转为3dtlies

过程不做赘述&#xff0c;网上大把&#xff0c;说下注意事项。 1. 存储3DTiles 选项 若是打开则输出的文件为glb格式文件,因为glb文件好储存易传输跨平台。cesium可以使用但无法处理&#xff0c;例如改变颜色&#xff0c;改着色器等。若是不打开则输出的文件为bm3d格式文件,此…

网络运维简介

目录 1.网络运维的定义 2.诞生背景 3.网络运维的重要性 4.优点 5.缺点 6.应用场景 6.1.十个应用场景 6.2.数据中心运维 7.应用实例 8.小结 1.网络运维的定义 网络运维&#xff08;Network Operations&#xff09;是指管理、监控和维护计算机网络以确保其高效、安全和…

IDEA快捷生成左边变量,取消final关键字

一&#xff1a;问题 如图&#xff1a;每次使用CtrlALtV或.var自动生成左边变量都会有final关键字&#xff0c;然后需要删除很麻烦 二&#xff1a;解决 以下步骤设置取消生成final关键字 1.先 生成变量&#xff1a;我是使用.var自动生成左边变量 2.使用快捷键ALtshiftO或者点…

C#WPF数字大屏项目实战08--生产量/良品统计

1、区域划分 生产量/良品统计这部分位于第二列的第二行 2、livechart拆线图 定义折线图,如下: <lvc:CartesianChart> <lvc:CartesianChart.Series> <!--设置Series的类型为 Line 类型, 该类型提供了一些折线图的实现--> <lvc:LineSeries/>…

装饰器,状态管理和if判断(HarmonyOS学习第六课)

Builder装饰器-自定义构建函数 前面介绍了如何创建一个自定义组件。该自定义组件内部UI结构固定&#xff0c;仅与使方法进行数据传递。ArkUI还提供了一种更轻量的UI 元素复用机制Builder&#xff0c;Builder 所装饰的函数遵循build( )函数语法规则&#xff0c;开发者可以将重…

AutoMQ 生态集成 Tigris

Tigris[1]是一个全球分布式的兼容 S3 的对象存储服务&#xff0c;它允许你存储和访问任意数量的数据&#xff0c;具有广泛的使用场景。Tigris 会自动且智能地将数据分布到靠近用户的位置&#xff0c;让用户无需担心数据复制和缓存复杂性。 你可以将 Tigris 用于多种场景&#x…

探究MySQL中的“树”结构

1 引言 树高千丈,叶落求索 – 唐代杜牧 树结构在MySQL中常用于表示层次关系,如组织结构或分类体系。引入树结构可使数据之间建立父子关系,便于查询和管理。益处包括快速检索子节点、方便展示层次关系、支持递归查询等。 2 基础概念 2.1 名词解析 程序就像是一张有向图,你…

全能大模型AIGC产品的体验与未来展望

目录 前言1 使用体验分享1.1 字节豆包1.2 百度文心一言1.3 阿里通义千问1.4 腾讯元宝 2 大模型产品的对比与选择2.1 产品功能对比2.2 使用成本与便捷性2.3 安全性与隐私保护 3 大模型产品的未来发展方向3.1 技术创新3.2 可持续与可拓展性3.3 用户体验3.4 应用场景 结语 前言 随…

vue 如何制作一个跟随窗口大小变化而变化的组件

vue 如何制作一个跟随窗口大小变化而变化的组件 像下图中展示的那些统计数件就是跟随窗口变化而变化的&#xff0c;而且是几乎等比缩放的。 实现原理 只简略说一下原理。 pinia 中记录一个窗口变化的高度值给要变化的组件添加一个高度值组件内部所有关于长度距离的值都通过这…

利用同时预测节点和边的图神经网络 实现鲁棒的椎骨识别

文章目录 Robust Vertebra Identification Using Simultaneous Node and Edge Predicting Graph Neural Networks摘要方法实验结果 Robust Vertebra Identification Using Simultaneous Node and Edge Predicting Graph Neural Networks 摘要 该论文指出,在CT扫描中自动定位和…

神经网络 torch.nn---Convolution Layers

torch.nn — PyTorch 2.3 documentation torch.nn - PyTorch中文文档 (pytorch-cn.readthedocs.io) torch.nn和torch.nn.functional的区别 torch.nn是对torch.nn.functional的一个封装&#xff0c;让使用torch.nn.functional里面的包的时候更加方便 torch.nn包含了torch.nn.…

使用API有效率地管理Dynadot域名,删除已设置的文件夹

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

几种更新 npm 项目依赖的实用方法

几种更新 npm 项目依赖的实用方法 引言1. 使用 npm update 命令2. 使用 npm-check-updates 工具3. 使用 npm outdated 命令4. 直接手动更新 package.json 文件5. 直接安装最新版本6. 使用自动化工具结语 引言 在软件开发的过程中&#xff0c;我们知道依赖管理是其中一个至关重…

Linux基础指令磁盘管理002

LVM&#xff08;Logical Volume Manager&#xff09;是Linux系统中一种灵活的磁盘管理和存储解决方案&#xff0c;它允许用户在物理卷&#xff08;Physical Volumes, PV&#xff09;上创建卷组&#xff08;Volume Groups, VG&#xff09;&#xff0c;然后在卷组上创建逻辑卷&am…

【Unity性能优化】使用多边形碰撞器网格太多,性能消耗太大了怎么办

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 专栏交流&#x1f9e7;&…

【多模态】35、TinyLLaVA | 3.1B 的 LMM 模型就可以实现 7B LMM 模型的效果

文章目录 一、背景二、方法2.1 模型结构2.2 训练 pipeline 三、模型设置3.1 模型结构3.2 训练数据3.3 训练策略3.4 评测 benchmark 四、效果 论文&#xff1a;TinyLLaVA: A Framework of Small-scale Large Multimodal Models 代码&#xff1a;https://github.com/TinyLLaVA/T…

Stable Diffusion——四种模型 LoRA(包括LyCORIS)、Embeddings、Dreambooth、Hypernetwork

目前 Stable diffusion 中用到主要有四种模型&#xff0c;分别是 Textual Inversion &#xff08;TI&#xff09;以 Embeddings 为训练结果的模型、Hypernetwork 超网络模型、LoRA&#xff08;包括 LoRA 的变体 LyCORIS&#xff09;模型、Dreambooth 模型。 视频博主 koiboi 用…

儿童护眼灯哪个好?带你了解适合儿童的护眼灯款式分享

儿童护眼灯哪个好&#xff1f;作为我们日常生活中极为实用的小家电&#xff0c;为了确保使用台灯时的舒适性并且保护视力&#xff0c;选择一款专业的护眼台灯成为了一个明智的决定。这样的台灯能够提供更舒适、均匀的照明环境&#xff0c;那么到底儿童护眼灯哪个好你&#xff1…

LeetCode刷题之HOT100之不同路径

2024/6/6 小雨&#xff0c;没停。明天就要高考啦&#xff0c;回想五年前我也带着紧张与期待走过这些天&#xff0c;祝高考学子一切顺利。Anyway&#xff0c;早上一到实验室我就去看望我的栀子花&#xff0c;带着满怀的期待去看它长大了多少&#xff0c;是的&#xff0c;花苞还在…