【嵌入式】HC32F07X 使用I2C外设读取LM75温度传感器数据

目录

一 背景说明

二 原理分析

三 代码实现

四 测试效果


一 背景说明

        使用小华(华大)的MCU HC32F07X实现使用I2C外设读取LM75温度传感器数据。

二 原理分析

        I2C的实际使用需要了解三个部分,I2C协议原理从机设备(LM75传感器)的使用说明主机设备(HX32F07X的I2C外设)

【1】I2C协议原理:

        关于 I2C协议,这边推荐B站博主 工科男孙老师 的几段视频,深入浅出讲解得非常详细:

  1. UART那么好用,为什么单片机还需要I2C和SPI?_哔哩哔哩_bilibili
  2. 单片机I2C通信入门(上):硬件部分有哪些注意点?_哔哩哔哩_bilibili
  3. 单片机I2C通信入门(下):三份文件搞清楚I2C通信协议_哔哩哔哩_bilibili

        I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
        主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。

        SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出。需通过上拉电阻接电源VCC。当总线空闲时,两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路。在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容。而线路中电容会影响总线传输速度。当电容过大时,有可能造成传输错误。所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。
        主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件。然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下。主机负责产生定时时钟和终止数据传送。

        其读写时序如下,注意几点:

        (1) I2C是通过 从机地址(7位) + R/W读写标志(1位) 来进行读写操作区分的;

        (2)等待应答ASK的时间不能忘;

【2】LM75说明书LM75BDP-HXY -PDF数据手册-参考资料-立创商城):

        (1)产品概述如下:

        (2)典型电路如下,注意上拉10K电阻(因总线上串接的I2C设备数量来做取值,过大可能会导致信号失真过小可能会浪费能量或者无法将总线电压拉低到低电平,甚至可能会烧毁电路

        (3)如果A0/A1/A2均接地的话,其逻辑地址为0x48

        (3)只需要读取温度寄存器的内容,所以从机内存地址为0x00

        (4)采样温度与实际温度的对应关系如下:

【3】HC32F07X的I2C外设说明书HC32F072PATA-LQFP100 -PDF数据手册-参考资料-立创商城

        (1)I2C总线概述:

        (2)状态码表述:

        这边特别注意HC32F07X上提供了一个状态寄存器 I2Cx_STAT ,可以实时查询该寄存器的值,以便知晓当前I2C总线通讯处于一个什么状态:

三 代码实现

        根据上面三方面的内容,可以写代码:

        【1】官方提供的驱动库 HC32F072_DDL_Rev1.2.0 ,调用里面的 i2c.c / i2c.h 驱动支持:

        i2c.c如下:

/******************************************************************************
 * Copyright (C) 2021, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************/

/******************************************************************************
 * @file   i2c.c
 *
 * @brief  Source file for I2C functions
 *
 * @author MADS Team 
 *
 ******************************************************************************/

/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "i2c.h"

/**
 *******************************************************************************
 ** \addtogroup I2cGroup
 ******************************************************************************/
//@{

/******************************************************************************/
/* Local function prototypes ('static')                                       */
/******************************************************************************/

/**
 ******************************************************************************
 ** \brief  I2C设置波特率配置寄存器
 **
 ** \param [in] u8Tm 波特率配置值
 **
 ** \retval enRet 成功或失败
 **
 ******************************************************************************/
 en_result_t I2C_SetBaud(M0P_I2C_TypeDef* I2Cx, uint8_t u8Tm)
 {
     en_result_t enRet = Error;
     
     I2Cx->TM = u8Tm;
     
     enRet = Ok;
     return enRet;
 }
 /**
 ******************************************************************************
 ** \brief  I2C功能设置相关函数
 **
 ** \param [in] enFunc功能参数
 **
 ** \retval enRet 成功或失败
 **
 ******************************************************************************/
en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
{
    en_result_t enRet = Error;
    
    SetBit((uint32_t)&I2Cx->CR, enFunc, TRUE);

    enRet = Ok;
    return enRet;
}
 /**
 ******************************************************************************
 ** \brief  I2C功能清除相关函数
 **
 ** \param [in] enFunc功能参数
 **
 ** \retval enRet 成功或失败
 **
 ******************************************************************************/
 en_result_t I2C_ClearFunc(M0P_I2C_TypeDef* I2Cx, en_i2c_func_t enFunc)
 {
    en_result_t enRet = Error;
    
    SetBit((uint32_t)&I2Cx->CR, enFunc, FALSE); 
  
    enRet = Ok;
    return enRet; 
 }
 /**
 ******************************************************************************
 ** \brief  I2C获取中断标记函数
 **
 ** \param 无
 **
 ** \retval bIrq中断标记
 **
 ******************************************************************************/
boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx)
{    
    if(I2Cx->CR&0x8)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    } 
}
/**
 ******************************************************************************
 ** \brief  I2C清除中断标记函数
 **
 ** \param 无
 **
 ** \retval bIrq中断标记
 **
 ******************************************************************************/
en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx)
{
    en_result_t enRet = Error;
    
    I2Cx->CR &= ~0x8u;
    
    enRet = Ok;
    return enRet; 
}
 /**
 ******************************************************************************
 ** \brief  I2C获取相关状态
 **
 ** \param 无
 **
 ** \retval I2C状态
 **
 ******************************************************************************/
uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx)
{
    uint8_t u8State = 0;
    
    u8State = I2Cx->STAT;
    
    return u8State;
}

/**
 ******************************************************************************
 ** \brief  字节数据写函数
 **
 ** \param  u8Data写数据
 **
 ** \retval 写数据是否成功
 **
 ******************************************************************************/
en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx, uint8_t u8Data)
{
    en_result_t enRet = Error;
    
    I2Cx->DATA = u8Data;

    enRet = Ok;
    return enRet;
}
/**
 ******************************************************************************
 ** \brief  字节数据读函数
 **
 ** \param  无
 **
 ** \retval 读取数据
 **
 ******************************************************************************/
uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx)
{
    uint8_t u8Data = 0;
    
    u8Data = I2Cx->DATA;
    
    return u8Data;
}

/**
 ******************************************************************************
 ** \brief  I2C模块初始化
 **
 ** \param pstcI2CCfg初始化配置结构体
 **
 ** \retval 初始化是否成功
 **
 ******************************************************************************/
en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx, stc_i2c_cfg_t *pstcI2CCfg)
{
   en_result_t enRet = Error;
   uint8_t     u8Tm;
   
   if(M0P_I2C0 == I2Cx)
   {
       M0P_RESET->PERI_RESET0 &= ~(uint32_t)0x10u; 
       M0P_RESET->PERI_RESET0 |= (uint32_t)0x10u;   
   }
   else
   {
       M0P_RESET->PERI_RESET0 &= ~(uint32_t)0x20u; 
       M0P_RESET->PERI_RESET0 |= (uint32_t)0x20u;   
   }
    
   I2Cx->CR = 0;
   I2Cx->CR = pstcI2CCfg->enMode;
    
   if((pstcI2CCfg->u32Baud<<4) > pstcI2CCfg->u32Pclk)
   {
        return Error;
   }       
    
   if(I2cMasterMode == pstcI2CCfg->enMode)
   {
        I2Cx->TMRUN = TRUE;
        ///< Fsck = Fpclk/8*(Tm+1)
        u8Tm = ((pstcI2CCfg->u32Pclk / pstcI2CCfg->u32Baud) >> 3) - 1;
        if(9 > u8Tm)
        {
            I2C_SetFunc(I2Cx,I2cHlm_En);
        }
        enRet = I2C_SetBaud(I2Cx, u8Tm);
   }
   else
   {
        I2Cx->TMRUN = FALSE;
        pstcI2CCfg->u8SlaveAddr = (uint8_t)(((uint32_t)pstcI2CCfg->u8SlaveAddr<<1)|(pstcI2CCfg->bGc));
        I2Cx->ADDR = pstcI2CCfg->u8SlaveAddr;
   }
 
   return enRet;
}

//@} // I2cGroup

        i2c.h如下:

/******************************************************************************
 * Copyright (C) 2021, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************/

/******************************************************************************
 * @file   i2c.h
 *
 * @brief  Header file for I2C functions
 *
 * @author MADS Team 
 *
 ******************************************************************************/

#ifndef __I2C_H__
#define __I2C_H__

#include "ddl.h"


/**
 *******************************************************************************
 ** \defgroup I2cGroup Inter-Integrated Circuit (I2C)
 **
 **
 ******************************************************************************/
//@{

/******************************************************************************/
/* Global pre-processor symbols/macros ('#define')                            */
/******************************************************************************/
/******************************************************************************
 * Global type definitions
 ******************************************************************************/

 /**
 ******************************************************************************
 ** \brief I2C功能配置
 *****************************************************************************/
typedef enum en_i2c_func
{
    I2cModule_En = 6u,  ///<I2C模块使能
    I2cStart_En  = 5u, ///<开始信号
    I2cStop_En   = 4u, ///<结束信号
    I2cAck_En    = 2u, ///<应答信号
    I2cHlm_En    = 0u, ///<高速使能
}en_i2c_func_t; 

 /**
 ******************************************************************************
 ** \brief I2C模式配置
 *****************************************************************************/
typedef enum en_i2c_mode
{
    I2cMasterMode = 0x40u,  ///<I2C主机模式
    I2cSlaveMode  = 0x44u,  ///<I2C从机模式
}en_i2c_mode_t;

/**
 ******************************************************************************
 ** \brief I2C初始化配置结构
 *****************************************************************************/
typedef struct stc_i2c_cfg
{
    uint32_t        u32Pclk;        ///<Pclk 设置(Hz)
    uint32_t        u32Baud;        ///<I2C通信波特率(Hz)
    en_i2c_mode_t   enMode;         ///<I2C主从模式配置
    uint8_t         u8SlaveAddr;    ///<从机地址配置(如果需要)
    boolean_t       bGc;            ///<广播地址使能(如果需要)
}stc_i2c_cfg_t;

/******************************************************************************
 * Global variable declarations ('extern', definition in C source)
 *****************************************************************************/

/******************************************************************************
 * Global function prototypes (definition in C source)
 *****************************************************************************/
 //I2C初始化函数
 en_result_t I2C_Init(M0P_I2C_TypeDef* I2Cx,stc_i2c_cfg_t *pstcI2CCfg);
 //设置波特率配置寄存器
 en_result_t I2C_SetBaud(M0P_I2C_TypeDef* I2Cx,uint8_t u8Tm);
 //I2C功能设置函数
 en_result_t I2C_SetFunc(M0P_I2C_TypeDef* I2Cx,en_i2c_func_t enFunc);
  //I2C功能清除函数
 en_result_t I2C_ClearFunc(M0P_I2C_TypeDef* I2Cx,en_i2c_func_t enFunc);
 //获取中断标记SI
 boolean_t I2C_GetIrq(M0P_I2C_TypeDef* I2Cx);
  //清除中断标记SI
 en_result_t I2C_ClearIrq(M0P_I2C_TypeDef* I2Cx);
 //获取状态
 uint8_t I2C_GetState(M0P_I2C_TypeDef* I2Cx);

 //字节写函数
 en_result_t I2C_WriteByte(M0P_I2C_TypeDef* I2Cx,uint8_t u8Data);

//字节读函数
uint8_t I2C_ReadByte(M0P_I2C_TypeDef* I2Cx);
 
//@} // I2cGroup

#ifdef __cplusplus
#endif

#endif /* __I2C_H__ */
/******************************************************************************
 * EOF (not truncated)
 *****************************************************************************/


        【2】GPIO以及I2C外设初始化:

//LM75温度传感器
#define I2C1_LM75_SCL_PORT    GpioPortB
#define I2C1_LM75_SCL_PIN     GpioPin13
#define I2C1_LM75_SDA_PORT    GpioPortB
#define I2C1_LM75_SDA_PIN     GpioPin14

#define LM75_ADDRESS        0x48    // LM75的I2C地址
#define LM75_REG_ADDRESS    0x00    // LM75的读取寄存器地址


/**************************************************************************
* 函数名称: I2C_Tmp_Init
* 功能描述: I2C温度传感器初始化
**************************************************************************/
void I2C_Tmp_Init(void)
{
    stc_gpio_cfg_t stcGpioCfg;
    DDL_ZERO_STRUCT(stcGpioCfg);                 ///< 初始化结构体变量的值为0
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///< 开启GPIO时钟门控 
        
    stcGpioCfg.enDir = GpioDirOut;               ///< 端口方向配置->输出      
    stcGpioCfg.enOD = GpioOdEnable;              ///< 端口开漏输出配置->开漏输出使能      
    stcGpioCfg.enPu = GpioPuEnable;              ///< 端口上拉配置->使能
    stcGpioCfg.enPd = GpioPdDisable;             ///< 端口下拉配置->禁止
    stcGpioCfg.bOutputVal = TRUE;                ///< 默认高电平
   
    Gpio_Init(I2C1_LM75_SCL_PORT, I2C1_LM75_SCL_PIN, &stcGpioCfg);      ///< 初始化SCL
    Gpio_Init(I2C1_LM75_SDA_PORT, I2C1_LM75_SDA_PIN, &stcGpioCfg);      ///< 初始化SDA
    
    Gpio_SetAfMode(I2C1_LM75_SCL_PORT, I2C1_LM75_SCL_PIN, GpioAf2);     ///< 配置SCL
    Gpio_SetAfMode(I2C1_LM75_SDA_PORT, I2C1_LM75_SDA_PIN, GpioAf2);     ///< 配置SDA
}

/**************************************************************************
* 函数名称: I2C_Tmp_Conf
* 功能描述: I2C温度传感器配置
**************************************************************************/
void I2C_Tmp_Conf(void)
{
    stc_i2c_cfg_t stcI2cCfg;
    DDL_ZERO_STRUCT(stcI2cCfg);                             ///< 初始化结构体变量的值为0
    Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c1,TRUE);  ///< 开启I2C1时钟门控   
        
    stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq();              ///< 获取PCLK时钟       
    stcI2cCfg.u32Baud = 100000;                             ///< 波特率100kHz
    stcI2cCfg.enMode  = I2cMasterMode;                      ///< I2C主机模式
    stcI2cCfg.u8SlaveAddr = LM75_ADDRESS;                   ///< 从地址,主模式无效
    stcI2cCfg.bGc = FALSE;                                  ///< 广播地址应答使能关闭,主模式无效
    I2C_Init(M0P_I2C1, &stcI2cCfg);                         ///< 模块初始化    
}

        【3】传感器值I2C读取与转换:

/**************************************************************************
* 函数名称: LM75_ReadTemperature
* 功能描述: I2C温度传感器值读取
**************************************************************************/
en_result_t LM75_ReadTemperature(M0P_I2C_TypeDef* I2Cx, uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
{
    en_result_t enRet = Error;
    uint8_t u8i=0,u8State;
    
    I2C_SetFunc(I2Cx,I2cStart_En);

    while(1)
    {
        while(0 == I2C_GetIrq(I2Cx))
        {}
        u8State = I2C_GetState(I2Cx);
        switch(u8State)
        {
            case 0x08:                                 ///< 已发送起始条件,将发送SLA+W
                I2C_ClearFunc(I2Cx,I2cStart_En);
                I2C_WriteByte(I2Cx,(LM75_ADDRESS << 1));
                break;
            case 0x18:                                 ///< 已发送SLA+W,并接收到ACK
                I2C_WriteByte(I2Cx,u8Addr);            ///< 发送从机内存地址
                break;
            case 0x28:                                 ///< 已发送数据,接收到ACK, 此处是已发送从机内存地址u8Addr并接收到ACK
                I2C_SetFunc(I2Cx,I2cStart_En);         ///< 发送重复起始条件
                break;
            case 0x10:                                 ///< 已发送重复起始条件
                I2C_ClearFunc(I2Cx,I2cStart_En);
                I2C_WriteByte(I2Cx,(LM75_ADDRESS << 1)|0x01);///< 发送SLA+R,开始从从机读取数据
                break;
            case 0x40:                                 ///< 已发送SLA+R,并接收到ACK
                if(u32Len>1)
                {
                    I2C_SetFunc(I2Cx,I2cAck_En);       ///< 使能主机应答功能
                }
                break;
            case 0x50:                                 ///< 已接收数据字节,并已返回ACK信号
                pu8Data[u8i++] = I2C_ReadByte(I2Cx);
                if(u8i==u32Len-1)
                {
                    I2C_ClearFunc(I2Cx,I2cAck_En);     ///< 已接收到倒数第二个字节,关闭ACK应答功能
                }
                break;
            case 0x58:                                 ///< 已接收到最后一个数据,NACK已返回
                pu8Data[u8i++] = I2C_ReadByte(I2Cx);
                I2C_SetFunc(I2Cx,I2cStop_En);          ///< 发送停止条件
                break;
            case 0x38:                                 ///< 在发送地址或数据时,仲裁丢失
                I2C_SetFunc(I2Cx,I2cStart_En);         ///< 当总线空闲时发起起始条件
                break;
            case 0x48:                                 ///< 发送SLA+R后,收到一个NACK
                I2C_SetFunc(I2Cx,I2cStop_En);          ///< 发送停止条件
                I2C_SetFunc(I2Cx,I2cStart_En);         ///< 发送起始条件
                break;
            default:
                I2C_SetFunc(I2Cx,I2cStart_En);         ///< 其他错误状态,重新发送起始条件
                break;
        }
        I2C_ClearIrq(I2Cx);                            ///< 清除中断状态标志位
        if(u8i==u32Len)                                ///< 数据全部读取完成,跳出while循环
        {
                break;
        }
    }
    enRet = Ok;
    return enRet;
}

/**************************************************************************
* 函数名称: LM75_ConvertToCelsius
* 功能描述: I2C温度传感器值转换
**************************************************************************/
float LM75_ConvertToCelsius(uint16_t rawData)
{
    float temperature;
    rawData >>= 7; // 取高 9 位
    if (rawData & 0x100) // 判断是否为负数
    {
        rawData |= 0xFE00; // 符号扩展
    }
    temperature = (int16_t)rawData * 0.5f; // 转换为实际温度
    return temperature;
}

        【4】再附一个主机写入的例程(本例中没有用到):

/**
 ******************************************************************************
 ** \brief  主机发送函数
 **
 ** \param u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
 **
 ** \retval 写数据是否成功
 **
 ******************************************************************************/
en_result_t I2C_MasterWriteData(M0P_I2C_TypeDef* I2CX,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
{
    en_result_t enRet = Error;
    uint8_t u8i=0,u8State;
    I2C_SetFunc(I2CX,I2cStart_En);
    while(1)
    {
        while(0 == I2C_GetIrq(I2CX))
        {;}
        u8State = I2C_GetState(I2CX);
        switch(u8State)
        {
            case 0x08:                               ///< 已发送起始条件
                I2C_ClearFunc(I2CX,I2cStart_En);
                I2C_WriteByte(I2CX,I2C_SLAVEADDR);   ///< 从设备地址发送
                break;
            case 0x18:                               ///< 已发送SLA+W,并接收到ACK
                I2C_WriteByte(I2CX,u8Addr);          ///< 从设备内存地址发送
                break;
            case 0x28:                               ///< 上一次发送数据后接收到ACK
                I2C_WriteByte(I2CX,pu8Data[u8i++]);  ///< 继续发送数据
                break;
            case 0x20:                               ///< 上一次发送SLA+W后,收到NACK
            case 0x38:                               ///< 上一次在SLA+读或写时丢失仲裁
                I2C_SetFunc(I2CX,I2cStart_En);       ///< 当I2C总线空闲时发送起始条件
                break;
            case 0x30:                               ///< 已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件
                I2C_SetFunc(I2CX,I2cStop_En);        ///< 发送停止条件
                break;
            default:
                break;
        }
        if(u8i>u32Len)
        {
            I2C_SetFunc(I2CX,I2cStop_En);            ///< 此顺序不能调换,出停止条件
            I2C_ClearIrq(I2CX);
            break;
        }
        I2C_ClearIrq(I2CX);                          ///< 清除中断状态标志位
    }
    enRet = Ok;
    return enRet;
}

        【5】将其放到 FreeRTOS的子任务中实现:

/**************************************************************************
* 函数名称: TMP_Task
* 功能描述: 状态子任务
**************************************************************************/
uint8_t temp_test[2]={0x00};
float temperature;

void TMP_Task(void* param)
{
    //按钮初始化
    IN_Key_Init();
    //蜂鸣器初始化
    OUT_Beep_Init();
    
    //I2C温度传感器初始化
    I2C_Tmp_Init();
    I2C_Tmp_Conf();
    
	while(1)
	{
        if(IN_KEY_GET())
        {
            //检测按钮未按下打印任务栈
            UBaseType_t uxUsedStackSize = TMP_TASK_SIZE - uxTaskGetStackHighWaterMark(NULL);
            UBaseType_t uxUsagePercentage = (uxUsedStackSize * 100) / TMP_TASK_SIZE;
            Dbg_Printf("TMP_Task-->Stack Used: %u/%u (%u%%)\r\n", 
                   (unsigned int)uxUsedStackSize, 
                   (unsigned int)TMP_TASK_SIZE, 
                   (unsigned int)uxUsagePercentage);
                   
            Gpio_ClrIO(OUT_BEEP_PORT, OUT_BEEP_PIN);    //禁止蜂鸣器
        }
        else
        {
            //检测按钮按下打印温度数据
            LM75_ReadTemperature(M0P_I2C1, LM75_REG_ADDRESS, temp_test, 2);
            temperature = LM75_ConvertToCelsius((temp_test[0] << 8) | temp_test[1]);
            Dbg_Printf("Temperature: %.1f C\r\n", temperature);
            
            Gpio_SetIO(OUT_BEEP_PORT, OUT_BEEP_PIN);    //使能蜂鸣器
        }

        vTaskDelay(1000);
	}
}

四 测试效果

        测试能够通过LM75正常读取数据:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值