基于STM32F1的VEML7700环境光传感器的使用代码

本文章基于STM32F1 HAL库文件下进行编写测试的代码,VEML7700传感器采用IIC通信,本实验为大学本科的课程设计,已经测试成功,均可在数码管和OLED上进行显示,效果如下:

在黑暗的环境下的光强(单位 lux):

在手机灯光照射下的光强(单位 lux):

现贴如代码如下:

iic.c

#include <stdio.h>

#include "i2c.h"
#include "update.h"
#include <string.h>

#if I2C1_MODE == I2C1_MODE_POLL
/**
 * PB10 PB11 config I2C1
*/
void i2c1_config(void)
{
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable I2C1 clock */
    rcu_periph_clock_enable(RCU_I2C1);
    /* connect PB10 to I2C1_SCL */
    /* connect PB11 to I2C2_SDA */
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//配置PB10,PB11为复用功能

    /* configure I2C clock */
    i2c_clock_config(I2C1, I2C1_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDR);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}

void i2c1_write_data_by_reg(uint8_t slave_addr,uint8_t* p_buffer, uint8_t write_address, uint8_t number_of_byte)
{
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_TRANSMITTER);
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2C1, I2C_FLAG_TBE));
    
    /* send the EEPROM's internal address to write to : only one byte address */
    i2c_data_transmit(I2C1, write_address);
    
    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
    
    /* while there is data to be written */
    while(number_of_byte--){  
        i2c_data_transmit(I2C1, *p_buffer);
        
        /* point to the next byte to be written */
        p_buffer++; 
        
        /* wait until BTC bit is set */
        while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
    }
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C1);
    
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C1)&0x0200);
}

void i2c1_read_data_by_reg(uint8_t slave_addr,uint8_t* p_buffer, uint8_t read_address, uint16_t number_of_byte)
{  
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));

    if(2 == number_of_byte){
        i2c_ackpos_config(I2C1,I2C_ACKPOS_NEXT);
    }
    
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_TRANSMITTER);
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while(SET != i2c_flag_get( I2C1 , I2C_FLAG_TBE));

    /* enable I2C1*/
    i2c_enable(I2C1);
    
    /* send the EEPROM's internal address to write to */
    i2c_data_transmit(I2C1, read_address);  
    
    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
    
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_RECEIVER);

    if(number_of_byte < 3){
        /* disable acknowledge */
        i2c_ack_config(I2C1,I2C_ACK_DISABLE);
    }
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
    
    if(1 == number_of_byte){
        /* send a stop condition to I2C bus */
        i2c_stop_on_bus(I2C1);
    }
    
    /* while there is data to be read */
    while(number_of_byte){
        if(3 == number_of_byte){
            /* wait until BTC bit is set */
            while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));

            /* disable acknowledge */
            i2c_ack_config(I2C1,I2C_ACK_DISABLE);
        }
        if(2 == number_of_byte){
            /* wait until BTC bit is set */
            while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
            
            /* send a stop condition to I2C bus */
            i2c_stop_on_bus(I2C1);
        }
        
        /* wait until the RBNE bit is set and clear it */
        if(i2c_flag_get(I2C1, I2C_FLAG_RBNE)){
            /* read a byte from the EEPROM */
            *p_buffer = i2c_data_receive(I2C1);
            
            /* point to the next location where the byte read will be saved */
            p_buffer++; 
            
            /* decrement the read bytes counter */
            number_of_byte--;
        } 
    }
    
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C1)&0x0200);
    
    /* enable acknowledge */
    i2c_ack_config(I2C1,I2C_ACK_ENABLE);

    i2c_ackpos_config(I2C1,I2C_ACKPOS_CURRENT);
}

#elif I2C1_MODE == I2C1_MODE_DMA
uint8_t i2c1_buff_rx[128];

static void i2c1_dma_rx_config(uint8_t *p_data,uint8_t len)
{
    dma_parameter_struct dma_init_struct;
    /* initialize DMA channel4 */
    dma_deinit(DMA0, DMA_CH4);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)p_data;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = len;
    dma_init_struct.periph_addr = (uint32_t)&I2C_DATA(I2C1);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH4, &dma_init_struct);
}

static void i2c1_dma_tx_config(uint8_t *p_data,uint8_t len)
{
    dma_parameter_struct dma_init_struct;
    /* initialize DMA channel3 */
    dma_deinit(DMA0, DMA_CH3);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = (uint32_t)p_data;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = len;
    dma_init_struct.periph_addr = (uint32_t)&I2C_DATA(I2C1);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH3, &dma_init_struct);
}

void i2c1_dma_init(void)
{
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_DMA0);

    /* enable I2C1 clock */
    rcu_periph_clock_enable(RCU_I2C1);
    /* connect PB10 to I2C1_SCL */
    /* connect PB11 to I2C2_SDA */
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//配置PB10,PB11为复用功能

    /* configure I2C clock */
    i2c_clock_config(I2C1, I2C1_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xff);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}


static void i2c1_dma_tx_data(uint8_t slave_addr,uint8_t *p_data,uint8_t len)
{
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_TRANSMITTER);
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2C1, I2C_FLAG_TBE));

    i2c1_dma_tx_config(p_data,len);
    
      /* enable I2C1 DMA */
    i2c_dma_config(I2C1, I2C_DMA_ON);

    /* enable DMA0 channel3 */
    dma_channel_enable(DMA0, DMA_CH3);

    /* DMA0 channel3 full transfer finish flag */
    while(!dma_flag_get(DMA0, DMA_CH3, DMA_FLAG_FTF));
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C1);
    
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C1)&0x0200);  
}
/**
 * 封装一个函数按寄存器写的函数,寄存器地址可以有多位。
 * 数据可以有多个
 * dma方式
*/
void i2c1_dma_send_data(uint8_t slave_addr,uint8_t *reg_addr,
                        uint16_t addr_len,uint8_t *p_data,uint8_t data_len)
{
    uint8_t data[I2C_TX_RX_DATA_LEN_MAX] = {0};
    uint8_t *p;
    if ((addr_len + data_len) > I2C_TX_RX_DATA_LEN_MAX)
    {
        perror("data to long and return\r\n");
        return ;
    }
    p = data;
    memcpy(p,reg_addr,addr_len);
    p += addr_len;
    memcpy(p,p_data,data_len);

    i2c1_dma_tx_data(slave_addr,data,(addr_len+data_len));

}

void i2c1_dma_receive_data(uint8_t slave_addr, uint8_t *reg_addr,uint16_t addr_len,  
            uint8_t* p_buffer, uint16_t number_of_byte)
{  
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));

    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_TRANSMITTER);
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while(SET != i2c_flag_get( I2C1 , I2C_FLAG_TBE));

    /* enable I2C1*/
    i2c_enable(I2C1);
    
    /* send the EEPROM's internal address to write to */
    while (addr_len)
    {
        i2c_data_transmit(I2C1, *reg_addr++); 
        addr_len--; 
        /* wait until BTC bit is set */
        while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
    }
    
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, slave_addr, I2C_RECEIVER);

    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);

    if(number_of_byte < 2) 
    {
        /* disable acknowledge */
        i2c_ack_config(I2C1, I2C_ACK_DISABLE);
        /* clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */
        i2c_flag_get(I2C1, I2C_FLAG_ADDSEND);
        /* send a stop condition to I2C bus*/
        i2c_stop_on_bus(I2C1);
        /* wait for the byte to be received */
        while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE));
        /* read the byte received from the EEPROM */
        *p_buffer = i2c_data_receive(I2C1);
        /* decrement the read bytes counter */
        number_of_byte--;     
    } 
    else
    {
        i2c1_dma_rx_config(p_buffer,number_of_byte);
        i2c_dma_last_transfer_config(I2C1, I2C_DMALST_ON);
        /* enable I2C1 DMA */
        i2c_dma_config(I2C1, I2C_DMA_ON);
        /* enable DMA0 channel5 */
        dma_channel_enable(DMA0, DMA_CH4);
        /* wait until BTC bit is set */
        while(!dma_flag_get(DMA0, DMA_CH4, DMA_FLAG_FTF));
    }
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C1)&0x0200);
    i2c_stop_on_bus(I2C1);

    /* enable acknowledge */
    i2c_ack_config(I2C1,I2C_ACK_ENABLE);
    i2c_ackpos_config(I2C1,I2C_ACKPOS_CURRENT);

}
#elif I2C1_MODE == I2C1_MODE_SLAVE

volatile uint8_t        i2c_txbuffer[128] = {0};
volatile uint8_t        i2c_rxbuffer[128];
volatile uint16_t       i2c_rx_num;
volatile uint16_t       i2c_tx_num;
static   uint8_t        isfirst = 0;

void i2c1_slave_config(void)
{
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable I2C1 clock */
    rcu_periph_clock_enable(RCU_I2C1);
    /* connect PB10 to I2C1_SCL */
    /* connect PB11 to I2C2_SDA */
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//配置PB10,PB11为复用功能

    /* configure I2C clock */
    i2c_clock_config(I2C1, I2C1_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_OWN_ADDRESS7);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);

    nvic_irq_enable(I2C1_EV_IRQn, 0, 2);
    nvic_irq_enable(I2C1_ER_IRQn, 0, 1);
    /* enable the I2C1 interrupt */
    i2c_interrupt_enable(I2C1, I2C_INT_ERR);
    i2c_interrupt_enable(I2C1, I2C_INT_BUF);
    i2c_interrupt_enable(I2C1, I2C_INT_EV);

}

/*!
    \brief      handle I2C1 event interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_EventIRQ_Handler(void)
{
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) {
        /* clear the ADDSEND bit */
        if (isfirst == 0)
        {
            isfirst = 1;
            i2c_rx_num = 0; 
        }
        else
        {
            isfirst = 0;
            i2c_tx_num = 0;
            send_i2c_message(i2c_rxbuffer,i2c_rx_num);
        }
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND);
    } else if((i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TBE)) && (!i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR))) {
        
        /* send a data byte */ 
        //printf("now send data  %d: \r\n",i2c_tx_num);
        i2c_data_transmit(I2C1, i2c_txbuffer[i2c_tx_num++]);
    } else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)) {
        /* if reception data register is not empty ,I2C1 will read a data from I2C_DATA */
        i2c_rxbuffer[i2c_rx_num] = i2c_data_receive(I2C1);
        i2c_rx_num++;

    } else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_STPDET)) {

        //printf("get num == %d\r\n",i2c_rx_num);
        handle_i2c_message(i2c_rxbuffer,i2c_rx_num);
        /* clear the STPDET bit */
        i2c_enable(I2C1);
        i2c_rx_num = 0;
        i2c_tx_num = 0;
        isfirst = 0;
    }
}


/*!
    \brief      handle I2C1 error interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_ErrorIRQ_Handler(void)
{
    /* no acknowledge received */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR);
    }

    /* SMBus alert */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT);
    }

    /* bus timeout in SMBus mode */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO);
    }

    /* over-run or under-run when SCL stretch is disabled */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR);
    }

    /* arbitration lost */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB);
    }

    /* bus error */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR);
    }

    /* CRC value doesn't match */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR);
    }
    // /* disable the I2C1 interrupt */
    // i2c_interrupt_disable(I2C1, I2C_INT_ERR);
    // i2c_interrupt_disable(I2C1, I2C_INT_BUF);
    // i2c_interrupt_disable(I2C1, I2C_INT_EV);
}
#elif I2C1_MODE == I2C1_MODE_SW
#include "main.h"

//#define VEML7700_SCL_Pin GPIO_PIN_6
//#define VEML7700_SCL_GPIO_Port GPIOB
//#define VEML7700_SDA_Pin GPIO_PIN_7
//#define VEML7700_SDA_GPIO_Port GPIOB


#define swi2c_sda_high HAL_GPIO_WritePin(VEML7700_SDA_GPIO_Port,VEML7700_SDA_Pin,GPIO_PIN_SET)
#define swi2c_sda_low  HAL_GPIO_WritePin(VEML7700_SDA_GPIO_Port,VEML7700_SDA_Pin,GPIO_PIN_RESET)
#define swi2c_sda_read   ((VEML7700_SDA_GPIO_Port->IDR & VEML7700_SDA_Pin) != 0)	/* 读SDA口线状态 */

#define swi2c_scl_high HAL_GPIO_WritePin(VEML7700_SCL_GPIO_Port,VEML7700_SCL_Pin,GPIO_PIN_SET)
#define swi2c_scl_low  HAL_GPIO_WritePin(VEML7700_SCL_GPIO_Port,VEML7700_SCL_Pin,GPIO_PIN_RESET)


void swi2c_config(void)
{   /* enable GPIOB clock */

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOB_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = VEML7700_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(VEML7700_SDA_GPIO_Port, &GPIO_InitStruct);

    swi2c_sda_high;
    swi2c_scl_high;  
}

void delay_1us(uint16_t us)
{
    HAL_Delay_us(us);
}

/**
 * SDA PB11 input mode
*/
static void swi2c_sda_config_input_mode(void)
{
//    gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOB_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = VEML7700_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(VEML7700_SDA_GPIO_Port, &GPIO_InitStruct);
    
    
    
    
    
}

/**
 * SDA PB11 output mode
*/
static void swi2c_sda_config_output_mode(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOB_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = VEML7700_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(VEML7700_SDA_GPIO_Port, &GPIO_InitStruct);

//    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
}

//开始信号
void swi2c_start(void)
{
	swi2c_sda_config_output_mode(); //SDA定义为输出
	swi2c_sda_high; 
	swi2c_scl_high;
	delay_1us(4);
	swi2c_sda_low;  
	delay_1us(4);
	swi2c_scl_low; 
} 


void swi2c_stop(void)//停止信号
{
	swi2c_sda_config_output_mode(); //SDA定义为输出
	swi2c_scl_low;
	swi2c_sda_low; 
	delay_1us(4);
	swi2c_scl_high; 
	delay_1us(4);
	swi2c_sda_high; //发送 I2C 总线结束信号
	delay_1us(4); 
}

uint8_t swi2c_wait_ack(void)//等待应答信号:0-应答;1-非应答
{
    uint8_t uc_time = 0;
	swi2c_sda_high;
	swi2c_sda_config_input_mode(); //SDA定义为输入 
	delay_1us(4); 
	swi2c_scl_high;
	delay_1us(1);

    while (swi2c_sda_read)
    {
        uc_time++;
        if (uc_time > 250)
        {
            swi2c_stop();
            return 1;
        }
    }
	delay_1us(4);
	swi2c_scl_low;
	return 0; 
} 

void swi2c_ack(void)//产生 ACK 应答
{ 
	swi2c_scl_low;
	swi2c_sda_config_output_mode();
	swi2c_sda_low;
	delay_1us(2);
	swi2c_scl_high;
	delay_1us(2);
	swi2c_scl_low;
}

void swi2c_no_ack(void)//产生 NACK 非应答
{ 
	swi2c_scl_low;
	swi2c_sda_config_output_mode();
	swi2c_sda_high;
	delay_1us(2);
	swi2c_scl_high;
	delay_1us(2);
	swi2c_scl_low;
} 

//IIC 发送一个字节
void swi2c_write_byte(uint8_t txd)
{ 
	uint8_t t; 
	swi2c_sda_config_output_mode(); 
	swi2c_scl_low;            //拉低时钟开始数据传输
	for(t = 0;t < 8;t++)
	{ 
        if((txd<<t) & 0x80)//表示数据是1
			swi2c_sda_high;
		else
			swi2c_sda_low;
		delay_1us(4); 
		swi2c_scl_high;
		delay_1us(4); 
		swi2c_scl_low;
		//delay_us(2);
	}
} 

//读一个字节
uint8_t swi2c_read_byte(void)
{ 
	uint8_t i,receive = 0;
	
	swi2c_sda_config_input_mode();
	for(i = 0;i < 8;i++ )
	{  
		delay_1us(4);
		swi2c_scl_high;
		receive <<= 1;
		if(swi2c_sda_read == 1)
		{
			receive ++;
		}
		delay_1us(4); 
		swi2c_scl_low;
	}
	return receive;
} 

//只写地址
uint8_t write_device_addr(uint8_t addr)
{
	uint8_t read_ack = 0;
	swi2c_start();
	swi2c_write_byte(addr);
	read_ack = swi2c_wait_ack();
	swi2c_stop();
	
	return(read_ack);
}

//在总线上搜寻挂载的器件地址
void swi2c_search_device_addr(void)
{
	uint8_t result = 0;
	uint8_t j = 0;
	for(j = 0;j < 128; j++)
	{
		if((j % 16) == 0)
		{
			printf("\r\n");
		}
		result = write_device_addr(j << 1);
		if(result == 0)
		{
			printf(" %X ",j << 1);//%X 十六进制输出,大写;%x 小写
		}
		else
		{
			printf(" -- ");
		}
	}
    printf("\r\n");
}

//读指定器件的指定位置中的一个字节
uint8_t swi2c_device_read_one_byte(uint8_t device_addr,uint8_t reg_addr)
{
	uint8_t dat;

	swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

	swi2c_write_byte(reg_addr);//写位置
	swi2c_wait_ack();

	swi2c_start();
	swi2c_write_byte((device_addr) | 0x01);//读写位改为读
	swi2c_wait_ack();

	dat = swi2c_read_byte();
	swi2c_no_ack();//读一个字节结束
	swi2c_stop();
	
	return dat;
}

void swi2c_device_write_one_byte(uint8_t device_addr,uint8_t reg_addr,uint8_t data)//写指定器件的指定位置中的一个字节
{
	swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

	swi2c_write_byte(reg_addr);//写位置
	swi2c_wait_ack();

	swi2c_write_byte(data);//写数据
	swi2c_wait_ack();

	swi2c_stop();
}

//连续读指定器件的指定位置中的多个字节
void swi2c_device_read_bytes(uint8_t device_addr,uint8_t reg_addr,uint8_t *buf,uint8_t len)
{
	swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

	swi2c_write_byte(reg_addr);//写位置
	swi2c_wait_ack();

	swi2c_start();
	swi2c_write_byte((device_addr) | 0x01);//读写位改为读
	swi2c_wait_ack();

	while(len > 1)
	{
		*buf++ = swi2c_read_byte();
		swi2c_ack();
		len--;
	}
	*buf = swi2c_read_byte();//循环体结束指针已经指向最后一个字节存放位置
	swi2c_no_ack();//读一个字节结束
	swi2c_stop();	
}

//连续写指定器件的指定位置中的多个字节
void swi2c_device_write_bytes(uint8_t device_addr,uint8_t reg_addr,uint8_t *buf,uint8_t len)
{
	while(len > 0)
	{
		swi2c_start();
		swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
		swi2c_wait_ack();//等待应答

		swi2c_write_byte(reg_addr++);//写位置
		swi2c_wait_ack();

		swi2c_write_byte(*buf++);//写数据
		swi2c_wait_ack();

		swi2c_stop();//发送完结束信号后,器件才会把数据进行擦写操作,搬运到非易失区,这段时间器件不再响应主机操作
		HAL_Delay(10);//eeprom连续写时必须加,否则下个字节写入失败
		len--;
	}
}

void swi2c_device_write_data(uint8_t device_addr,uint8_t *reg_addr,
                                    uint16_t reg_len,uint8_t *buf,uint8_t len)
{
    swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

	while(reg_len)
    {
	    swi2c_write_byte(*reg_addr++);//写位置
	    swi2c_wait_ack();
        reg_len--;
    }

    while(len)
    {
	    swi2c_write_byte(*buf++);//写位置
	    swi2c_wait_ack();
        len--;
    }
    swi2c_stop();
}

void swi2c_write_data(uint8_t device_addr,uint8_t *buf,uint8_t len)
{
    swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

    while(len)
    {
	    swi2c_write_byte(*buf++);//写位置
	    swi2c_wait_ack();
        len--;
    }
    swi2c_stop();
}

void swi2c_device_read_data(uint8_t device_addr,uint8_t *reg_addr,
                                    uint16_t reg_len,uint8_t *buf,uint8_t len)
{
	swi2c_start();
	swi2c_write_byte(device_addr);//写地址,7位地址左移,低位补0
	swi2c_wait_ack();//等待应答

    while (reg_len/* condition */)
    {
        /* code */
        swi2c_write_byte(*reg_addr++);//写位置
        swi2c_wait_ack();
        reg_len--;
    }
    
	swi2c_start();
	swi2c_write_byte((device_addr) | 0x01);//读写位改为读
	swi2c_wait_ack();

	while(len > 1)
	{
		*buf++ = swi2c_read_byte();
		swi2c_ack();
		len--;
	}
	*buf = swi2c_read_byte();//循环体结束指针已经指向最后一个字节存放位置
	swi2c_no_ack();//读一个字节结束
	swi2c_stop();	
}

void swi2c_read_data(uint8_t device_addr,uint8_t *buf,uint8_t len)
{
	swi2c_start();
	swi2c_write_byte((device_addr) | 0x01);//读写位改为读
	swi2c_wait_ack();

	while(len > 1)
	{
		*buf++ = swi2c_read_byte();
		swi2c_ack();
		len--;
	}
	*buf = swi2c_read_byte();//循环体结束指针已经指向最后一个字节存放位置
	swi2c_no_ack();//读一个字节结束
	swi2c_stop();	
}

#endif

iic.h 

#ifndef __I2C_H__
#define __I2C_H__
#include "main.h"

#define I2C1_MODE_POLL              0x00
#define I2C1_MODE_INT               0x01
#define I2C1_MODE_DMA               0x02
#define I2C1_MODE_SLAVE             0x03
#define I2C1_MODE_SW                0x04


#define I2C1_MODE                   I2C1_MODE_SW

#define I2C1_SLAVE_ADDR             0xA0
#define I2C1_SPEED                  100000

#if I2C1_MODE == I2C1_MODE_POLL
void i2c1_config(void);
void i2c1_write_data_by_reg(uint8_t slave_addr,uint8_t* p_buffer, uint8_t write_address, uint8_t number_of_byte);
void i2c1_read_data_by_reg(uint8_t slave_addr,uint8_t* p_buffer, uint8_t read_address, uint16_t number_of_byte);

#elif I2C1_MODE == I2C1_MODE_DMA
#define ARRAYNUM(arr_nanme)      (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
//#define I2C0_DATA_ADDRESS        0x40005410
#define I2C1_DATA_ADDRESS        0x40005810
#define I2C_TX_RX_DATA_LEN_MAX   128

void i2c1_dma_send_data(uint8_t slave_addr,uint8_t *reg_addr,uint16_t addr_len,uint8_t *p_data,uint8_t data_len);
void i2c1_dma_init();
void i2c1_dma_receive_data(uint8_t slave_addr, uint8_t *reg_addr,uint16_t addr_len,  
            uint8_t* p_buffer, uint16_t number_of_byte);

#elif I2C1_MODE == I2C1_MODE_SLAVE
#define I2C1_OWN_ADDRESS7      0x30

extern volatile uint8_t        i2c_txbuffer[128];
extern volatile uint8_t        i2c_rxbuffer[128];

void i2c1_slave_config(void);

#elif I2C1_MODE == I2C1_MODE_SW

void swi2c_config(void);
void swi2c_search_device_addr(void);

//针对eeprom使用
void swi2c_device_write_bytes(uint8_t device_addr,uint8_t reg_addr,uint8_t *buf,uint8_t len);
void swi2c_device_read_bytes(uint8_t device_addr,uint8_t reg_addr,uint8_t *buf,uint8_t len);

void swi2c_device_read_data(uint8_t device_addr,uint8_t *reg_addr,
                                    uint16_t reg_len,uint8_t *buf,uint8_t len);
void swi2c_device_write_data(uint8_t device_addr,uint8_t *reg_addr,
                                    uint16_t reg_len,uint8_t *buf,uint8_t len);
void swi2c_read_data(uint8_t device_addr,uint8_t *buf,uint8_t len);
void swi2c_write_data(uint8_t device_addr,uint8_t *buf,uint8_t len);
#endif // I2C1_MODE == I2C1_MODE_POLL

#endif //__I2C_H__

上边是IIC基本的驱动代码,接下来就是大头:

VEML7700.C

#include "main.h"
#include "veml7700.h"
#include "i2c.h"
#include <stdio.h>

void veml7700_write(uint8_t reg_addr,uint8_t *p_buf)
{
#if I2C1_MODE == I2C1_MODE_SW
    swi2c_device_write_data(VEML_SLAVE_ADDR,&reg_addr,1,p_buf,2);
#endif
}

void veml7700_read(uint8_t reg_addr,uint8_t *p_buf)
{
#if I2C1_MODE == I2C1_MODE_SW
    swi2c_device_read_data(VEML_SLAVE_ADDR,&reg_addr,1,p_buf,2);
#endif
}

static int get_veml7700_default_value(uint16_t *default_value)
{
    uint8_t rx_data[2] = {0};
    veml7700_read(0x00,rx_data);
    *default_value = ((rx_data[1] << 8) | rx_data[0]);
    return 0;
}

static uint16_t veml7700_get_light_sensor_value(uint8_t command,uint16_t mask,uint8_t shift)
{
    uint8_t rx_data[2] = {0};
    uint16_t r_value = 0;

    veml7700_read(command,rx_data);
    r_value = ((rx_data[1] << 8) | rx_data[0]);
    return (r_value & mask) >> shift;
}

static void veml7700_set_light_sensor_value(uint8_t value,uint8_t command,uint16_t mask,uint8_t shift)
{
    uint8_t rx_data[2] = {0};
    uint8_t tx_data[2] = {0};
    uint16_t r_value = 0;
    uint16_t tmp_value = 0;
    veml7700_read(command,rx_data);
    r_value = ((rx_data[1] << 8) | rx_data[0]);
    tmp_value = r_value & ~(mask);
    tmp_value |= ((value << shift) & mask);

    tx_data[0] = tmp_value & 0xff;
    tx_data[1] = ((tmp_value >> 8) & 0xff); 
    veml7700_write(command,tx_data);
} 

static uint16_t get_power_enable()
{
    return veml7700_get_light_sensor_value(COMMAND_ALS_SD,ALS_SD_MASK,ALS_SD_SHIFT);
}

static void set_power_enable(int enable)
{
     veml7700_set_light_sensor_value(enable,COMMAND_ALS_SD,ALS_SD_MASK,ALS_SD_SHIFT);
}

static uint16_t get_gain_value(void)
{
    return veml7700_get_light_sensor_value(COMMAND_ALS_GAIN,ALS_GAIN_MASK,ALS_GAIN_SHIFT);
}

static void set_gain_value(uint16_t gain)
{
    veml7700_set_light_sensor_value(gain,COMMAND_ALS_GAIN,ALS_GAIN_MASK,ALS_GAIN_SHIFT);
}

static uint16_t get_interrupt_enable(void)
{
    return veml7700_get_light_sensor_value(COMMAND_ALS_INT_EN,ALS_INT_EN_MASK,ALS_INT_EN_SHIFT);
}

static void set_interrupt_enable(uint16_t enable)
{
    veml7700_set_light_sensor_value(enable,COMMAND_ALS_INT_EN,ALS_INT_EN_MASK,ALS_INT_EN_SHIFT);
}

static int get_integration_time(void) 
{
    return veml7700_get_light_sensor_value(COMMAND_ALS_IT,ALS_IT_MASK,ALS_IT_SHIFT);
   
}

static void set_integration_time(int time)
{
    veml7700_set_light_sensor_value(time,COMMAND_ALS_IT,ALS_IT_MASK,ALS_IT_SHIFT);
}

static int get_power_saving_mode(void) 
{
    return veml7700_get_light_sensor_value(COMMAND_PSM_EN,PSM_EN_MASK,PSM_EN_SHIFT);
}


static void set_power_saving_mode(int mode)
{
    veml7700_set_light_sensor_value(mode,COMMAND_PSM_EN,PSM_EN_MASK,PSM_EN_SHIFT);
}

static uint16_t get_als_reg_data(void)
{
    uint8_t rx_data[2] = {0};
    uint16_t r_value = 0;
 
    veml7700_read(COMMAND_ALS_DATA,rx_data);
    r_value = ((rx_data[1] << 8) | rx_data[0]);
    return r_value;
}

static float normalize_resolution(float value)
{
    switch (get_gain_value())
    {

        case ALS_GAIN_X2:
        value /= 2.0;
        break;
        case ALS_GAIN_d4:
            value *= 4.0;
            break;
        case ALS_GAIN_d8:
            value *= 8.0;
            break;
        case ALS_GAIN_X1:
        default:break;
        
    }
    switch (get_integration_time()){

        case ALS_INTEGRATION_25ms:
            value *= 4;
            break;
        case ALS_INTEGRATION_50ms:
            value *= 2;
            break;
        case ALS_INTEGRATION_200ms:
            value *= 2.0;
            break;
        case ALS_INTEGRATION_400ms:
            value *= 4.0;
            break;
        case ALS_INTEGRATION_800ms:
            value *= 8.0;
            break;
        case ALS_INTEGRATION_100ms:
        default:break;
    }
    return value;    

} 

float get_lux_data(void)
{
    //gain value==2
//    return normalize_resolution(get_als_reg_data() * 0.1152);//原有代码25ms
//    return normalize_resolution(get_als_reg_data() * 0.0576);//原有代码50ms
//    return normalize_resolution(get_als_reg_data() * 0.0288);//原有代码100ms
//    return normalize_resolution(get_als_reg_data() * 0.0144);//原有代码200ms
    return normalize_resolution(get_als_reg_data() * 0.0072);//原有代码400ms   这个比较准确
//    return normalize_resolution(get_als_reg_data() * 0.0036);//原有代码800ms
  
}

void veml7700_init(void)
{
    uint16_t default_value;
    get_veml7700_default_value(&default_value);
 
    if (default_value == 0x0001)
    {
        printf("Have Fined Veml7700!\r\n");
    }
    else
    {
        printf("Veml7700 not exsit %x\r\n",default_value);
    }

    set_power_enable(ALS_POWER_SHUTDOWN);
    printf("get_power_enable %d\r\n",get_power_enable());

    set_interrupt_enable(ALS_INTERRUPT_DISABLE);

    set_gain_value(ALS_GAIN_d8);
    printf("get_gain_value == %d\r\n",get_gain_value());

    set_integration_time(ALS_INTEGRATION_400ms);//请修改这里表示精度  400比较准确

    set_power_saving_mode(ALS_POWER_MODE_DISABLE);

    set_power_enable(ALS_POWER_ON);
}

VEML7700.h

#ifndef __VEML_7700_H__
#define __VEML_7700_H__

#define ENABLE_VEML7700  0

#define VEML_SLAVE_ADDR 0x20

#define COMMAND_ALS_DEFAULT_VALUE       0x01  
// 获得寄存器
#define COMMAND_ALS_GAIN                0x00  
#define ALS_GAIN_MASK                   0x1800  
#define ALS_GAIN_SHIFT                  11  
// ALS IT寄存器
#define COMMAND_ALS_IT                  0x00  
#define ALS_IT_MASK                     0x03C0  
#define ALS_IT_SHIFT                    6  
// ALS持久寄存器
#define COMMAND_ALS_PER                 0x00  
#define ALS_PER_MASK                    0x0030  
#define ALS_PER_SHIFT                   4  
// ALS INT EN Register
#define COMMAND_ALS_INT_EN              0x00  
#define ALS_INT_EN_MASK                 0x0002  
#define ALS_INT_EN_SHIFT                1  
// ALS SD Register
#define COMMAND_ALS_SD                  0x00  
 #define ALS_SD_MASK                     0x0001  
#define ALS_SD_SHIFT                    0  
// ALS Window High
#define COMMAND_ALS_WH                  0x01  
// ALS Window Low
#define COMMAND_ALS_WL                  0x02  
// ALS Power Save Mode
#define COMMAND_PSM                     0x03  
#define PSM_MASK                        0x0006  
#define PSM_SHIFT                       1  
// ALS Power Save Mode Enable
#define COMMAND_PSM_EN                  0x03  
#define PSM_EN_MASK                     0x0001  
#define PSM_EN_SHIFT                    0  
// ALS High Resolution Output Data
#define COMMAND_ALS_DATA                0x04  
//White Channel Output Data
#define COMMAND_WHITE_DATA              0x05  
// Interrupt Status
#define COMMAND_ALS_IF_L                0x06  
#define ALS_IF_L_MASK                   0x8000  
#define ALS_IF_L_SHIFT                  15  
#define COMMAND_ALS_IF_H                0x06  
#define ALS_IF_H_MASK                   0x4000  
#define ALS_IF_H_SHIFT                  14  

#define ALS_GAIN_X1                      0x0  
#define ALS_GAIN_X2                      0x1  
#define ALS_GAIN_d8                      0x2  
#define ALS_GAIN_d4                      0x3  

#define ALS_INTEGRATION_25ms             0xC  
#define ALS_INTEGRATION_50ms             0x8  
#define ALS_INTEGRATION_100ms            0x0  
#define ALS_INTEGRATION_200ms            0x1  
#define ALS_INTEGRATION_400ms            0x2  
#define ALS_INTEGRATION_800ms            0x3  

#define ALS_PERSISTENCE_1                0x0  
#define ALS_PERSISTENCE_2                0x1  
#define ALS_PERSISTENCE_4                0x2  
#define ALS_PERSISTENCE_8                0x3  

#define ALS_POWER_MODE_1                 0x0  
#define ALS_POWER_MODE_2                 0x1  
#define ALS_POWER_MODE_3                 0x2  
#define ALS_POWER_MODE_4                 0x3  

#define ALS_POWER_MODE_ENABLE            0x1  
#define ALS_POWER_MODE_DISABLE           0x0  

#define ALS_INTERRUPT_ENABLE             0x1  
#define ALS_INTERRUPT_DISABLE            0x0  

#define ALS_POWER_ON                     0x0  
#define ALS_POWER_SHUTDOWN               0x1  

void veml7700_init(void);
float get_lux_data(void);
#endif

调用上面的驱动程序进行数据获取的示例,只贴出部分程序,其他不方便贴出,望谅解:

main.c

/* USER CODE BEGIN 2 */
veml7700_init();

 OLED_Init();
    OLED_ColorTurn(0);//0正常显示,1 反色显示
    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显?
    OLED_Refresh();
    OLED_Clear();
    HAL_Delay(10);

    OLED_ShowString(0, 16 * 1, (u8 *)"max:", 16, 1);
    OLED_ShowString(0, 16 * 2, (u8 *)"min:", 16, 1);
    OLED_ShowString(0, 16 * 3, (u8 *)"val:", 16, 1);

    OLED_ShowString(96, 16 * 1, (u8 *)"lux", 16, 1);
    OLED_ShowString(96, 16 * 2, (u8 *)"lux", 16, 1);
    OLED_ShowString(96, 16 * 3, (u8 *)"lux", 16, 1);

    OLED_Refresh();

  /* USER CODE END 2 */


 while (1)
    {
        Light = get_lux_data();
            printf("%.2f\r\n", Light);
//定时器定时每100ms采集数据
        OLED_ShowNum(32, 48, Light, 5, 16, 1);//0~65535
        Light=Light*100;
        Light=(int)Light % 100;//获取后面两位小数点;
        OLED_ShowString(72, 16 * 3, (u8 *)".", 16, 1);
        OLED_ShowNum(76, 48, Light, 2, 16, 1);//0~65535
        OLED_Refresh();//OLED显示数据
}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
以下是基于STM32 HAL库的VEML6040传感器读取代码示例: ```c #include "main.h" #include "stdio.h" #include "stdlib.h" #include "string.h" #define I2C_ADDRESS 0x10<<1 // I2C地址为0x10 #define VEML6040_REG_CONF 0x00 // 寄存器配置地址 #define VEML6040_REG_UVA 0x07 // UVA数据寄存器地址 #define VEML6040_REG_DYN_RANGE 0x06 // 动态范围寄存器地址 I2C_HandleTypeDef hi2c1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); // 写入字节到VEML6040寄存器 void VEML6040_WriteByte(uint8_t reg, uint8_t val) { uint8_t data[2]; data[0] = reg; data[1] = val; HAL_I2C_Master_Transmit(&hi2c1, I2C_ADDRESS, data, 2, 100); } // 从VEML6040寄存器读取字节 uint8_t VEML6040_ReadByte(uint8_t reg) { uint8_t data; HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, reg, 1, &data, 1, 100); return data; } // 初始化VEML6040传感器 void VEML6040_Init() { VEML6040_WriteByte(VEML6040_REG_CONF, 0x00); // 将配置寄存器设置为默认值 VEML6040_WriteByte(VEML6040_REG_DYN_RANGE, 0x00); // 将动态范围设置为默认值 } // 读取VEML6040传感器的UVA数据 uint16_t VEML6040_ReadUVA() { uint8_t data[2]; HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, VEML6040_REG_UVA, 1, data, 2, 100); return (data[1] << 8) | data[0]; // 将读取的数据转换为16位整数 } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); VEML6040_Init(); // 初始化VEML6040传感器 while (1) { uint16_t uva = VEML6040_ReadUVA(); // 读取UVA数据 printf("UVA: %d\n", uva); // 输出UVA数据 HAL_Delay(1000); // 1秒延迟 } } // SystemClock_Config()和MX_GPIO_Init()省略,需要根据具体情况进行配置 // MX_I2C1_Init()的配置如下: void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } ``` 在此示例中,使用HAL库中的I2C_Master_Transmit()和I2C_Mem_Read()函数来进行I2C通信。首先进行初始化,然后通过VEML6040_WriteByte()和VEML6040_ReadByte()函数操作VEML6040寄存器,最后通过VEML6040_ReadUVA()函数读取UVA数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桂北研猛男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值