HS3003是温湿度计,I2C接口,这里给大家分享一下基本的驱动:
时钟配置
这里要说明一下,原来的RA4M2的晶振是24M,这次大赛拿到的开发板是12M的。
添加串口打印配置
添加i2c配置
串口参数配置
1、将debug改为swd,这样串口9才能配置为p109,p110接到开发板的CH340G上,详见原理图
2、按下图设置:
3、按下图配置串口的波特率、引脚、中断回调函数:
I2C详细参数设置:
1、按下图配置为I2C3,传感器hs3003可以直插在开发板的I2C插座上
2、原理图的引脚号:
代码编写:
1、生成工程代码后为了方便后面的模块重用,建立BSP文件夹:
2、新建debug_uart、hs3003文件夹。
里面分别新建Xbsp_debug_uart.c及bsp_debug_uart.h、hs3003.c、hs3003.h
3、工程添加bsp/debu_uart、bsp/hs3002目录如下:
添加相关的.c文件
4、添加.h目录:
#文件源码:
bsp_debug_uart.c
#include "bsp_debug_uart.h"
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;
}
}
#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"
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;
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)
#define RM_HS300X_MASK_HUMIDITY_UPPER_0X3F (0x3F)
#define RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC (0xFC)
#define RM_HS300X_MASK_STATUS_0XC0 (0xC0)
#define RM_HS300X_DATA_STATUS_VALID (0x00)
#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)
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
#define HS300X_TEMP_MULTY 0.010071415
#define HS300X_TEMP_MIN 40
#define HS300X_HUMD_MULTY 0.006163516
#define HS300X_MAX_ITERATION 100
#define HS300X_DELAY_MEASUREMENT 35
#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
}
效果如图:
这只是读出来了数据,对HS3003的详细数据处理、错误处理等没有做深一步的处理,有错误之处请大家指正。