基于STM32F103RCT6的接收ds18620温度传感器数据通过串口传回电脑

        本项目通过STM32MINI板去获取ds18620温度传感器的温度数据,再通过串口将温度数据传输给电脑。

一、ds18620温度传感器:

1.介绍:

        DS18B20 是由 Dallas Semiconductor(现 Maxim Integrated)推出的数字温度传感器,采用 1-Wire 总线协议,仅需单根数据线即可通信,支持多点组网,广泛用于嵌入式系统和物联网设备。

补充:1-Wire 总线是一种由 Dallas Semiconductor(现 Maxim Integrated)设计的 单线通信协议,以极简的硬件成本实现双向数据传输,广泛应用于传感器、存储器等低带宽设备。

2.技术特性

①独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。
② 测温范围 -55℃~+125℃,精度为±0.5℃。
③支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。
④ 工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。
⑤ 在使用中不需要任何外围元件。
⑥ 测量结果以9~12位数字量方式串行传送。

3.硬件连接:

4.读取温度的过程:

        复位发SKIP ROM命令(0XCC)——》发开始转换命令(0X44)——》延时——》复位——》发送SKIP ROM命令(0XCC)——》发读存储器命令(0XBE)——》连续读出两个字节数据(即温度)——》结束。

二、程序部分

1.ds18620驱动与头文件:

ds18620.c:

#include "ds18b20.h"
#include "Delay.h"					 		   
//Mini STM32开发板
//DS18B20 驱动函数 
//正点原子@ALIENTEK
//2010/6/17	 

//复位DS18B20
void DS18B20_Rst(void)	   
	{                 
	DS18B20_IO_OUT(); //SET PA0 OUTPUT
	Clr_DS18B20_DQ_OUT; //拉低DQ
	Delay_us(750);    //拉低750us
	Set_DS18B20_DQ_OUT; //DQ=1 
	Delay_us(15);     //15US
	}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
	{   
	u8 retry=0;
	DS18B20_IO_IN();//SET PA0 INPUT	 
	while (DS18B20_DQ_IN&&retry<200)
		{
		retry++;
		Delay_us(1);
		};	 
	if(retry>=200)return 1;
	else retry=0;
	while (!DS18B20_DQ_IN&&retry<240)
		{
		retry++;
		Delay_us(1);
		};
	if(retry>=240)return 1;	    
	return 0;
	}
	
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 			 // read one bit
	{
	u8 data;
	DS18B20_IO_OUT();//SET PA0 OUTPUT
	Clr_DS18B20_DQ_OUT; 
	Delay_us(2);
	Set_DS18B20_DQ_OUT; 
	DS18B20_IO_IN();//SET PA0 INPUT
	Delay_us(12);
	if(DS18B20_DQ_IN)data=1;
	else data=0;	 
	Delay_us(50);           
	return data;
	}
	
	
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
	{        
	u8 i,j,dat;
	dat=0;
	for (i=1;i<=8;i++) 
		{
		j=DS18B20_Read_Bit();
		dat=(j<<7)|(dat>>1);
		}						    
	return dat;
	}
	
	
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
	{             
	u8 j;
	u8 testb;
	DS18B20_IO_OUT();//SET PA0 OUTPUT;
	for (j=1;j<=8;j++) 
		{
		testb=dat&0x01;
		dat=dat>>1;
		if (testb) 
			{
			Clr_DS18B20_DQ_OUT;// Write 1
			Delay_us(2);                            
			Set_DS18B20_DQ_OUT;
			Delay_us(60);             
			}
		else 
			{
			Clr_DS18B20_DQ_OUT;// Write 0
			Delay_us(60);             
			Set_DS18B20_DQ_OUT;
			Delay_us(2);                          
			}
		}
	}
	
	
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
	{   						               
	DS18B20_Rst();	   
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);// skip rom
	DS18B20_Write_Byte(0x44);// convert
	} 
	
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
	{
	GPIO_InitTypeDef GPIO_InitStructure;	//GPIO
	//RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA, ENABLE );	 //使能PORTA口时钟  
	//GPIOA->CRL&=0XFFFFFFF0;//PORTA.0 推挽输出
	//GPIOA->CRL|=0X00000003;
	//GPIOA->ODR|=1<<0;      //输出1
	/* Configure PA0 */
	GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_OUT_PIN;  //SPI CS
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DS18B20_DQ_OUT_PORT, &GPIO_InitStructure);
	/* Deselect the PA0 Select high */
	GPIO_SetBits(DS18B20_DQ_OUT_PORT,DS18B20_DQ_OUT_PIN);
	DS18B20_Rst();
	return DS18B20_Check();
	}  
	
	
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
	short DS18B20_Get_Temp(void) {
    u8 TL, TH;
    short tem;
    DS18B20_Rst();
    if (DS18B20_Check()) return 9999; // 检测失败
    DS18B20_Write_Byte(0xCC);        // 跳过ROM
    DS18B20_Write_Byte(0xBE);        // 读取暂存器
    TL = DS18B20_Read_Byte();        // 低字节
    TH = DS18B20_Read_Byte();        // 高字节

    // 判断是否为负温度(最高位为1)
    if (TH & 0x80) {
        // 补码转换:取反后加1
        tem = (TH << 8) | TL;
        tem = ~tem + 1;
        tem = -tem; // 转换为负数
    } else {
        tem = (TH << 8) | TL; // 正温度直接组合
    }
    
    // 计算实际温度(12位分辨率,0.0625/bit,放大10倍返回)
    tem = tem * 0.0625 * 10; // 示例:25.6℃返回256
    return tem;
}
#ifndef __DS18B20_H
#define __DS18B20_H 
#include "stm32f10x.h"  
//Mini STM32开发板
//DS18B20 驱动函数 

//IO方向设置
#define DS18B20_IO_IN()  {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;}
#define DS18B20_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;}
IO操作函数											   
//#define	DS18B20_DQ_OUT PAout(0) //数据端口	PA0 
#define DS18B20_DQ_OUT_PORT              GPIOA
#define DS18B20_DQ_OUT_CLK               RCC_APB2Periph_GPIOA  
#define DS18B20_DQ_OUT_PIN               GPIO_Pin_0
#define Set_DS18B20_DQ_OUT  {GPIO_SetBits(DS18B20_DQ_OUT_PORT,DS18B20_DQ_OUT_PIN);}
#define Clr_DS18B20_DQ_OUT  {GPIO_ResetBits(DS18B20_DQ_OUT_PORT,DS18B20_DQ_OUT_PIN);} 


//#define	DS18B20_DQ_IN  PAin(0)  //数据端口	PA0
#define DS18B20_DQ_IN_PORT              GPIOA
#define DS18B20_DQ_IN_CLK               RCC_APB2Periph_GPIOA  
#define DS18B20_DQ_IN_PIN               GPIO_Pin_0 
#define DS18B20_DQ_IN  (GPIO_ReadInputDataBit(DS18B20_DQ_IN_PORT, DS18B20_DQ_IN_PIN))
   	
u8 DS18B20_Init(void);//初始化DS18B20
short DS18B20_Get_Temp(void);//获取温度
void DS18B20_Start(void);//开始温度转换
void DS18B20_Write_Byte(u8 dat);//写入一个字节
u8 DS18B20_Read_Byte(void);//读出一个字节
u8 DS18B20_Read_Bit(void);//读出一个位
u8 DS18B20_Check(void);//检测是否存在DS18B20
void DS18B20_Rst(void);//复位DS18B20    
#endif















2、main.c

#include "stm32f10x.h"
#include "GPIO.H"
#include "Delay.h"
#include "ds18b20.h"
#include "Serial.h"
#include <stdio.h>  // 添加stdio.h用于sprintf

int main(void) {
    gpio_init();     // 初始化GPIO(包含串口GPIO配置)
    Serial_Init();   // 显式初始化串口(确保波特率、中断等配置正确)
    short temperature;
    
    if (DS18B20_Init() == 0) { 
        while(1) {
            DS18B20_Start();    // 启动温度转换
            Delay_ms(750);      // 等待转换完成
            temperature = DS18B20_Get_Temp();
            
            // 发送温度字符串
            char buffer[32];
            sprintf(buffer, "Temp: %d\r\n", temperature);
            Serial_SendString(buffer);
            
            if (temperature >= 250) { 
                GPIO_WriteBit(GPIOA, GPIO_Pin_8, 0); // 报警
            } else {
                GPIO_WriteBit(GPIOA, GPIO_Pin_8, 1); // 关闭报警
            }
            Delay_s(1); 
        }
    } else { 
        while(1) { 
            GPIO_WriteBit(GPIOA, GPIO_Pin_8, 0);
            Delay_ms(500);
            GPIO_WriteBit(GPIOA, GPIO_Pin_8, 1);
            Delay_ms(500);
            Serial_SendString("Sensor Error!\r\n"); // 明确错误信息
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值