瑞萨单片机论坛
直播中

华仔stm32

3年用户 2958经验值
擅长:嵌入式技术
私信 关注
[经验]

【RA4M2设计挑战赛】HS3003读取数据

HS3003是温湿度计,I2C接口,这里给大家分享一下基本的驱动:

时钟配置

image.png

这里要说明一下,原来的RA4M2的晶振是24M,这次大赛拿到的开发板是12M的。

添加串口打印配置

image.png

添加i2c配置

image.png

串口参数配置

1、将debug改为swd,这样串口9才能配置为p109,p110接到开发板的CH340G上,详见原理图

image.png

2、按下图设置:

image.png

3、按下图配置串口的波特率、引脚、中断回调函数:

image.png

I2C详细参数设置:

1、按下图配置为I2C3,传感器hs3003可以直插在开发板的I2C插座上

image.png

image.png

2、原理图的引脚号:

image.png

代码编写:

1、生成工程代码后为了方便后面的模块重用,建立BSP文件夹:

image.png

2、新建debug_uart、hs3003文件夹。

里面分别新建Xbsp_debug_uart.c及bsp_debug_uart.h、hs3003.c、hs3003.h

3、工程添加bsp/debu_uart、bsp/hs3002目录如下:

image.png

image.png

添加相关的.c文件

4、添加.h目录:

image.png

image.png

#文件源码:

bsp_debug_uart.c

#include "bsp_debug_uart.h"
/* 调试串口 UART4 初始化 */
void bsp_uart_init(void)
{
	fsp_err_t err = FSP_SUCCESS;
	err = R_SCI_UART_Open (&debug_uart_ctrl, &debug_uart_cfg);
	assert(FSP_SUCCESS == err);
}

/* 发送完成标志 */
volatile bool uart_send_complete_flag = false;
/* 串口中断回调 */
void debug_uart_callback (uart_callback_args_t * p_args)
{
	switch (p_args->event)
	{
		case UART_EVENT_RX_CHAR:
		{
		/* 把串口接收到的数据发送回去 */
		R_SCI_UART_Write(&debug_uart_ctrl, (uint8_t *)&(p_args->data), 1);
		break;
		}
		case UART_EVENT_TX_COMPLETE:
		{
		uart_send_complete_flag = true;
		break;
		}
		default:
		break;
	}
}	

/* 重定向 printf 输出 */
#if defined __GNUC__ && !defined __clang__
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
	(void)fd;
	R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
	while(uart_send_complete_flag == false);
	uart_send_complete_flag = false;
	return size;
}
#else
int fputc(int ch, FILE *f)
{
	(void)f;
	R_SCI_UART_Write(&debug_uart_ctrl, (uint8_t *)&ch, 1);
	while(uart_send_complete_flag == false);
	uart_send_complete_flag = false;
	return ch;
}
#endif

bsp_debug_uart.h

#ifndef __BSP_UART_H__
#define __BSP_UART_H__

#include "hal_data.h"
#include "stdio.h"
void bsp_uart_init(void);

#endif

hs3003.c

#include "hs3003.h"
#include "stdio.h"

/* Sequence */
typedef enum e_demo_sequence
{
    DEMO_SEQUENCE_1 = (1),
    DEMO_SEQUENCE_2,
    DEMO_SEQUENCE_3,
    DEMO_SEQUENCE_4,
    DEMO_SEQUENCE_5,
    DEMO_SEQUENCE_6,
} demo_sequence_t;

/* Callback status */
typedef enum e_hs3003_callback_status
{
    HS3003_CALLBACK_STATUS_WAIT = (0),
    HS3003_CALLBACK_STATUS_SUCCESS,
    HS3003_CALLBACK_STATUS_REPEAT,
} hs3003_callback_status_t;


#define SENSOR_TEMP_RANGE_MAX (80)
#define SENSOR_TEMP_RANGE_MIN (-10)
#define SENSOR_HUMI_RANGE_MAX (100)
#define SENSOR_HUMI_RANGE_MIN (0)

/* Definitions of Mask Data for A/D data */
#define RM_HS300X_MASK_HUMIDITY_UPPER_0X3F       (0x3F)
#define RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC    (0xFC)
#define RM_HS300X_MASK_STATUS_0XC0               (0xC0)

/* Definitions for Status Bits of A/D Data */
#define RM_HS300X_DATA_STATUS_VALID              (0x00) // Status-bit: Valid data

/* Definitions for Calculation */
#define RM_HS300X_CALC_STATIC_VALUE              (16383.0F)
#define RM_HS300X_CALC_HUMD_VALUE_100            (100.0F)
#define RM_HS300X_CALC_TEMP_C_VALUE_165          (165.0F)
#define RM_HS300X_CALC_TEMP_C_VALUE_40           (40.0F)
#define RM_HS300X_CALC_DECIMAL_VALUE_100         (100.0F)


/* See Developer Assistance in the project */
void g_comms_i2c_bus0_quick_setup(void);
void g_hs300x_sensor0_quick_setup(void);

void        start_demo(void);
static void demo_err(void);

static volatile hs3003_callback_status_t  hs3003_callback_status;

void g_comms_i2c_bus0_quick_setup(void)
{
    fsp_err_t err;
    err = R_SCI_I2C_Open(&hs3003_i2c3_ctrl, &hs3003_i2c3_cfg);
    assert(FSP_SUCCESS == err);
}


void hs3003_i2c_callback(i2c_master_callback_args_t * p_args)
{
	  if (HS3003_CALLBACK_STATUS_SUCCESS == p_args->event)
    {
        hs3003_callback_status = HS3003_CALLBACK_STATUS_SUCCESS;
    }
    else
    {
        hs3003_callback_status = HS3003_CALLBACK_STATUS_REPEAT;
    }
}

void start_hs3003(void)
{
	fsp_err_t err;
	uint8_t r_buf[4] = {0};
    uint16_t humi, temp;
    float    tmp_f   = 0.0;
	uint8_t data[2] = {0x00,0x00};
	demo_sequence_t         sequence = DEMO_SEQUENCE_1;
	g_comms_i2c_bus0_quick_setup();
	while(1)
	{
		err = R_SCI_I2C_Write(&hs3003_i2c3_ctrl,data,1,0);
		R_BSP_SoftwareDelay(40000,BSP_DELAY_UNITS_MICROSECONDS);
		err = R_SCI_I2C_Read(&hs3003_i2c3_ctrl,&r_buf,4,1);
		if(err == FSP_SUCCESS)
		{
        printf("0x%X,0x%X,0x%X,0x%X\n", r_buf[0], r_buf[1], r_buf[2], r_buf[3]);
        printf("state:%x\n", r_buf[0] & RM_HS300X_MASK_STATUS_0XC0);
        if ((r_buf[0] & RM_HS300X_MASK_STATUS_0XC0) != RM_HS300X_DATA_STATUS_VALID)
        {
            printf("转换时间不哆");
        }

        humi = (r_buf[0] & RM_HS300X_MASK_HUMIDITY_UPPER_0X3F) << 8 | r_buf[1];
        temp = (r_buf[2] << 8 | (r_buf[3] & RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC)) >> 2;

        tmp_f = (float)humi;
        tmp_f = (tmp_f * RM_HS300X_CALC_HUMD_VALUE_100) / RM_HS300X_CALC_STATIC_VALUE;
				printf("湿度: %.2f\n",tmp_f );

        tmp_f = (float)temp;
        tmp_f = ((tmp_f * RM_HS300X_CALC_TEMP_C_VALUE_165) / RM_HS300X_CALC_STATIC_VALUE) - RM_HS300X_CALC_TEMP_C_VALUE_40;
				printf("温度: %.2f\n", tmp_f);
    }
    else {
        printf("读取传感器出错!\n");
    }
		
		R_BSP_SoftwareDelay(1000000,BSP_DELAY_UNITS_MICROSECONDS);
	}
	
}

hs3003.h

#ifndef __HS3003_H
#define __HS3003_H
#include "hal_data.h"
#define HS300X_ADR  0x44                        // look at datasheet
#define HS300X_TEMP_MULTY           0.010071415 // look at datasheet
#define HS300X_TEMP_MIN             40          // look at datasheet
#define HS300X_HUMD_MULTY           0.006163516 // look at datasheet
#define HS300X_MAX_ITERATION        100
#define HS300X_DELAY_MEASUREMENT    35          // typical on datasheet 16.90 ms, rounded up a little (35ms = 1 try)
#define HS300X_DELAY_ITERATION      1

#define HS300X_STALE_DATA           2
#define HS300X_OK                   1
#define HS300X_ERROR_SENSOR_BUSY    0
#define HS300X_ERROR_COLLISION_I2C  -1

void start_hs3003(void);

#endif

hal_enty.c中添加头文件引用以及如下代码:

#include "hal_data.h"
#include "bsp_debug_uart.h"
#include "hs3003.h"

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */
		bsp_uart_init();
		printf("start...\r\n");
	printf("end");
		start_hs3003();
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

效果如图:

image.png

这只是读出来了数据,对HS3003的详细数据处理、错误处理等没有做深一步的处理,有错误之处请大家指正。

更多回帖

发帖
×
20
完善资料,
赚取积分