找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1827|回复: 0
收起左侧

STM32单片机wifi云平台+温度+烟雾+火焰+短信+蜂鸣器 源程序原理图

  [复制链接]
ID:316613 发表于 2023-5-15 14:45 | 显示全部楼层 |阅读模式
没有仿真,但是程序跑实物运行了,可以借鉴部分代码测试哦,附带原理图

1.     整体设计
设计由stm32f103c8t6单片机为控制核心

2.     液晶显示
单片机通过iic接口(pa6、pa7)与oled12864的液晶显示屏(scl、sda)连接,驱动液晶数据和阈值。

3.     Ds18b20温度传感器
Ds18b20温度传感器是单总线接口,把数据端接到单片机的pb9管脚,通过传感器协议读取温度值。


4.     Mq2烟雾传感器
Mq2传感器输出模电压会随着烟雾浓度的增大而增大。单片机通过模拟量采集管脚PA0采集mq2传感器输出的电压值,然后单片机通过计算把0-vcc电压转化成0-100%烟雾浓度。


5.     火焰传感器传感器
火焰传感器是数字量do输出,当检测到有明火时输出低电平0,无明火时输出高电平1。单片机通过io口pa6读取火焰传感器状态。


6.     蜂鸣器驱动控制
如果蜂鸣器接电源3.3v和地,蜂鸣器有电就会发声。1k电阻是限流电阻。单片机通过控制pa7管脚输出高低电平,从而达到控制风扇转动的效果。单片机输出高电平1时,三极管导通,蜂鸣器接地,蜂鸣器响。输出低电平0时,三极管截至不导通,蜂鸣器没有接地,蜂鸣器不响。


7.     按键
单片机io口接按键,按键按下的接地。Io口读取到低电平0,按键松开时,由于单片机有内置上拉电阻,Io口读取到高电平1。其他两个按键原理一样。

8.     Gsm短信模块
Sim900a gsm短信模块是通过串口通讯的,将单片机串口1发送端pa9接到gsm模块的接收端rxd,然后单片机通过at指令控制gsm模块发送短信。

9.     Esp8266wifi模块
8266是串口控制得模块,单片机通过串口1(pa9和pa10)与wifi模块通讯,从而控制wifi模块工作。首先wifi模块上电自动连接热点,然后连接onenet云平台得ip地址,通过mqtt协议登录云平台设备,订阅app(订阅了才能接收到app下发得信息)。单片机会定时上传数据(以mcu得身份发布数据)到onenet云平台,在app订阅了mcu设备得前提下,云平台接收到单片机上传得数据后会自动转发到app显示。反之app下发数据过程也一样。

单片机源程序如下:
  1. #include "stm32f10x.h" //头文件
  2. #include "./usart/bsp_usart1.h"
  3. #include "./OLED_I2C/OLED_I2C.h"
  4. #include "./delay/delay.h"
  5. #include "adc.h"
  6. #include "string.h"
  7. #include "bsp_ds18b20.h"
  8. #include "./TIMER/timer.h"



  9. #define  Speaker   PAout(7)//pa7接蜂鸣器


  10. #define   Key1         PBin(12)//按键
  11. #define   Key2         PBin(13)//按键
  12. #define   Key3         PBin(14)//按键
  13. #define   HY         PAin(6)//火焰传感器

  14. TIM_TimeBaseInitTypeDef  TIM3_TimeBaseStructure;  
  15. TIM_OCInitTypeDef  TIM3_OCInitStructure;

  16. void DelayStm32(__IO u32 nCount)
  17. {
  18.   for(; nCount != 0; nCount--);
  19. }
  20. u16 Time_1MS=0;
  21. u16 TX_10MS=0;
  22. u16 A0Value = 0; //烟雾值
  23. u16 Ds18b20Value; //温度
  24. u16 Cnt=0;
  25. u8 AlarmT=35; //温度阈值
  26. u8 AlarmM=60; //烟雾阈值

  27. char dispBuff[10];

  28. u8 FlagUpData = 0;
  29. u8 FlagFS = 0;       //风扇手动标志位
  30. u8 FlagDelayA = 0;  //继电器手动标志位
  31. u8 StateDelayA = 0; //继电器状态
  32. u8 StateFS = 0;     //风扇状态

  33. u8  Stm32[17];
  34. u16 KeyCnt = 0;
  35. u8 FlagSet=0; //按键设置标志位
  36. u8 FlagAlarm=0; //告警标志位
  37. u8 RxBuf1[32];
  38. u8 RxBuf2[32];
  39. u8 RxBuf3[32];  //串口3数据缓存
  40. u8 pass[11];

  41. /**********************MQTTdata***********************/
  42. char MqttDataDL[37]=
  43. {         
  44.         0x10, 0x23, 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54, 0x04, 0xC0,
  45.         0x00, 0x78, 0x00, 0x0A, 0x31, 0x30, 0x36, 0x35, 0x36, 0x30,
  46.         0x31, 0x35, 0x35, 0x39, 0x00, 0x06, 0x35, 0x38, 0x39, 0x35,
  47.         0x35, 0x34, 0x00, 0x03, 0x6D, 0x63, 0x75
  48.                
  49. };//mqtt登录数组

  50. char MqttDataDY[10]=
  51. {
  52.                 0x82, 0x08, 0x00, 0x02, 0x00, 0x03, 'a', 'p', 'p', 0x00
  53. };//mqtt订阅数组

  54. char MqttDataFB[24]=
  55. {
  56.                 0x30, 0x16, 0x00, 0x03, 0x6D, 0x63, 0x75, 0x06, 0x06, 0x06,
  57.                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  58.                 0x00, 0x00, 0x00, 0x00
  59. };//mqtt发布数组

  60. void SendASC1(u8 d) //串口1发送一个字节
  61. {
  62.         USART_SendData(USART1, d);
  63.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);                                
  64. }

  65. void SendASC2(u8 d)   //串口2发送一个字节
  66. {
  67.         USART_SendData(USART2, d);
  68.         while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);                                
  69. }

  70. void SendASC3(u8 d)
  71. {
  72.         USART_SendData(USART3, d);
  73.         while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);                                
  74. }

  75. void DengLu(void) //mqtt登录函数
  76. {
  77.                         u8 k=0;
  78.                         printf("AT+CIPSEND=37\r\n");
  79.                         DelayS(1);
  80.                         for(k=0; k<37; k++)
  81.                         {
  82.                                                 SendASC1(MqttDataDL[k]);
  83.                         }
  84. }

  85. void DingYue(void)  //mqtt订阅函数
  86. {
  87.                         u8 k=0;
  88.                         printf("AT+CIPSEND=10\r\n");
  89.                         DelayS(1);
  90.                         for(k=0; k<10; k++)
  91.                         {
  92.                                                 SendASC1(MqttDataDY[k]);
  93.                         }
  94. }

  95. void FaBu(void)  //mqtt发布函数
  96. {
  97.                         u8 k=0;
  98.                         printf("AT+CIPSEND=24\r\n");
  99.                         DelayS(1);
  100.                         for(k=0; k<24; k++)
  101.                         {
  102.                                                 SendASC1(MqttDataFB[k]);
  103.                         }
  104. }

  105. /*************************************************/





  106. void GPIO_Config(void)  //io口配置
  107. {
  108.   GPIO_InitTypeDef GPIO_InitStructure;

  109.   /* GPIOA and GPIOA clock enable */ //pb8、pb12、pb13、pb14设置为输入
  110.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);   
  111.   GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 |GPIO_Pin_12 | GPIO_Pin_13  | GPIO_Pin_14;
  112.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         
  113.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  114.   GPIO_Init(GPIOB, &GPIO_InitStructure);  
  115.         

  116.   /* GPIOA and GPIOA clock enable */ //pa6设置为输入
  117.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   
  118.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6  ;
  119.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         
  120.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  121.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  122.   
  123.         
  124.     /* GPIOA and GPIOA clock enable */  //pa7.pa4配置为推免输出
  125.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  126.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 |GPIO_Pin_7;
  127.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  128.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  129.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  130.         
  131.     /* GPIOA and GPIOA clock enable */  //pc13配置为推免输出
  132.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  133.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13;
  134.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  135.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  136.   GPIO_Init(GPIOC, &GPIO_InitStructure);
  137.                
  138. }
  139.   

  140. void DispOled(void)//液晶显示函数
  141. {
  142.                 //显示温度和阈值
  143.                 sprintf(dispBuff,"WenDu=%d%d.%dC %d%dC", Ds18b20Value %1000/100, Ds18b20Value%100/10, Ds18b20Value%10, AlarmT%100/10, AlarmT%10);  
  144.                 OLED_ShowStr(0,0,dispBuff,2);
  145.                 //显示烟雾和阈值
  146.                 sprintf(dispBuff,"YanWu = %0.2d%% %0.2d%%",A0Value,AlarmM);  
  147.                 OLED_ShowStr(0,2,dispBuff,2);
  148.           //显示接收短信的号
  149.                 sprintf(dispBuff,"%d%d%d%d%d%d%d%d%d%d%d",pass[10],pass[9],pass[8],pass[7],pass[6],pass[5],pass[4],pass[3],pass[2],pass[1],pass[0]);
  150.                 OLED_ShowStr(0,6,dispBuff,2);
  151.                                                 
  152. }


  153. void SendDx(void) //发送短信函数
  154. {
  155.         Uart3_printf("AT+CSCS=\"GSM\"\r\n");
  156.         DelayS(1);
  157.         Uart3_printf("AT+CMGF=1\r\n");
  158.         DelayS(1);
  159.         /*******************************************************/
  160.         //printf("AT+CMGS=\"18xxxxxxxx\"\r\n");
  161.         Uart3_printf("AT+CMGS=\"");   //按设置的号码发送短信
  162.         SendASC3(pass[10]+0x30);
  163.         SendASC3(pass[9]+0x30);
  164.         SendASC3(pass[8]+0x30);
  165.         SendASC3(pass[7]+0x30);  
  166.         SendASC3(pass[6]+0x30);   
  167.         SendASC3(pass[5]+0x30);
  168.         SendASC3(pass[4]+0x30);
  169.         SendASC3(pass[3]+0x30);
  170.         SendASC3(pass[2]+0x30);
  171.         SendASC3(pass[1]+0x30);
  172.         SendASC3(pass[0]+0x30);
  173.         Uart3_printf("\"\r\n");
  174.         /*******************************************************/
  175.         DelayS(1);
  176.         Uart3_printf("Have a Fire!!!"); //发送短信的内容
  177.         DelayS(1);
  178.         SendASC3(0x1A);  //启动发送短信
  179.         DelayS(1);
  180. }



  181. int main(void) //主函数
  182. {

  183.         USART1_Config();  //串口初始化
  184.         GPIO_Config();//io口初始化
  185.         Adc_Init();//ad初始化
  186.         DelayInit(); //定时函数初始化
  187.         Speaker = 0;//关闭输出设备
  188.         I2C_Configuration();//iic初始化
  189.         OLED_Init();//液晶初始化
  190.         OLED_Fill(0xFF);
  191.                 DelayS(1);
  192.                 DelayS(1);
  193.                 DelayS(1);
  194.                 DelayS(1);
  195.                 printf("AT\r\n");
  196.                 DelayS(1);
  197.                 printf("AT\r\n");
  198.                 DelayS(1);
  199.                 printf("AT\r\n");
  200.                 DelayS(1);
  201.                 printf("AT+CWMODE=3\r\n");  //8266设置为模式3
  202.                 DelayS(1);
  203.                 printf("AT+CWJAP=\"win\",\"123123123\"\r\n");  //连接热点
  204.                 DelayS(1);
  205.                 DelayS(1);
  206.                 DelayS(1);
  207.                 DelayS(1);
  208.                 DelayS(1);
  209.                 while(DS18B20_Init()); //温度初始化
  210.                 DelayS(1);
  211.                 Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10); //上电连续读取几次温度值使其稳定
  212.                 DelayStm32(0xFFFFF);
  213.                 Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
  214.                 DelayStm32(0xFFFFF);
  215.                  Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
  216.                 DelayStm32(0xFFFFF);
  217.                 Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
  218.                 DelayStm32(0xFFFFF);
  219.                 Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
  220.                 DelayStm32(0xFFFFF);
  221.                 DelayS(1);
  222.                 DelayS(1);
  223.                 DelayS(1);
  224.                 DelayS(1);
  225.                 DelayS(1);
  226.                 DelayS(1);
  227.                 /*******************************************************/
  228.                 printf("AT+CIPSTART=\"TCP\",\"183.230.x.x\",6002\r\n");  //连接云平台ip和端口号
  229.                 /*******************************************************/
  230.                 DelayS(1);
  231.                 DelayS(1);
  232.                 DelayS(1);
  233.                 DelayS(1);
  234.                 DelayS(1);
  235.                 DelayS(1);
  236.                 DengLu();   //调用mqtt登录函数
  237.                 DelayS(1);
  238.                 DelayS(1);
  239.                 DelayS(1);
  240.                 DingYue();   //调用mqtt订阅函数
  241.                 DelayStm32(0xFFFFF);
  242.                 OLED_Fill(0x00);
  243.                 DelayStm32(0xFFFFF);
  244.                 TIM4_Int_Init(9,7199); //定时器初始化
  245.         while(1)
  246.         {

  247.                 Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);//读取稳定
  248.                 A0Value = (Get_Adc_Average(0,20)*100/4096);//读取烟雾
  249.                 DispOled(); //调用显示函数

  250.                                         MqttDataFB[10] = Ds18b20Value/100;  //把要上传得数据填进mqtt发布数据
  251.                                         MqttDataFB[11] = Ds18b20Value%100/10;
  252.                                         MqttDataFB[12] = Ds18b20Value%10;
  253.                                         MqttDataFB[13] = A0Value;
  254.                                         MqttDataFB[14] = 0;
  255.                                         MqttDataFB[15] = 0;
  256.                                         MqttDataFB[16] = FlagAlarm;
  257.                
  258.                                         if(FlagUpData==1)  //上传数据时间到,上传数据
  259.                                         {
  260.                                                                 FlagUpData = 0;
  261.                                                                 FaBu();  //发布数据
  262.                                         }        
  263.                                 
  264.                
  265.                 if( (Ds18b20Value>(AlarmT*10))||(A0Value>AlarmM)||(HY) ) //如果温度或者烟雾大于阈值或者有火焰
  266.                 {
  267.                                 Speaker = 1; //蜂鸣器响
  268.                                 if(FlagAlarm==0) //每个告警值发送一次短信
  269.                                 {
  270.                                                 SendDx(); //调用发送短信函数
  271.                                 }
  272.                                 FlagAlarm = 1;
  273.                 }
  274.                 else
  275.                 {
  276.                                 FlagAlarm = 0;
  277.                                 Speaker = 0;
  278.                 }
  279.                
  280.                
  281.                         if(!Key1) //按键1
  282.                 {
  283.                                 while(!Key1);
  284.                                                 pass[0]++;
  285.                                                         if(pass[0]>=10) pass[0]=0;
  286.                 }
  287.                
  288.                 if(!Key2)//按键2
  289.                 {
  290.                                 while(!Key2);
  291.                                                 pass[10] = pass[9];
  292.                                                         pass[9] = pass[8];
  293.                                                         pass[8] = pass[7];
  294.                                                         pass[7] = pass[6];
  295.                                                         pass[6] = pass[5];
  296.                                                         pass[5] = pass[4];
  297.                                                         pass[4] = pass[3];
  298.                                                         pass[3] = pass[2];
  299.                                                         pass[2] = pass[1];
  300.                                                         pass[1] = pass[0];
  301.                                                         pass[0] = 0;
  302.                                 
  303.                 }        
  304.                
  305.                         

  306. /**************************************************************************************/
  307. /**************************************************************************************/
  308.         }                        
  309. }

  310. void TIM4_IRQHandler(void) //定时中断每1ms中断一次
  311. {         
  312.         if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//?????
  313.         {                                    
  314.                                 TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //??TIM4??????  
  315.                                 
  316.                                 TX_10MS++;
  317.                                 if(TX_10MS>=5000)
  318.                                 {
  319.                                                 TX_10MS = 0;
  320.                                                 FlagUpData = 1;
  321.                                 }        
  322.                  

  323.                
  324.                                                 
  325.                                 
  326.                                 

  327.         }            
  328. }

  329. void USART1_IRQHandler(void)
  330. {
  331.           uint8_t ucTemp;
  332.         if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
  333.         {        
  334.                 ucTemp = USART_ReceiveData(USART1);
  335.                 RxBuf1[0] = RxBuf1[1];
  336.                 RxBuf1[1] = RxBuf1[2];
  337.                 RxBuf1[2] = RxBuf1[3];
  338.                 RxBuf1[3] = ucTemp;
  339.                                 if( (RxBuf1[0]=='F')&&(RxBuf1[1]=='t') )  //Ftxx 设置温度阈值
  340.                                         {
  341.                                                         AlarmT = (RxBuf1[2]-0x30)*10 + (RxBuf1[3]-0x30);
  342.                                         }
  343.                                         else if( (RxBuf1[0]=='F')&&(RxBuf1[1]=='m') )  //Fmxx  设置烟雾阈值
  344.                                         {
  345.                                                         AlarmM = (RxBuf1[2]-0x30)*10 + (RxBuf1[3]-0x30);
  346.                                         }
  347.         }         
  348. }

  349. void USART2_IRQHandler(void)
  350. {
  351.           uint8_t ucTemp2;
  352.         if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
  353.         {        
  354.                         ucTemp2= USART_ReceiveData(USART2);
  355.                         RxBuf2[0] = RxBuf2[1];
  356.                         RxBuf2[1] = RxBuf2[2];
  357.                         RxBuf2[2] = RxBuf2[3];
  358.                         RxBuf2[3] = ucTemp2;
  359.                         if( (RxBuf2[0]=='F')&&(RxBuf2[1]=='T') )
  360.                         {        

  361.                         }

  362.         
  363.         }         
  364. }

  365. void USART3_IRQHandler(void)
  366. {
  367.           uint8_t ucTemp3;
  368.         if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
  369.         {        
  370.                                 ucTemp3= USART_ReceiveData(USART3);
  371.                                 RxBuf3[0] = RxBuf3[1];
  372.                                 RxBuf3[1] = RxBuf3[2];
  373.                                 RxBuf3[2] = RxBuf3[3];
  374.                                 RxBuf3[3] = ucTemp3;


  375.                 }

  376.                                 

  377. }
复制代码

所有资料51hei附件下载:
Keil代码原理图.7z (2.73 MB, 下载次数: 217)
51hei截图_20230515144420.png

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表