单片机
返回首页

STM32配置IIC接口通信方式参考源码

2024-10-09 来源:cnblogs

最近在读取SHT3x系列sensor的温度和湿度,用到的是IIC接口。

顺便写了一下STM32的IIC接口。


这次配置的是STM32内部的IIC接口。


注意:读的时候,怎么发送Ack, 和 NAck信号,参考stm的设计文档。


#include 'Dev_SHT3X.h'

#include 'globalDef.h'

#include



#define I2C1_OWN_ADDRESS7 0x0A

#define I2C_Speed         40000

#define SHT3X_ADDRESS     0x44


/* read out command */

#define CMD_READH_SHX     0x2c

#define CMD_READL_SHX     0x06


/**

* SHX device: IIC1

* PB6 - SCL

* PB7 - SDA

*/

static void IIC_gpioConfig(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;


    /* 使能与 I2C1 有关的时钟 */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);


    /* PB6-I2C1_SCL、PB7-I2C1_SDA*/

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;     // 开漏输出

    GPIO_Init(GPIOB, &GPIO_InitStructure);        

}


static void IIC_modeConfig(void)

{

    I2C_InitTypeDef I2C_InitStructure;


    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; /* I2C 配置 */

    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */

    I2C_InitStructure.I2C_OwnAddress1 = I2C1_OWN_ADDRESS7; /* setting master address. */

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ; /* enable ack */

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* 7-bit addressing mode */

    I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* communication speed <= 400k */


    I2C_Init(I2C1, &I2C_InitStructure);

    I2C_Cmd(I2C1, ENABLE);    

}



void SHT3X_InitDevice(void)

{

    IIC_gpioConfig();    

    IIC_modeConfig();

}



void sht3x_readTempHumi(uint8_t* pBuffer, uint8_t NumByteToRead)

{

    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* detect IIC busy */


    I2C_GenerateSTART(I2C1, ENABLE); /* Send START condition */


    /* Test on EV5 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


    /* Send slave device address for write */

    I2C_Send7bitAddress(I2C1, (SHT3X_ADDRESS << 1), I2C_Direction_Transmitter);


    /* Test on EV6 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));


    /* Clear EV6 by setting again the PE bit */

    I2C_Cmd(I2C1, ENABLE);


    /* Send the device address to write to */

    I2C_SendData(I2C1, CMD_READH_SHX);


    /* Test on EV8 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));


    /* Send the device address to write to */

    I2C_SendData(I2C1, CMD_READL_SHX);


    /* Test on EV8 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));


//------------------------------------------------


    /* Send STRAT condition a second time */

    I2C_GenerateSTART(I2C1, ENABLE);


    /* Test on EV5 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


    /* Send shx address for read */

    I2C_Send7bitAddress(I2C1, ((SHT3X_ADDRESS << 1) | 0x01), I2C_Direction_Receiver);


    /* Test on EV6 and clear it */

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


    /* While there is data to be read */

    while(NumByteToRead)

    {

        if(NumByteToRead == 1)

        {

            /* Disable Acknowledgement */

            I2C_AcknowledgeConfig(I2C1, DISABLE);


            /* Send STOP Condition */

            I2C_GenerateSTOP(I2C1, ENABLE);

        }


        /* Test on EV7 and clear it */

        if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))

        {

            /* Read a byte from the EEPROM */

            *pBuffer = I2C_ReceiveData(I2C1);


            /* Point to the next location where the byte read will be saved */

            pBuffer++;


            /* Decrement the read bytes counter */

            NumByteToRead--;

        }

    }


    /* Enable Acknowledgement to be ready for another reception */

    I2C_AcknowledgeConfig(I2C1, ENABLE);

}




//-----------------------------------------------------------------------------

static float SHT3X_CalcTemperature(uint16_t rawValue)

{

    // calculate temperature [°C]

    // T = -45 + 175 * rawValue / (2^16-1)

    return 175.0f * (float)rawValue / 65535.0f - 45.0f;

}


//-----------------------------------------------------------------------------

static float SHT3X_CalcHumidity(uint16_t rawValue)

{

    // calculate relative humidity [%RH]

    // RH = rawValue / (2^16-1) * 100

    return 100.0f * (float)rawValue / 65535.0f;

}


void sht3x_testTask(void)

{

    uint8_t recBuffer[6];

    uint16_t rawdata;

    float fTemp, fHumi;


    sht3x_readTempHumi(&recBuffer[0], 6);

    rawdata = recBuffer[0];

    rawdata = (rawdata << 8) + recBuffer[1];

    fTemp = SHT3X_CalcTemperature(rawdata);


    rawdata = recBuffer[3];

    rawdata = (rawdata << 8) + recBuffer[4];

    fHumi = SHT3X_CalcHumidity(rawdata);


    enterCriticalSection();

    printf('T: %0.2f, H: %0.1frn', fTemp, fHumi);

    exitCriticalSection();

}


#ifndef _DEV_SHT3X_H

#define _DEV_SHT3X_H


#include 'bsp_iic.h'

#include 'bsp_SysConfig.h'




extern void SHT3X_InitDevice(void);

extern void sht3x_testTask(void);



#endif /* _DEV_SHT3X_H */


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何构建一个触摸传感器电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章