单片机之单总线通信DS18B20和红外遥控

1、单总线只有一根数据线,设备(主机或从机)通过一个漏极开路或三态端口,连接至该数据线,这样允许设备在不发送数据时释放数据总线,以便总线被其它设各所使用。单总线端口为漏极开路,其内部等效电路下图所示:

单总线电路外接一个约5K的上拉电阻,由于设置的单片机引脚是开漏输出,所以当单总线处于空闲状态时为高电平,如果总线保持低电平超过480us,总线上的所有器件将复位。另外,在寄生方式供电时,为了保证单总线器件在某些工作状态下(如温度转换期间、EEPROM写入等)具有足够的电源电流,必须在总线上提供强上拉。

2、配置端口为开漏输出

c 复制代码
#ifndef __DRIVER_DS18B20_H__
#define __DRIVER_DS18B20_H__
#include <stdint.h>

/*******修改这部分可更换ds18b20引脚**********/
#define DS18B20_GPIO_PORT                  GPIOC
#define DS18B20_GPIO_PIN                   GPIO_PIN_3


//单总线的复位功能:
uint8_t one_wire_reset(void);

//单总线发送一个bit的功能:
void one_wire_send1Bit(uint8_t bit);

//单总线发送一个字节的功能:
void one_wire_write1Byte(uint8_t byte);

//单总线上读取一个bit功能:
uint8_t one_wire_recv1Bit(void);

//单总线上读取一个字节的功能:
uint8_t one_wire_read1Byte(void);

//从ds18b20芯片上读取温度:
float get_DS18B20_Temp(void);
#endif
c 复制代码
#include "driver_ds18b20.h"
#include "gpio.h"
#include "tim2Udelay.h"
#include "FreeRTOS.h"
// 单总线的复位功能:
uint8_t one_wire_reset(void)
{
    // 主机主动拉低单总线电平为低电平:
    HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
    // 维持480us:
    tim2_u_delay(480);
    // 释放单总线:
    HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
    tim2_u_delay(60);

    GPIO_PinState status = HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN);
    tim2_u_delay(480);

    return status == GPIO_PIN_RESET;
}

// 单总线发送一个bit的功能:
void one_wire_send1Bit(uint8_t bit)
{
    if (bit == 1)
    {
        HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
        tim2_u_delay(2);
        HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
        tim2_u_delay(60);
    }
    else
    {
        HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
        tim2_u_delay(60);
        HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
        tim2_u_delay(2);
    }
}

// 单总线发送一个字节的功能:
void one_wire_write1Byte(uint8_t byte)
{
    for (int i = 0; i < 8; i++)
    {
        one_wire_send1Bit(byte & 0x01);
        byte = byte >> 1;
    }
}

// 单总线上读取一个bit功能:
uint8_t one_wire_recv1Bit(void)
{
    // 发起读取标记:
    HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
    tim2_u_delay(2);
    // 主机释放单总线:
    HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
    tim2_u_delay(12);
    uint8_t bit = HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN);
    tim2_u_delay(50);
    return bit;
}
// 单总线上读取一个字节的功能:
uint8_t one_wire_read1Byte(void)
{
    uint8_t data = 0;
    for (int i = 0; i < 8; i++)
    {
        data = data >> 1;
        if (one_wire_recv1Bit())
        {
            data |= 0x80;
        }
    }
    return data;
}

// 从ds18b20芯片上读取温度:
float get_DS18B20_Temp(void)
{
    //1.复位单总线:
    one_wire_reset();
    //2.发送跳过ROM的命令
    one_wire_write1Byte(0xcc);
    //3.开启温度转换:
    one_wire_write1Byte(0x44);
    //4.等待数据转换(750ms)
    HAL_Delay(750);
		//vTaskDelay(750);
    //5.再次复位
    one_wire_reset();
    //6.发送跳过ROm的命令
    one_wire_write1Byte(0xcc);
    //7.发送读取读暂存寄存器的命令
    one_wire_write1Byte(0xbe);
    //8.读取暂存寄存器的低八位与高八位,两个字节
    uint8_t temp_LSB = one_wire_read1Byte();
    uint8_t temp_MSB = one_wire_read1Byte();

    uint16_t temp = temp_MSB << 8 | temp_LSB;

    //9.把ds18b20的数据转换为浮点值:
    if((temp & 0xf800) > 0)//负温度
    {
        temp = temp & 0x7ff;
        return -temp * 0.0625;
    }

    //正温度:
    temp = temp & 0x7ff;
    return temp * 0.0625;
}

3、红外遥控器

原理,使用定时器的输入捕获功能,记录两个下降沿的之间的周期,1120us就是0,2250us代表1,这样就能得到32位的数据

使能中断

相关推荐
瓢儿菜20183 小时前
stm32 f103c8t6仿真 串口收发测试
stm32·单片机·嵌入式硬件·proteus
蜡笔小电芯3 小时前
实时中值滤波 + 低通滤波 示例程序(STM32环境)
stm32·单片机·嵌入式硬件
深圳市尚想信息技术有限公司6 小时前
工业4.0核心引擎!意法STM32F407ZET6 单片机 赋能智能PLC/网关设计
stm32·单片机·嵌入式硬件·st意法·单片机mcu
GodKK老神灭7 小时前
STM32 串口寄存器开发
stm32·单片机·嵌入式硬件
木子单片机8 小时前
基于STM32电子密码锁
stm32·单片机·嵌入式硬件·proteus
Ivy烎11 小时前
STM32学习笔记
笔记·stm32·学习
蜡笔小电芯12 小时前
【STM32】 LWIP -TCP 客户端收发数据
网络·stm32·tcp/ip
深圳市尚想信息技术有限公司14 小时前
意法STM32F103C8T6 单片机ARM Cortex-M3 国民MCU 电机控制到物联网专用
arm开发·stm32·单片机
GodKK老神灭15 小时前
STM32 实现PID
stm32·单片机·算法·c