| 本帖最后由 swtman 于 2025-8-15 16:57 编辑 
 #申请原创#
 
 @21小跑堂
 
 
 
 高精度无线人体温度仪1. 前言 手中持有一款瑞萨的开发板,已经吃灰很久了。关于瑞萨开发板的使用也忘记了好多,为了发挥一下开发板的余热,同时也重新熟悉一下瑞萨开发板的使用和开发过程。因此想基于这个开发板做一个小而实用的项目。一个高精度无线温度仪由此诞生了。
 项目目标:
 1-精度高,小于0.1度;
 2-带有显示屏,方便及时查看;
 3-最重要的是支持蓝牙传输,支持BLE和SPP,既可以连接手机,也可以连接电脑。
 2. 最终效果图
 从无数的坑里终于爬出来了,最终完成目标,实现最终效果如下:
 
 
 
 
 
 图 1 项目验证实物图 
 3. 系统硬件设计后续手机端,若是能做成更好的APP适配,效果会更好。硬件方面可以集成一个小盒子,会更方便收纳。本项目需要使用一些外设和模块,因此需要进行硬件设计。
 3.1. 系统整体设计
 主控采用RA-Eco-RA4M2-100PIN-V1.0开发板,通过IIC采集温度传感器数据,然后通过OLED显示屏显示计算的人体温度,并通过无线模块将数据发送给电脑或者手机等终端。开发通过LED显示系统正常运行。
 
 
 图 2 整体硬件架构图3.2. RA4M2开发板 RA-Eco-RA4M2-100PIN-V1.0是一款基于100MHz Arm® Cortex®-M33内核架构的核心板,主控芯片为R7FA4M2AD3CFP。 RA4M2 32 位微控制器 (MCU) 产品群使用支持 TrustZone 的高性能 Arm® Cortex®-M33 内核。 与片内的 Secure Crypto Engine (SCE) 配合使用,可实现安全芯片的功能。 RA4M2 采用高效的 40nm 工艺,由灵活配置软件包 (FSP) 这个开放且灵活的生态系统概念提供支持,FSP 基于 FREERTOS 构建,并能够进行扩展,以使用其他实时操作系统 (RTOS) 和中间件。 RA4M2 适用于物联网应用的需求, 如多样化的通信功能、面向未来应用的安全功能、大容量嵌入式 RAM 和较低的运行功耗(从闪存运行 CoreMark® 算法时功耗低至 81µA/MHz)。
 以上是官方的介绍,这个开发板的相关接口和资源介绍如下:
 1个复位按键,2个用户按键,2个触摸按键,3个LED,2个PMOD接口,板载USB转TTL模块,可用于串口通信和烧录,板载SWD接口,方便用户调试与下载,支持 TrustZone 的 100MHz Arm Cortex-M33安全芯片的功能,512kB 闪存、64kB SRAM(支持奇偶校验)以及 64kB ECC SRAM,8KB 数据闪存,提供与 EEPROM 类似的数据存储功能,1kB 休眠用 SRAM,电容式触摸传感单元 (CTSU),全速 USB 2.0,支持主机模式和设备模式,CAN 2.0B,四线 SPI,SCI(UART、简单 SPI、简单 I2C),独立SPI/I2C 多主接口,SDHI 和 MMC。
 本项目只是使用部分接口和资源。
 3.3. OLED显示屏
 0.96寸OLED显示屏窄白光IIC接口,屏幕分辨率为128X64。这个屏幕从立创商城购买来。链接如下:
 https://item.szlcsc.com/5960631.html?spm=sc.ols.it2-1___sc.hm.hd.dd&lcsc_vid=TgJXAgVTFgdaUVFeQVZaBAFfFAJbU11e**MUV0FRlQxVlNTQlBdX1xQQFRaUDtW
 相关参数如下:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps76.jpg 
 图 3 OLED显示屏采购 
 3.4. 温度传感器
 采用敏源的M1820ZT5,该传感器具有±0.1℃精度、16bitADC、超低功耗、1-wire数字接口。是一款高精度温度传感芯片。在立创商城上购买,链接如下:
 https://item.szlcsc.com/5750395.html?spm=sc.ols.it0-1___sc.hm.hd.dd&lcsc_vid=TgJXAgVTFgdaUVFeQVZaBAFfFAJbU11e**MUV0FRlQxVlNTQlBdX1xQQFRaUDtW
 该高精度数字温度探头,探头直径5MM,线长1米,内部芯片型号M1820Z,最高测温精度±0.1℃@0~+50℃,1-Wire协议数字输出,16bit ADC 0.004℃分辨率,10.5ms快速测温,1.8V~5.5V宽电压供电,工作温度范围-20℃~+85℃(芯片工作温度范围-70℃~+150℃)。选择这款的原因就是精度很高啊。测量也方便哦。
 
 
 图 4 M1820ZT5温度传感器3.5. 无线模块
 基于KT6368的蓝牙模块,支持SPP和BLE双模。不仅可以可以连接手机,也可以连接电脑。该模块板载PCB天线。通过串口控制收发数据。供电:3.3V。该模块采用立创开源的硬件制作,相关开源链接如下:
 https://oshwhub.com/swtblue/kt86368akt6328a-bluetooth-module
 具体实物如下:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps78.jpg 图 5 无线模块  3.6. LED灯 这里直接使用开发板上的3个LED灯,不再详述,相关原理图如下图所示:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps79.jpg 图 6 LED控制IO
4. 系统软件设计需要对相关GPIO进行配置。 通过RASC进行初始参数配置,基于keil MDK平台使用C语言进行编码。
 4.1. OLED的IIC配置与关键代码实现
 OLED使用的IIC的IO分别是SDA:P408、SCL:P409。为了屏幕刷新的更快,这里配置速度为FAST-MODE。大约400KBPS。需要注意选择IIC的通道,SLAVE的地址:0x3c,并命名好回调函数。具体配置如下图所示:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps80.jpg 
 图 7 OLED的IIC配置 
 4.2. 温度传感器的IO配置与关键代码实现回调函数实现如下: i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED; 
 void sci_i2c_master_callback(i2c_master_callback_args_t *p_args) 
 { 
     i2c_event = I2C_MASTER_EVENT_ABORTED; 
     if (NULL != p_args) 
     { 
         /* capture callback event for validating the i2c transfer event*/ 
         i2c_event = p_args->event; 
     } 
 } 
 int  timeout_ms = 100; 
 当然这里还有屏幕的驱动代码等,由于篇幅所限,不再详述。该屏幕的使用属于常规操作。具体可以查看工程源码。 
 在这里需要注意一下汉字取模,我采用的是在线进行汉字取模。网站链接如下: 
 https://www.23bei.com/tool/216.html 
 我需要使用的汉字是:高精度无线人体温度仪。通过在线取模,参数配置如下图所示:该传感器单线通信,因此只需要一个IO:P115,该管脚需要外部4.7K的电阻3.3V进行上拉。否则通信会有问题。管脚P115的软件配件如下图所示:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps82.jpg 图 9温度传感器通信IO 
 4.3. LED的GPIO配置与关键代码实现该传感器的驱动代码官方已经写好,只需要对IO和延时程序重新移植即可。 相关需要自行配置和修改的函数如下: 
 /*********用户可自行配置us级延时************/ 
 #define ow_Delay_us(N)   R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MICROSECONDS) 
 #define DELAY_Ms(N)    R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MILLISECONDS) 
 #define ow_DQ_set()     { R_IOPORT_PinWrite(&g_ioport_ctrl, DQ_PIN,BSP_IO_LEVEL_HIGH); } 
 #define ow_DQ_reset()   { R_IOPORT_PinWrite(&g_ioport_ctrl, DQ_PIN,BSP_IO_LEVEL_LOW);} 
 uint8_t ow_DQ_get(void) 
 { 
 bsp_io_level_t x=0; 
 if(R_IOPORT_PinRead(&g_ioport_ctrl,DQ_PIN,&x)==FSP_SUCCESS){ 
 return x; 
 } 
 return 1; 
 } 
 void OW_Init(void) 
 { 
 ow_DQ_set(); 
 } 
这里需要配置三个IO分别是P405、P404、P002分别对应LED1、LED2、LED3。配置起来非常简单,将设置为输出即可,配置分别如下图所示:
 
 
 
 
 
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps85.jpg 
 
 
 图 10 LED控制IO配置
4.4. 无线模块的UART接口配置与关键代码实现具体代码实现控制LED亮灭非常简单,如下所示:            R_BSP_SoftwareDelay(250, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT 
            R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_LOW); 
            R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_HIGH); 
            R_BSP_SoftwareDelay(250, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT 
            R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_HIGH); 
            R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_LOW); 
 无线蓝牙模块的接口为串口,因此需要使用1个UART。相关配置如下:
 
 
 
 图 11 无线模块UART通信接口配置 
 相关的回调函数需要自己进行实现,相关代码如下: fsp_err_t err = FSP_SUCCESS; 
 unsigned char send_buff[100]; 
 volatile bool uart_send_complete_flag = false; 
 void g_uart9_callback (uart_callback_args_t * p_args) 
 { 
     if(p_args->event == UART_EVENT_TX_COMPLETE) 
     { 
         uart_send_complete_flag = true; 
     } 
 } 
 为了方便调试,和打印相关信息。这里对printf函数进行了重定向,相关代码如下所示: 
 /* 重定向 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_uart4_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(&g_uart9_ctrl, (uint8_t *)&ch, 1); 
    while(uart_send_complete_flag == false); 
    uart_send_complete_flag = false; 
    return ch; 
 } 
 #endif 
 4.5. SWD调试与下载接口配置
 由于我手头上有j-link调试器,所以配置SWD接口,不仅能适配我的调试器,还可以节省IO。具体配置如下图所示:
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps87.jpg 图 12 SWD调试下载接口配置 4.6. 主程序设计
 由于在RASC中已经配置了相关的外设,这里只需要调用即可。因此主程序实现如下:
 /*******************************************************************************************************************//**
 * 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 */
 
 float T=0;
 unsigned char str[16]={0};
 err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
 assert(FSP_SUCCESS == err);
 /* IIC初始化*/
 err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
 assert(FSP_SUCCESS == err);
 WriteCmd();//OLED初始化
 OLED_Clear();//清屏
 //高精度无线人体温仪
 OLED_ShowCHinese(0,1,0);//高
 OLED_ShowCHinese(16,1,1);//精
 OLED_ShowCHinese(32,1,2);//度
 OLED_ShowCHinese(48,1,3);//无
 OLED_ShowCHinese(64,1,4);//线
 OLED_ShowCHinese(80,1,7);//温
 OLED_ShowCHinese(96,1,2);//度
 OLED_ShowCHinese(112,1,8);//仪
 OW_Init();
 SetConfig(CFG_MPS_Single,CFG_Repeatbility_High);
 while(1)
 {
 //printf("kwin\r\n");
 
 T= OutputTemp();
 sprintf(str,"%6.2fC",T);
 printf("%s",str);
 OLED_ShowString(32,5,str,16);
 
 R_BSP_SoftwareDelay(250, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
 R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_LOW);
 R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_HIGH);
 R_BSP_SoftwareDelay(250, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
 R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_HIGH);
 R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_LOW);
 }
 #if BSP_TZ_SECURE_BUILD
 /* Enter non-secure code */
 R_BSP_NonSecureEnter();
 #endif
 }
 代码编译成功后,会有如下提示:
 
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps88.jpg 
 图 13 代码编译成功提示 
 程序调试,可以观测到串口输出如下:下载之前需要进行配置: file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps89.jpg
 
 
 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml13540/wps90.jpg 
 图 15 程序调试输出验证
说明程序运行正常。温度输出为实验室环境温度。 最终的效果图参见第二章节的最终成品图。 
 系统演示可以查看如下链接: 
 https://www.bilibili.com/video/BV1WUbJzpEgQ/?vd_source=e36622a05269c0356d6cd566056a2488 
 
 
 
 
 
 
 |