0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何利用GD32F310读取HDC1080环境温湿度

科技观察员 来源:兆易创新GD32 MCU 作者:cain 2022-04-15 15:23 次阅读

我拿到的开发板实际板载的MCUGD32F310G8,QFN28pin封装,基于ARM CORTEX M4内核,主频72MHz,芯片内置64KB flash,8KB SRAM,两路I2C外设。

poYBAGJZHUuANGnBAAFPRa5cvtA192.png

本次试用目的是利用GD32F310的I2C0实现对HDC1080的初始化及读取环境温湿度,并利用UART口在电脑上显示出来。

1、新建工程

①首先建立一个新的项目文件夹,并在此文件夹下建立对应子文件夹,我建立的文件如下图所示,这个依个人习惯会有不同:

pYYBAGJZHUaANI-lAABHV_LSPPU501.png

② Document文件夹中存放对项目的说明文件readme.txt;将系统支持包中的GD32F3x0_Firmware_Library_V2.2.0/Firmware文件夹中的内容复制到Libraries文件夹中;Listing/Output文件夹用于存放项目编译时生成的目标文件及list文件,在MDK的魔术棒中进行设置路径;users文件夹中存放main文件及我们自已写的代码;Project文件夹中存放MDK项目文件;

③打开MDK keil5,首先要先导入GD32F310G文件支持包。

poYBAGJZHUGAYE_hAAIuprokS6U913.png

④建立新的项目,选择所使用的MCU,我们选择GD32F330G8,如下图所示

pYYBAGJZHT2ACcnKAAIiA6Rz0Z4597.png

⑤新项目中建立如下文件组,并导入启动文件和外设支持包。

poYBAGJZHTqAArcDAAHD3JCcZ-o737.png

⑥点击魔术棒工具进行项目设置。在C/C++选项中添加include文件路径;

pYYBAGJZHTaAQD2xAAFXbSyTJts568.png

⑦点击Debug选项进行GDLink的设置,要选择CMSIS_DAP Debugger,并将Reset and Run打勾。

pYYBAGJZHTCAYknXAAFsWb10O54560.png

⑧这样整个项目的配置基本就结束了,可以在main.c文件中建立一个空循环,编译测试项目建立是否正确无误。

2、硬件映射

硬件映射的目的是按目前的硬件连接建立.h文件,如下图所示:

pYYBAGJZHSyARUsWAAKHXC6G9oM705.png

因此基于开发板I2C0采用的是PB6/PB7引脚,因为需要打印读出的值,UART0使用的是PA9/PA10引脚。

3、编写代码

①UART0初始化和printf函数重定向:

void UART_TypeInit(void)
{
    gpio_deinit(UART0_GPIO_PORT);
    usart_deinit(USART0);
    rcu_periph_clock_enable(UART0_GPIO_PORT_CLK);
    gpio_mode_set(UART0_GPIO_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,UART0_TX_PIN | UART0_RX_PIN);
    gpio_output_options_set(UART0_GPIO_PORT,GPIO_OTYPE_OD,GPIO_OSPEED_MAX,UART0_TX_PIN | UART0_RX_PIN);
    gpio_af_set(UART0_GPIO_PORT,GPIO_AF_1,UART0_TX_PIN | UART0_RX_PIN);
    
    rcu_periph_clock_enable(UART0_CLK);
    usart_baudrate_set(USART0,UART0_Baudrate);
    usart_parity_config(USART0,USART_PM_NONE);
    usart_word_length_set(USART0,USART_WL_8BIT);
    usart_stop_bit_set(USART0,USART_STB_1BIT);
    usart_enable(USART0);
    usart_transmit_config(USART0,USART_TRANSMIT_ENABLE);
    usart_receive_config(USART0,USART_RECEIVE_ENABLE);
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0,USART_FLAG_TBE)); 
        
    return ch;
}

②I2C0外设初始化:

void I2C0_TypeInit(void)
{
    gpio_deinit(I2C0_GPIO_PORT);
    i2c_deinit(I2C0);
    rcu_periph_clock_enable(I2C0_GPIO_PORT_CLK);
    gpio_mode_set(I2C0_GPIO_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,I2C0_SCL_PIN | I2C0_SDA_PIN);
    gpio_output_options_set(I2C0_GPIO_PORT,GPIO_OTYPE_OD,GPIO_OSPEED_MAX,I2C0_SCL_PIN | I2C0_SDA_PIN);
    gpio_af_set(I2C0_GPIO_PORT,GPIO_AF_1,I2C0_SCL_PIN | I2C0_SDA_PIN);
    
    rcu_periph_clock_enable(I2C0_CLK);
    i2c_clock_config(I2C0,I2C0_Frequence,I2C_DTCY_2);
    i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,I2C0_OWN_Address);
    i2c_enable(I2C0);
    i2c_ack_config(I2C0,I2C_ACK_ENABLE);
}

③读寄存器操作:

void  I2C0_Register_Read(uint8_t* B_buffer, uint8_t read_address,uint16_t number_of_byte)
{
     /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));

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

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

    if(number_of_byte < 3){
        /* disable acknowledge */
        i2c_ack_config(I2C0,I2C_ACK_DISABLE);
    }
    
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
    
    if(1 == number_of_byte){
        /* send a stop condition to I2C bus */
        i2c_stop_on_bus(I2C0);
    }
    
    /* 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(I2C0, I2C_FLAG_BTC));

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

    i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
}

④写寄存器操作:

void I2C0_Byte_Write(uint8_t* P_buffer, uint8_t write_address)
{
    uint8_t i;
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));

    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C0);

    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));

    /* send slave address to I2C bus */
    i2c_master_addressing(I2C0, HDC1080_Addr, I2C_TRANSMITTER);

    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));

    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);

    /* wait until the transmit data buffer is empty */
    while(SET != i2c_flag_get(I2C0, I2C_FLAG_TBE));

    /* send the EEPROM's internal address to write to : only one byte address */
    i2c_data_transmit(I2C0, write_address);

    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
    
    for(i=0;i<2;i++)
    {

        /* send the byte to be written */
        i2c_data_transmit(I2C0, *(P_buffer+i)); 

        /* wait until BTC bit is set */
        while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
    
    }

    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C0);

    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2C0)&0x0200);
}

⑤对HDC1080进行初始化并读取其ID:

void HDC1080_Init(void)
{
    uint8_t    IDBuffer[2]={0};
    uint8_t InitSetup[2]={0x90,0x00};
    uint32_t SID[3]={0},MID=0,DID=0;
    I2C0_Byte_Write(InitSetup,CONFIGURATION);
    delay_1ms(20);
    
    I2C0_Register_Read(IDBuffer,DEVICE_ID,2);
    DID = (((uint32_t)IDBuffer[0])<<8 | IDBuffer[1]);
    printf("The DeviceID is 0x%x\n\r",DID);
    I2C0_Register_Read(IDBuffer,MANUFACTURE_ID,2);
    MID = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]);
    printf("The ManufactureID is 0x%x\n\r",MID);
    I2C0_Register_Read(IDBuffer,FIRST_SID,2);
    SID[0] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]); 
    I2C0_Register_Read(IDBuffer,MID_SID,2);
    SID[1] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]);
    I2C0_Register_Read(IDBuffer,LAST_SID,2);
    SID[2] = ((uint16_t) IDBuffer[0]<<8 | IDBuffer[1]);
    printf("The First bytes of the serial ID of the part is 0x%x\n\r",SID[0]);
    printf("The MID bytes of the serial ID of the part is 0x%x\n\r",SID[1]);
    printf("The Last bytes of the serial ID of the part is 0x%x\n\r",SID[2]);
    printf("\n\r");
}

⑥读取温湿度值并转换成十进制显示:

void readSensor(void)
{
  //holds 2 bytes of data from I2C Line
  uint8_t Buffer_Byte[2];

  //holds the total contents of the temp register
  uint16_t temp,hum;

  //holds the total contents of the humidity register
  double temperature=0,humidity=0 ;
    
    I2C0_Register_Read(Buffer_Byte,T_MEASUREMENT,2);
    temp = (((uint32_t)Buffer_Byte[0])<<8 | Buffer_Byte[1]);
    temperature = (double)(temp)/(65536)*165-40;
    printf("The temperature is %.2f\n\r",temperature);
    
    I2C0_Register_Read(Buffer_Byte,RH_MEASUREMENT,2);
    hum = (((uint32_t)Buffer_Byte[0])<<8 | Buffer_Byte[1]);
    humidity = (double)(hum)/(65536)*100;
    printf("The humidity is %.2f%%\n\r",humidity);    
}

⑦main函数:

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* configure periphreal */
  systick_Init();
    LED_TypeInit();
//    NVIC_config();
//    KEY_EXTI_TypeInit();
    UART_TypeInit();
    I2C0_TypeInit();
    printf("**********DEMO START**********\n\r");
    printf("******************************\n\r");
    HDC1080_Init();

    while(1) 
    {
        readSensor();
        delay_1ms(1000);
    }
}

4、编译下载

①Build项目文件:

pYYBAGJZHR-Aau-GAAF4k5tcoFo234.png

②没有错误,直接下载到开发板中,可以打开串口看到读出温湿度每隔1S读一次并打印出来,与环境温度计比较取值还是比较准确的。

pYYBAGJZHRuAMxGEAAX3roeRMRU159.png

pYYBAGJZHReAKZFCAAI6fFkP86M893.png

5、试用总结

GD32F310G8芯片采用4x4 QFN28封装,结构可以设计相当紧凑,软件开发资源也是很丰富,虽然功能不算特别强大,但主流的外设基本都有囊括,在目前国产替代的大环境之下,应用前景还是相当广泛的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1346

    浏览量

    120811
  • uart
    +关注

    关注

    22

    文章

    1158

    浏览量

    99952
收藏 人收藏

    评论

    相关推荐

    【TI SimpleLink SensorTag试用体验】6.温湿度传感器HDC1000

    HDC1000的pcb layout有一定的要求芯片周围pcb板需要一定的空隙来减少 thermal mass热质量,以加快对环境变化的响应这是tag的HDC1000驱动程序温湿度
    发表于 05-02 17:43

    hdc1080读取温湿度值为0

    hdc1080可以正常读取设备ID,但是当读取温湿度值时总是0,配置寄存器值配置为0x1000,是默认值,,请问该如何解决啊?
    发表于 03-05 06:26

    请问这段基于msp430的hdc1080传感器的驱动程序如何读取温湿度数值?我需要将温湿度用oied屏显示出来

    ; 0x00FF);for(i=20;i>0;i--){MyApp_I2cStart( );MyApp_I2cSendByte( dev_addr); // HDC1080 Addr + Wif
    发表于 03-20 15:21

    MSP430FR2433无法读取HDC1080

    我在尝试了硬件IIC读取无果后,尝试模拟IIC读取,但读到的始终都为0,实在不解,读HDC1080的0XFE的ID也为0,有没有用过的大佬交流一下
    发表于 07-02 08:49

    HDC1080温湿度传感器的使用步骤

    HDC1080温湿度传感器的驱动链接(函数都封装好了,稍微改改就能用了):没有积分的小伙伴给我发消息或者留下邮箱!!白嫖了网上这么多资料也该回馈回馈了!HDC1080使用步骤:1.编写I2C驱动
    发表于 11-25 06:14

    详解HDC1080温湿度传感器

    HDC1080是什么? HDC1080温湿度传感器有哪些功能和典型应用呢?
    发表于 01-18 06:08

    HDC1080温湿度驱动IIC/I2C/STM32的过程是怎样的?

    HDC1080温湿度驱动IIC/I2C/STM32的过程是怎样的?
    发表于 02-28 06:41

    基于GD32F310开发板的AD多通道交流采样计算

    1、基于GD32F310开发板的AD多通道交流采样计算  很幸运能够有机会试用兆易公司的GD32F310开发板。本次使用中,我将使用开发板连接我之前的采样电路(之前自己做的板件)对交流电压信号进行
    发表于 09-30 14:29

    基于GD32F310开发板移植FreeRTOS的步骤详解

    1、GD32F310移植FreeRTOS  开发板信息  我们在来看看关于这款开发板:  GD32F310K-START 评估板使用 GD32F310K8T6 作为主控制器。LED的引脚是PA8
    发表于 10-10 18:07

    利用GD32F310的I2C0实现对HDC1080的初始化及读取环境温湿度

    ,芯片内置64KB flash,8KB SRAM,两路I2C外设。  本次试用目的是利用GD32F310的I2C0实现对HDC1080的初始化及读取
    发表于 11-08 16:24

    GD32F310开发板上移植FreeRTOS的步骤相关资料分享

    1、GD32F310移植FreeRTOS  环境说明  首先我先说明我的环境:  我使用keil5的版本是V5.36,电脑系统是WIN10,使用的固件库版本是从官网下载的最新版2.2.0,我所移植
    发表于 11-08 16:58

    HDC1080 HDC1080 具有温度传感器的低功耗、高精度数字湿度传感器

    电子发烧友网为你提供TI(ti)HDC1080相关产品参数、数据手册,更有HDC1080的引脚图、接线图、封装手册、中文资料、英文资料,HDC1080真值表,HDC1080管脚等资料,
    发表于 09-21 16:46
    <b class='flag-5'>HDC1080</b> <b class='flag-5'>HDC1080</b> 具有温度传感器的低功耗、高精度数字<b class='flag-5'>湿度</b>传感器

    温湿度记录仪如何读取温湿度记录仪的操作介绍

    等在运输过程中的温度状况进行实时自动监测。 那么温湿度记录仪到底怎么读取数据? 一、显示屏读取数据 温湿度记录仪屏幕直接实时显示监测数据,简单方便,数据明了,一眼就能看到结果。 二、U
    发表于 06-28 16:31 3572次阅读

    HDC1080传感器使用

    HDC1080温湿度传感器的驱动链接(函数都封装好了,稍微改改就能用了):没有积分的小伙伴给我发消息或者留下邮箱!!白嫖了网上这么多资料也该回馈回馈了!HDC1080使用步骤:1.编写I2C驱动
    发表于 11-16 21:06 22次下载
    <b class='flag-5'>HDC1080</b>传感器使用

    MSP432 P401R 单片机 读取DHT11 串口发送温湿度 OLED显示温湿度 温湿度检测

    MSP432P401R读取DHT11串口发送温湿度OLED显示温湿度
    发表于 12-16 16:54 33次下载
    MSP432 P401R 单片机  <b class='flag-5'>读取</b>DHT11 串口发送<b class='flag-5'>温湿度</b> OLED显示<b class='flag-5'>温湿度</b> <b class='flag-5'>温湿度</b>检测