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);
}
这里展示部分代码,水平有限,仅供参考