• 基于STM32单片机温度水位-proteus仿真-源程序


    一、系统方案
    1、本设计采用STM32单片机作为主控器。
    2、DS18B20采集温度值送到液晶1602显示。
    3、水位传感器采集水位,送到液晶1602显示。
    4、按键设置温度和水位上下限,低于下限或高于上限,对应继电器执行操作。
    在这里插入图片描述

    二、硬件设计
    原理图如下:
    在这里插入图片描述

    三、单片机软件设计
    1、首先是系统初始化

    u8 i;
    u16 adcx;
    u16 adc;

    InitGPIO();
    LcdInit();
    Adc_Init();
    LcdWriteCom(0x80);  //设置数据指针起点
    
    
    KEY_Init();
    LED_Init();
    DHT11_Init();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、液晶显示程序
    /*******************************************************************************

    • 函 数 名 : LcdWriteCom
    • 函数功能 : 向LCD写入一个字节的命令
    • 输 入 : com
    • 输 出 : 无
      /
      void LcdWriteCom(uchar com) //写入命令
      {
      // LCD1602_E = 0; //使能
      GPIO_ResetBits(GPIOB,GPIO_Pin_3);
      // LCD1602_RS = 0; //选择发送命令
      GPIO_ResetBits(GPIOB,GPIO_Pin_1);
      // LCD1602_RW = 0; //选择写入
      GPIO_ResetBits(GPIOB,GPIO_Pin_2);
      // LCD1602_DATAPINS = com; //放入命令
      GPIO_Write(GPIOC,0X00FF&com);
      Lcd1602_Delay1ms(1); //等待数据稳定
      // LCD1602_E = 1; //写入时序
      GPIO_SetBits(GPIOB,GPIO_Pin_3);
      Lcd1602_Delay1ms(5); //保持时间
      // LCD1602_E = 0;
      GPIO_ResetBits(GPIOB,GPIO_Pin_3);
      }
      /
    • 函 数 名 : LcdWriteData
    • 函数功能 : 向LCD写入一个字节的数据
    • 输 入 : dat
    • 输 出 : 无
      *******************************************************************************/
      void LcdWriteData(uchar dat) //写入数据
      {
      // LCD1602_E = 0; //使能清零
      GPIO_ResetBits(GPIOB,GPIO_Pin_3);
      // LCD1602_RS = 1; //选择输入数据
      GPIO_SetBits(GPIOB,GPIO_Pin_1);
      // LCD1602_RW = 0; //选择写入
      GPIO_ResetBits(GPIOB,GPIO_Pin_2);
      // LCD1602_DATAPINS = dat; //写入数据
      GPIO_Write(GPIOC,0X00FF&dat);
      Lcd1602_Delay1ms(1);

    // LCD1602_E = 1; //写入时序
    GPIO_SetBits(GPIOB,GPIO_Pin_3);
    Lcd1602_Delay1ms(5); //保持时间
    // LCD1602_E = 0;
    GPIO_ResetBits(GPIOB,GPIO_Pin_3);
    }
    /*******************************************************************************

    • 函 数 名 : LcdInit()

    • 函数功能 : 初始化LCD屏

    • 输 入 : 无

    • 输 出 : 无
      *******************************************************************************/
      void LcdInit() //LCD初始化子程序
      {
      LcdWriteCom(0x38); //开显示
      LcdWriteCom(0x0c); //开显示不显示光标
      LcdWriteCom(0x06); //写一个指针加1
      LcdWriteCom(0x01); //清屏
      // LcdWriteCom(0x80); //设置数据指针起点
      }
      3、按键程序
      void KEY_Scan(void)
      {

      if(KEY40) //读取K1按键状态
      {
      Delay(10);
      if(KEY4
      0)
      {
      while(KEY4==0);
      LcdInit();
      mode++;
      if(mode>4) mode=0;

        	}
        }
        if(KEY5==0)			//读取K2按键状态
        {
        	 Delay(10);
        	if(KEY5==0)
        	{
        		while(KEY5==0);
        		if(mode==1)
        		{
        			wendu++;
        			if(wendu>50) wendu=50;
        			
        		}
        		if(mode==2)
        		{
        			shidu++;
        			if(shidu>50) wendu=50;
        		}
        		if(mode==3)
        		{
        			dy=dy+1;
        			if(dy>100)dy=100;
        		}
          	if(mode==4)
        		{
        			dl=dl+1;
        			if(dl>100)dy=100;
        		}
        }
        }
          if(KEY6==0)			//读取K3按键状态
        {
        	 Delay(10);
        	if(KEY6==0)
        	{
        		while(KEY6==0);
        	if(mode==1)
        		{
        		
        			if(wendu>0) wendu--;
        			
        		}
        		if(mode==2)
        		{
        			
        			if(shidu>0) shidu--;
        		}
        		if(mode==3)
        		{
        			
        			if(dy>0)dy=dy-1;
        		}
          	if(mode==4)
        		{
        			
        			if(dl>0)dl=dl-1;
        		}
        	}
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60

    }
    4、核心算法程序
    //从DHT11读取一个字节

    //返回值:读到的数据

    u8 DHT11_Read_Byte(void)

    {

    u8 i,dat;
    
    dat=0;
    
    • 1
    • 2
    • 3

    for (i=0;i<8;i++)

    {

    dat<<=1;

    dat|=DHT11_Read_Bit();
    
    }    
    
    return dat;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    }

    //从DHT11读取一次数据

    //temp:温度值(范围:0~50°)

    //humi:湿度值(范围:20%~90%)

    //返回值:0,正常;1,读取失败

    u8 DHT11_Read_Data(u8 *temp,u8 *humi)

    {

    u8 buf[5];

    u8 i;

    DHT11_Rst();

    if(DHT11_Check()==0)
    {
    
    	for(i=0;i<5;i++)//读取40位数据
    	{
    
    		buf[i]=DHT11_Read_Byte();
    	}
    	if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
    	{
    
    		*humi=buf[0];
    
    		*temp=buf[2];
    	}
    	
    }
    else return 1;
    	
    return 0;    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    }

    //初始化DHT11的IO口 DQ 同时检测DHT11的存在

    //返回1:不存在

    //返回0:存在

    void DHT11_Init(void)

    {

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    DHT11_Rst(); //复位DHT11

    DHT11_Check();//等待DHT11的回应

    }

    uint8_t DHT_ByteRead(unsigned char dat)
    { unsigned char temp=0;
    unsigned char x,y;
    unsigned char m=0;
    unsigned char n=0;
    unsigned char mask=0x01;
    unsigned char sum=0;
    DHT11_IO_IN() ;
    for(y=0;y<5;y++)
    {
    for(mask=0x80;mask!=0;mask>>=1)
    {
    while(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0&&m<200)m++;
    delay(30);
    if(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)
    temp|=mask;
    else
    temp&=(~mask);
    while(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)1&&n<200)n++;
    }
    (dat+y)=temp;
    temp=0;
    }
    for(x=0;x<4;x++)
    sum+=
    (dat+x);
    if((sum&=0xff)
    (dat+4))
    return 1;
    else
    return 0;
    }
    四、 proteus仿真设计
    Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。

    在这里插入图片描述

  • 相关阅读:
    浏览器不能访问阿里云ECS
    ESP8266-Arduino编程实例-MQ3酒精传感器驱动
    vscode python run code 中文乱码
    【项目_01】搭建项目基本框架、底部tabbar、头部banner | 旅途拾景 | 基于Vue3全家桶
    三菱PLC slmp(mc)协议
    Go语言:通过TDD测试驱动开发学习 Mocking (模拟)的思想
    这3个高级前端常用的API,有你正在用的吗?
    Linux开发工具 - vim篇
    IP6826无线充电底座方案IC芯片,兼容WPC Qi v1.2.4
    Apache Commons FileUpload框架的简介说明
  • 原文地址:https://blog.csdn.net/bbxyliyang/article/details/132905767