【TB作品】msp430f5529单片机,dht22,烟雾传感器

功能

//硬件:msp430f5529、dht22、LCD1602、蜂鸣器、烟雾传感器、蓝牙模块。
//功能:读取温湿度、烟雾浓度显示到屏幕;
//按键调节三个报警数值;
//温度、湿度、烟雾浓度,任意一个大于报警数值就蜂鸣器报警;
//单片机将温度、湿度、烟雾浓度,通过蓝牙模块,发送到电脑端显示。
//电脑端也可以调节三个报警数值。

引脚


//PCF8574 LCD1602----MSP430F5529
//GND----------------GND
//VCC----------------3.3v
//SDA----------------P2.4
//SCL----------------P2.5//HC05 蓝牙----------MSP430F5529
//GND----------------GND
//VCC----------------3.3v
//RX-----------------P3.3  T
//TX-----------------P3.4  R//PM2烟雾传感器 0~3.3v电压转为ppm单位 20~20000ppm
//DHT22--------------MSP430F5529
//GND----------------GND
//VCC----------------3.3v
//DAT----------------P2.3//烟雾---------------MSP430F5529
//GND----------------GND
//VCC----------------3.3v
//A0-----------------P6.5//蜂鸣器-------------MSP430F5529
//GND----------------GND
//VCC----------------3.3v
//DAT----------------P1.6//按键----------------MSP430F5529
//KEY1----------------P1.2
//KEY2----------------P1.3
//KEY3----------------P1.4
//KEY4----------------P1.5
//GND-----------------GND//板子自己有的按键
//KEY5----------------P1.1
//KEY6----------------P2.1

部分程序


unsigned char get_key(void) //声明一个函数,返回值类型为 unsigned char,函数名为 get_key,参数列表为空
{unsigned char key; //声明一个名为 key 的无符号字符变量if ((P1IN & BIT2) == 0) //如果 P1IN 寄存器的第二位是 0,说明按键1被按下{delay_ms(10); //延时 10 毫秒,以确保读取的值稳定if ((P1IN & BIT2) == 0) //再次检测按键1是否被按下{key = 1; //将 key 设置为 1,表示按下了按键1while ((P1IN & BIT2) == 0)//等待按键1松开;}}else if ((P1IN & BIT3) == 0) //如果按键1未被按下,检测按键2是否被按下{delay_ms(10); //同样进行延时if ((P1IN & BIT3) == 0) //检测按键2是否被按下{key = 2; //将 key 设置为 2,表示按下了按键2while ((P1IN & BIT3) == 0)//等待按键2松开;}}else if ((P1IN & BIT4) == 0){delay_ms(10);if ((P1IN & BIT4) == 0){key = 3;while ((P1IN & BIT4) == 0);}}else if ((P1IN & BIT5) == 0){delay_ms(10);if ((P1IN & BIT5) == 0){key = 4;while ((P1IN & BIT5) == 0);}}else if ((P1IN & BIT1) == 0){delay_ms(10);if ((P1IN & BIT1) == 0){key = 5;while ((P1IN & BIT1) == 0);}}else if ((P2IN & BIT1) == 0){delay_ms(10);if ((P2IN & BIT1) == 0){key = 6;while ((P2IN & BIT1) == 0);}}else{key = 0;}return key;
}u8 data[5];
u16 shidu, wendu, yanwu;
u16 shidu_baojing = 900, wendu_baojing = 400, yanwu_baojing = 10000;
u8 disp[20];
u8 count = 0;
u8 timecnt = 0;
u8 keyvalue = 0;void disp_line1(void) // 定义名为disp_line1的函数
{count = 0; // 初始化计数器disp[count++] = wendu % 1000 / 100 + '0'; // 将温度百位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = wendu % 100 / 10 + '0'; // 将温度十位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = 'C'; // 存入字符'C',表示摄氏度,计数器+1disp[count++] = ' '; // 存入空格字符,计数器+1disp[count++] = shidu % 1000 / 100 + '0'; // 将湿度百位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = shidu % 100 / 10 + '0'; // 将湿度十位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = '%'; // 存入字符'%',表示百分比符号,计数器+1disp[count++] = ' '; // 存入空格字符,计数器+1disp[count++] = yanwu % 100000 / 10000 + '0'; // 将烟雾万位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = yanwu % 10000 / 1000 + '0'; // 将烟雾千位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = yanwu % 1000 / 100 + '0'; // 将烟雾百位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = yanwu % 100 / 10 + '0'; // 将烟雾十位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = yanwu % 10 + '0'; // 将烟雾个位数字转换为字符存入显示缓存数组,计数器+1disp[count++] = 'p'; // 存入字符'p',表示“ppm”(parts per million),计数器+1disp[count++] = 0; // 存入字符'\0',表示字符串结束,计数器+1LCD_write_str(0, 0, disp); // 在LCD屏幕第0行显示disp数组中的内容
}void send_computer(void)
{count = 0;disp[count++] = wendu % 1000 / 100 + '0';disp[count++] = wendu % 100 / 10 + '0';disp[count++] = 'C';disp[count++] = ' ';disp[count++] = shidu % 1000 / 100 + '0';disp[count++] = shidu % 100 / 10 + '0';disp[count++] = '%';disp[count++] = ' ';disp[count++] = yanwu % 100000 / 10000 + '0';disp[count++] = yanwu % 10000 / 1000 + '0';disp[count++] = yanwu % 1000 / 100 + '0';disp[count++] = yanwu % 100 / 10 + '0';disp[count++] = yanwu % 10 + '0';disp[count++] = 'p';disp[count++] = '\r';disp[count++] = '\n';disp[count++] = 0;Print_Str(disp);
}void disp_line2(void)
{count = 0; //计数器清零//显示湿度报警值的百位、十位disp[count++] = shidu_baojing % 1000 / 100 + '0';disp[count++] = shidu_baojing % 100 / 10 + '0';disp[count++] = 'C'; //显示'C'disp[count++] = ' '; //显示空格//显示温度报警值的百位、十位disp[count++] = wendu_baojing % 1000 / 100 + '0';disp[count++] = wendu_baojing % 100 / 10 + '0';disp[count++] = '%'; //显示'%'disp[count++] = ' '; //显示空格//显示烟雾报警值的万位、千位、百位、十位、个位disp[count++] = yanwu_baojing % 100000 / 10000 + '0';disp[count++] = yanwu_baojing % 10000 / 1000 + '0';disp[count++] = yanwu_baojing % 1000 / 100 + '0';disp[count++] = yanwu_baojing % 100 / 10 + '0';disp[count++] = yanwu_baojing % 10 + '0';disp[count++] = 'p'; //显示'p'disp[count++] = 0; //末尾字符为0//在LCD的第1行第0列显示字符串dispLCD_write_str(0, 1, disp);
}void deal_key(void)
{// 定义一个函数deal_key,没有返回值,没有参数if (keyvalue == 1){// 如果keyvalue的值为1shidu_baojing += 10;// 湿度报警值加10if (shidu_baojing > 900){// 如果湿度报警值大于900shidu_baojing = 900;// 把湿度报警值设为900}}else if (keyvalue == 2){// 否则,如果keyvalue的值为2shidu_baojing -= 10;// 湿度报警值减10if (shidu_baojing < 100){// 如果湿度报警值小于100shidu_baojing = 100;// 把湿度报警值设为100}}else if (keyvalue == 3){// 否则,如果keyvalue的值为3wendu_baojing += 10;// 温度报警值加10if (wendu_baojing > 900){// 如果温度报警值大于900wendu_baojing = 900;// 把温度报警值设为900}}else if (keyvalue == 4){// 否则,如果keyvalue的值为4wendu_baojing -= 10;// 温度报警值减10if (wendu_baojing < 100){// 如果温度报警值小于100wendu_baojing = 100;// 把温度报警值设为100}}else if (keyvalue == 5){// 否则,如果keyvalue的值为5yanwu_baojing += 100;// 烟雾报警值加100if (yanwu_baojing > 20000){// 如果烟雾报警值大于20000yanwu_baojing = 20000;// 把烟雾报警值设为20000}}else if (keyvalue == 6){// 否则,如果keyvalue的值为6yanwu_baojing -= 100;// 烟雾报警值减100if (yanwu_baojing < 200){// 如果烟雾报警值大于200yanwu_baojing = 200;// 把烟雾报警值设为200}}
}void contorl_beep(void) // 定义一个名为 contorl_beep 的函数
{if ((shidu > shidu_baojing) || (wendu > wendu_baojing) // 如果湿度、温度或烟雾任意一个超过了警戒值|| (yanwu > yanwu_baojing)){P1OUT &= ~BIT6; // 将 P1OUT 寄存器的第 6 位设置为 0,表示开启蜂鸣器}else // 如果湿度、温度和烟雾都没有超过警戒值{P1OUT |= BIT6; // 将 P1OUT 寄存器的第 6 位设置为 1,表示关闭开启蜂鸣器}
}/* 烟雾浓度换算 */
static unsigned int  yw_ppm_count(unsigned int x1)
{float a =0 ,b = 0,c = 0,d = 0;float ax =0 ,bx = 0,cx = 0,dx = 0;float y;float x;x=x1*3.3/4096;a = x * x * x * x * x;b = x * x * x * x;c = x * x * x;d = x * x ;ax = 0.0001923 * a;bx = 0.006017 * b;cx = 0.07267 * c;dx = 0.425 * d;y = ax - bx + cx - dx + (1.267 * x) + 1.209;y = y * 1000;return (unsigned int)y;
}void main(void)
{WDTCTL = WDTPW + WDTHOLD;                 // 停止看门狗定时器init_clock();                             // 初始化时钟init_uart();                              // 初始化UART串口init_adc();                               // 初始化ADC模块init_key();                               // 初始化按键init_beep();                              // 初始化蜂鸣器while (DHT22_Init() == 1)                 // 初始化DHT22温湿度传感器{delay_ms(100);                        // 延时100毫秒}delay_ms(1000);LCD_Init();                               // 初始化液晶屏disp_line2();                             // 在液晶屏上显示第二行_EINT();                                  // 开启总中断while (1)                                 // 无限循环{delay_ms(10);                         // 延时10毫秒timecnt++;                            // 时间计数器加1if (timecnt > 200)                    // 如果时间计数器超过200{timecnt = 0;                      // 重置时间计数器DHT22_Read_Data(data);            // 读取DHT22传感器数据shidu = data[0];                  // 湿度数据shidu = (shidu << 8) + data[1];   // 拼接数据wendu = data[2];                  // 温度数据wendu = (wendu << 8) + data[3];   // 拼接数据yanwu = get_adc();                // 获取烟雾浓度值//0到4096转为0到20000ppmyanwu = yw_ppm_count(yanwu);             // 将ADC值转换为烟雾浓度值contorl_beep();                    // 控制蜂鸣器disp_line1();                      // 在液晶屏上显示第一行disp_line2();                      // 在液晶屏上显示第二行send_computer();}keyvalue = get_key();                 // 获取按键值if (keyvalue)                         // 如果有按键按下{deal_key();                       // 处理按键disp_line2();                     // 在液晶屏上显示第二行}}
}unsigned char revchar = 0;                      // 定义一个无符号字符变量,初始值为0,用于保存接收到的字符
unsigned char revchar_openflag = 0;       // 定义一个无符号字符变量,初始值为0,用于标志接收到的字符是否为有效数据
unsigned char revchar_cnt = 0;               // 定义一个无符号字符变量,初始值为0,用于计数接收到的有效数据个数
unsigned char revchar_buffer[20];              // 定义一个无符号字符数组,长度为20,用于存储接收到的有效数据#pragma vector=USCI_A0_VECTOR                   // 定义中断函数,当 USCI_A0_VECTOR 中断发生时,执行以下函数
__interrupt void USCI_A0_ISR(void)
{switch (__even_in_range(UCA0IV, 4))// 获取 USCI_A0_VECTOR 中断的状态{case 0:                                     // Vector 0 - no interrupt,无中断状态break;case 2:                                     // Vector 2 - RXIFG,接收到数据的中断状态revchar = UCA0RXBUF;            // 读取 USCI_A0_VECTOR 的接收缓冲区数据到变量 revcharif (revchar_openflag)                   // 如果接收到的字符是有效数据{//S889912345                        // 检查接收到的数据是否符合特定的格式,如S889912345if ((revchar >= '0') && (revchar <= '9'))  // 如果接收到的数据是数字字符{revchar_buffer[revchar_cnt] = revchar - '0'; // 把接收到的数字字符转化为对应的数字存入 revchar_buffer 数组中revchar_cnt++;                              // 计数器加1if (revchar_cnt >= 9)                     // 如果接收到的数字字符数量达到特定的数量{shidu_baojing = revchar_buffer[0] * 100+ revchar_buffer[1] * 10;  // 计算湿度报警值wendu_baojing = revchar_buffer[2] * 100+ revchar_buffer[3] * 10;  // 计算温度报警值yanwu_baojing = revchar_buffer[4] * 10000+ revchar_buffer[5] * 1000 + revchar_buffer[6] * 100+ revchar_buffer[7] * 10 + revchar_buffer[8]; // 计算烟雾报警值revchar_openflag = 0;               // 清除接收标志revchar_cnt = 0;                    // 清除计数器}}else                                    // 如果接收到的字符不是数字字符{revchar_openflag = 0;               // 清除接收标志revchar_cnt = 0;                    // 清除计数器}}if (revchar == 'S'){revchar_openflag = 1;revchar_cnt = 0;}break;case 4:break;                             // Vector 4 - TXIFGdefault:break;}
}

全部程序

https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2

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

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

相关文章

如何编辑pdf文件内容?编辑技巧大揭秘,秒变办公达人!

如何编辑pdf文件内容&#xff1f;在数字化办公日益普及的今天&#xff0c;PDF文件因其跨平台、格式稳定的特点&#xff0c;成为我们日常工作和学习中不可或缺的一部分。然而&#xff0c;PDF文件的编辑却常常令人头疼&#xff0c;许多人面对需要修改内容的PDF文件时感到无从下手…

【RPG Maker MV 仿新仙剑 战斗场景UI (九)】

RPG Maker MV 仿新仙剑 战斗场景UI 九 前言角色战斗精灵精灵图设置攻击 战斗背景图 前言 前段天研究并完成了主角人物行走图部分的开发&#xff0c;完成了对应的8方向行走&#xff0c;及精灵的展示。现在开始重新回到战斗场景的开发中&#xff0c;回顾下&#xff0c;已完成功能…

如何手动批准内核扩展 Tuxera NTFS for mac内核扩展需要批准 内核扩展怎么打开

在了解如何手动批准内核扩展之前&#xff0c;我们应该先了解什么叫做内核扩展。内核扩展又被称为KEXT&#xff0c;通过它可以实现macOS系统与软件组件之间的交互&#xff0c;例如磁盘管理、任务管理和内存管理等等。 kext 是内核扩展&#xff08;Kernel Extension&#xff09;…

【漏洞复现】海康威视综合安防管理平台 orgManage/v1/orgs/download 任意文件读取漏洞复现

0x01 产品简介 海康威视综合安防管理平台是一套“集成化”、“智能化”的平台,通过接入视频监控、一卡通、停车场、报警检测等系统的设备。海康威视集成化综合管理软件平台,可以对接入的视频监控点集中管理,实现统一部署、统一配置、统一管理和统一调度。 0x02 漏洞概述 海康…

C语言:学生成绩管理系统(含源代码)

一.功能 二.源代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NUM 100 typedef struct {char no[30];char name[10];char sex[10];char phone[20];float cyuyan;float computer;float datastruct; } *student, student1;typ…

渗透测试报告生成工具

目录 1.前言 1.1 渗透测试报告是什么? 1.2 渗透测试报告的编写需要考虑以下几点&#xff1a; 1.3 一份优秀的渗透测试报告应该具备以下特点&#xff1a; 1.4 在编写渗透测试报告之前&#xff0c;需要进行一些准备工作&#xff1a; 1.5 渗透测试报告一般包括以下部分&…

作为表达式调用时,无法解析类修饰器的签名。vue3+ts+vite,使用装饰器时报错

作为表达式调用时&#xff0c;无法解析类修饰器的签名。 The runtime will invoke the decorator with 2 arguments, but the decorator expects 1.ts(1238) 页面也无法打开 解决方案&#xff1a; {"extends": "vue/tsconfig/tsconfig.dom.json","in…

代码随想录算法训练营Day55 | 583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇

代码随想录算法训练营Day55 | 583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇 LeetCode 583. 两个字符串的删除操作 题目链接&#xff1a;LeetCode 583. 两个字符串的删除操作 思路&#xff1a; 分别删除 class Solution { public:int minDistance(string word1, …

SEW交频器 MDX61801110-5A3-4-0T可议价

SEW交频器 MDX61801110-5A3-4-0T可议价 SEW交频器 MDX61801110-5A3-4-0T可议价 SEW交频器 MDX61801110-5A3-4-0T可议价 SEW交频器 MDX61801110-5A3-4-0T参数表 SEW交频器 MDX61801110-5A3-4-0T中文说明书 SEW交频器 MDX61B01110-5A3-4-0T 规格:MOVIDRIVE MDX61B0110-5A3…

【MySQL】探索 MySQL 中的 NVL:使用 IFNULL 和 COALESCE 实现

缘分让我们相遇乱世以外 命运却要我们危难中相爱 也许未来遥远在光年之外 我愿守候未知里为你等待 我没想到为了你我能疯狂到 山崩海啸没有你根本不想逃 我的大脑为了你已经疯狂到 脉搏心跳没有你根本不重要 &#x1f3b5; 邓紫棋《光年之外》 什么是 NVL…

PyTorch使用tensorboard的SummaryWriter报错

PyTorch使用tensorboard可以显示网络运行情况,但偶尔使用SummaryWriter时遇到Segmentation fault错误。 利用python3的faulthandler,可定位到出错的代码行,具体操作有两种方式如下: (1) 在代码中写入faulthandler import faulthandler # 在import之后直接添加以下启用代码…

探索数据结构:便捷的双向链表

&#x1f511;&#x1f511;博客主页&#xff1a;阿客不是客 &#x1f353;&#x1f353;系列专栏&#xff1a;渐入佳境之数据结构与算法 欢迎来到泊舟小课堂 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ​​ 前言 前面我们学习了单链表&#xff0c;它解…

k8s常用命令(持续更新中)

1. 常用命令 # 查看命名空间下的所有pod kubectl get pod -n 命名空间 # 查看某命名空间下某个pod的日志 kubectl logs -f -n 命名空间 pod名# 查看某命名空间下某pod的详细信息 kubectl describe pod pod名 -n 命名空间# 查看所有命名空间下pod kubectl pods --all-namespac…

等保测评核心对象概览及实施要点

等保测评的对象主要包括以下几个方面&#xff1a; 1. 信息系统&#xff1a;由计算机硬件、网络和通信设备、计算机软件、信息资源、信息用户和规章制度组成的以处理信息流为目的的人机一体化系统。常见的信息系统包括办公自动化系统(OA)、客户关系管理系统、进销存管理系统等。…

ICLR24大模型提示(3/11) | PromptAgent:利用语言模型进行战略规划,实现专家级提示优化

【摘要】高效的、针对特定任务的提示通常由专家精心设计&#xff0c;以整合详细的说明和领域见解&#xff0c;这些见解基于对大型语言模型 (LLM) 的本能和目标任务的复杂性的深刻理解。然而&#xff0c;自动生成这种专家级提示仍然难以实现。现有的提示优化方法往往忽视领域知识…

20240603每日AI------------项目引入Spring Cloud Alibaba AI (二)

项目源码解析 前端代码&#xff1a; <div class"container"><h1>Spring Cloud Alibaba AI Example</h1><form id"form"><label for"message">User Message&#xff1a;</label><input type"text&q…

大模型PEFT(一)之推理实践学习记录

1. 简介 多种模型: LLaMA、Mistral、Mixtral-MoE、Qwen、Yi、Gemmha、Baichuan、ChatGLM、Phi等等。集成方法:(增量)预训练、指令监督微调、奖励模型训练、PPO训练和DPO训练。多种精度:32比特全参数微调、16比特冻结微调、16比特LORA微调和基于AQLM/AWQ/GPTQ/LLM.int8 的2/4/8…

一篇文章掌握Java的80%:面向对象与并发编程

Java作为一种广泛使用的计算机编程语言&#xff0c;其强大之处在于其面向对象的特性和对并发编程的良好支持。作为一名程序员&#xff0c;我深知掌握Java的面向对象概念、集合框架、多线程与并发编程&#xff0c;以及JVM基础对于编写高效、可维护的代码至关重要。本文将引导你快…

操作字符串获取文件名字(包含类型)

记录一种操作字符串获取文件名字的操作方式&#xff0c;方便后期的使用。示例&#xff1a; 输入&#xff1a;"D:/code/Test/Test.txt" 输出&#xff1a;"Test.txt" 设计思路&#xff1a; 首先查找路径中最后一个”/“&#xff0c;然后再通过字符串截取的…

湖南源点调研 为什么中小企业产品上市前一定要做市场调研?

本文由湖南长沙&#xff08;产品前测&#xff09;源点调研咨询编辑发布 可能有很多企业主会表示&#xff0c;市场调研&#xff0c;产品调研&#xff0c;不都是大公司、大品牌、上市公司才会有的流程吗&#xff0c;像我们这种小企业、小品牌、小厂家没有必要去那么做&#xff0…