基于stm32f103c8t6的电子温度计(0.96寸oled显示温度,测温用的是ds18b20传感器,可以设置温度范围,超出范围报警)小白学习记录

1.电路图 

2.实物图

 

3.材料简单:stm32f103c8t6一个,0.96寸oled显示屏一个,ds18b20一个,四个按键,一个蜂鸣器,usb转ttl一个(烧录用),还有面包板,杜邦线这些。

4.下面是程序:

main.c文件如下:

#include "stm32f10x.h" 
#include "oled.h"
#include "bmp.h"
#include "delay.h"
#include "anjian.h"
#include "led.h"
#include "ds18b20.h"
#include "baojing.h"

int main()
{             

        delay_init();         //初始化
        OLED_Init();                    
        Anjian_Init();               
        LedInit();                      
        FengmingqiInit();            

        while(1)
        {
        OLED_Display();                   //显示不变的部分,如“温度:"                
        datapros(Ds18b20ReadTemp());      //获取温度数据并处理
        Anjian_Check();                                 //按键检查
        Anjian_Pros();                                 //按键处理
        Anjian_xianshi();                             //显示温度  
        LedShan();                                      //让stm32f103c8t6板子上的led闪烁
        } 
}

 ds18b20.c文件如下

#include "DS18B20.h"
#include "oled.h"
#include "delay.h"

double temperaturezhi;
//初始化ds18b20
unsigned char Ds18b20Init()
{
    unsigned char i=0;                    

    DS18B20_IO_OUT();                    
    DS18B20_DQ_OUT=0;                 //将总线拉低
    delay_us(640);                              //延时640us

    DS18B20_DQ_OUT=1;                //总线拉高    
    DS18B20_IO_IN();
    while(DS18B20_DQ_IN)            //等待ds18b20拉低总线
    {
    delay_ms(1);
        i++;
        if(i>5)                                    
        {
            return 0;                            //初始化失败
        }
        
    }
    return 1;                                    //初始化成功
}
//向18b20写入一个字节
void Ds18b20WriteByte(unsigned char dat)
{
    unsigned int j;
        DS18B20_IO_OUT();
        for(j=0;j<8;j++)
        {
            u8 testb;

            DS18B20_DQ_OUT=0;
            testb=dat&0x01;

        if (testb) 
        {
            DS18B20_DQ_OUT=0;    // 每写一位前将总线拉低1us
                        delay_us(1);                            
                        DS18B20_DQ_OUT=1;                 
        }
        else 
        {
            DS18B20_DQ_OUT=0;    // Write 0
            delay_us(1);             
            DS18B20_DQ_OUT=0;                                  
        }
                delay_us(68);                
                DS18B20_DQ_OUT=1;        
                dat=dat>>1;            
        }
}

//读取一个字节
unsigned char Ds18b20ReadByte()
{      unsigned char byte, bi;
        unsigned int j;
    for(j=0;j<8;j++)
    {    
            DS18B20_IO_OUT();                
            DS18B20_DQ_OUT=0;                //总线拉低1us
            delay_us(1);
      DS18B20_DQ_OUT=1;                //释放总线
            delay_us(6);                        //等待6us数据稳定
          DS18B20_IO_IN();                
            bi=DS18B20_DQ_IN;                        
            byte = (byte >> 1) | (bi << 7);         
            delay_us(48);                       
    }
    return byte;
}
//转换温度
void  Ds18b20ChangTemp()
{
        Ds18b20Init();
        delay_ms(1);
        Ds18b20WriteByte(0xcc);            
        Ds18b20WriteByte(0x44);             
        delay_ms(100);
    
}
//读温度命令
void  Ds18b20ReadTempCom()
{
    Ds18b20Init();
    delay_ms(1);
    Ds18b20WriteByte(0xcc);        
    Ds18b20WriteByte(0xbe);            
}
//读温度
int Ds18b20ReadTemp()
{
        int temp = 0;
      unsigned char tmh,tml;
        Ds18b20ChangTemp();                
        Ds18b20ReadTempCom();        
        tml = Ds18b20ReadByte();    
        tmh = Ds18b20ReadByte();    
        temp = tmh;
        temp <<= 8;
        temp |= tml;
        return temp;
}
void datapros(int temp)                 //温度数据处理
{
       float tp;  
    if(temp>=2048)                
        {
        temp=65536-temp;                        //温度是负的则变换温度
        tp=temp;
        temp=tp*0.0625*100+0.5;
        temperaturezhi=temp/100.0;

        OLED_ShowChar(48,0,'-');
      OLED_ShowNum(56,0,temp/100,3,16);
        OLED_ShowChar(80,0,'.');
       OLED_ShowNum(88,0,temp/10%100,1,16);
        OLED_ShowNum(96,0,temp%10,1,16);     
      }
     else
      {            
        tp=temp;
        temp=tp*0.0625*100+0.5;    
        temperaturezhi=temp/100.0;            
        
        OLED_ShowChar(48,0,'+');
      OLED_ShowNum(56,0,temp/100,3,16);
        OLED_ShowChar(80,0,'.');
      OLED_ShowNum(88,0,temp/10%100,1,16);
        OLED_ShowNum(96,0,temp%10,1,16);    
        }

}

//返回温度值函数

double get_temperaturezhi()
{
    return temperaturezhi;
}
 

 ds18b20.h文件

#ifndef __DS18B20_H
#define __DS18B20_H

#define DS18B20_IO_IN()  {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=8<<20;}
#define DS18B20_IO_OUT() {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=3<<20;}
                                           
#define    DS18B20_DQ_OUT PAout(5) 
#define    DS18B20_DQ_IN  PAin(5)   
unsigned char Ds18b20Init(void);
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte(void);
void  Ds18b20ChangTemp(void);
int Ds18b20ReadTemp(void);
void datapros(int temp);     
double get_temperaturezhi(void);

#endif

anjian.c文件

#include "anjian.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
#include "oled.h"
#include "ds18b20.h"
#include "baojing.h"


double shangxian=shangxianzhi;
double xiaxian=xiaxianzhi;
int intshangxian=shangxianzhi;
int intxiaxian=xiaxianzhi;

//按键初始化,按键接PB5,PB6,PB7,PB8
void Anjian_Init()
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
        GPIO_Init(GPIOB, &GPIO_InitStructure);
}

//按键检查函数

void Anjian_Check()
{
        if(Anjian_DQ_IN1==0)          //按键1按下
        {    
        delay_ms(10);                       //消抖
        if(Anjian_DQ_IN1==0)             //再次检查
        {
            shangxian=shangxian+0.5;         //此部分主要是进行温度上限范围调整+0.5
            intshangxian=shangxian*10;
            intxiaxian=xiaxian*10;}
            while(!Anjian_DQ_IN1);        //检测按键释放
        }
    
        else if(Anjian_DQ_IN2==0)          //同理,检测按键二是否按下,一共四个按键,以下都与按键一同
        {    
        delay_ms(10);                               
        if(Anjian_DQ_IN2==0)                    
        {
            shangxian=shangxian-0.5;               //温度上限范围调整-0.5
            intshangxian=shangxian*10;
            intxiaxian=xiaxian*10;}
            while(!Anjian_DQ_IN1);                
        }
            
        else if(Anjian_DQ_IN3==0)          
        {    
        delay_ms(10);                            
        if(Anjian_DQ_IN3==0)                
        {
            xiaxian=xiaxian+0.5;                        //温度下限范围调整+0.5
            intxiaxian=xiaxian*10;
            intshangxian=shangxian*10;}
            while(!Anjian_DQ_IN1);                
        }
            
        else if(Anjian_DQ_IN4==0)          
        {    
        delay_ms(10);                               
        if(Anjian_DQ_IN4==0)                   
        {
            xiaxian=xiaxian-0.5;
            intshangxian=shangxian*10;
            intxiaxian=xiaxian*10;}
            while(!Anjian_DQ_IN1);            
        }
        else 
        {
            intshangxian=shangxian*10;      
            intxiaxian=xiaxian*10;    
        }

    }        

//按键处理函数

void Anjian_Pros()
    {
            if(get_temperaturezhi()>shangxian|get_temperaturezhi()<xiaxian)  //检测当前温度是否在设置范围之内
            {
                OLED_ShowCHinese(32,6,2);            //显示”温度异常“
                OLED_ShowCHinese(48,6,3);
                OLED_ShowCHinese(64,6,9);
                OLED_ShowCHinese(80,6,10);
                FengmingqiXiang();                        //蜂鸣器响
            
            }
            else
            {    
                OLED_ShowCHinese(32,6,2);            //显示“温度正常“
                OLED_ShowCHinese(48,6,3);
                OLED_ShowCHinese(64,6,11);
                OLED_ShowCHinese(80,6,10);
                FengmingqiTing();                            //蜂鸣器不响
            }
        
        }
    
    void Anjian_xianshi()                                                    //按键显示当前上下限
    {
        if(shangxian< 0)            
       {
        OLED_ShowChar(48,2,'-');
        intshangxian=-1*intshangxian;
      OLED_ShowNum(56,2,intshangxian/10,3,16);
        OLED_ShowChar(80,2,'.');
      OLED_ShowNum(88,2,intshangxian%10,2,16);
      }
      else
      {            
        OLED_ShowChar(48,2,'+');
      OLED_ShowNum(56,2,intshangxian/10,3,16);
        OLED_ShowChar(80,2,'.');
      OLED_ShowNum(88,2,intshangxian%10,2,16);        
        }
        
      if(xiaxian< 0)        
       {
        OLED_ShowChar(48,4,'-');
        intxiaxian=intxiaxian*(-1);
      OLED_ShowNum(56,4,intxiaxian/10,3,16);
        OLED_ShowChar(80,4,'.');
      OLED_ShowNum(88,4,intxiaxian%10,2,16);
      }
       else
      {            
        OLED_ShowChar(48,4,'+');
      OLED_ShowNum(56,4,intxiaxian/10,3,16);
        OLED_ShowChar(80,4,'.');
      OLED_ShowNum(88,4,intxiaxian%10,2,16);        
      }

}

 

led.c文件

#include "led.h"
#include "stm32f10x_gpio.h"
#include "delay.h"

//让stm32自带的led闪烁,以此显示正常工作中
void LedInit()

    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void LedShan()
{
        GPIO_ResetBits(GPIOC,GPIO_Pin_13);
        delay_ms(50);        
        GPIO_SetBits(GPIOC,GPIO_Pin_13);    
        delay_ms(50);    
}
baojing.c文件

#include "baojing.h"
#include "anjian.h"
#include "delay.h"

void FengmingqiInit()        //PB9连接蜂鸣器,作为报警器
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}


void FengmingqiXiang()
{
        GPIO_ResetBits(GPIOB,GPIO_Pin_9);
        delay_ms(50);        
        GPIO_SetBits(GPIOB,GPIO_Pin_9);    
        delay_ms(50);    
}
void FengmingqiTing()
{
        GPIO_SetBits(GPIOB,GPIO_Pin_9);    

}

baojing.h文件

#ifndef __BAOJING_H
#define __BAOJING_H

#define    fengmingqi  PBin(9)

void FengmingqiInit(void);
void FengmingqiXiang(void);
void FengmingqiTing(void);

#endif
另外

 void OLED_Display()
{
        OLED_ShowCHinese(0,0,2);
        OLED_ShowCHinese(16,0,3);
        OLED_ShowCHinese(32,0,4);
        OLED_ShowCHinese(104,0,8);
    
        OLED_ShowCHinese(0,2,5);    
        OLED_ShowCHinese(16,2,7);
        OLED_ShowCHinese(32,2,4);
        OLED_ShowCHinese(104,2,8);
        
        OLED_ShowCHinese(0,4,6);
        OLED_ShowCHinese(16,4,7);
        OLED_ShowCHinese(32,4,4);    
        OLED_ShowCHinese(104,4,8);
}
这里展示部分代码,水平有限,仅供参考

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值