瑞萨单片机论坛
直播中

jf_37047872

3年用户 36经验值
擅长:电源/新能源 嵌入式技术 处理器/DSP
私信 关注

【RA4M2设计挑战赛】基于瑞萨RA4M2开发板设计的多参数物联网采集终端(作品提交)

本帖最后由 jf_37047872 于 2023-3-5 17:06 编辑

【作品概述】

本次参赛作品是一款基于瑞萨RA4M2开发板设计的多参数物联网采集终端,主要用于研究温湿度与光照对植物生长的影响。根据比赛规则,本次主要采用瑞萨R7FA4M2AD3CFP作为主控芯片,通过瑞萨HS3003低功耗MEMS高精度传感器采集温湿度数据,通过瑞萨ISL29035传感器采集环境光照强度数据,通过Dialog半导体公司(瑞萨电子全资子公司)的DA16200超低功耗WIFI模块实现相关数据定时上传至OneNet中国移动物联网开放平台,同时可通过0.96寸OLED显示屏实时查看终端当前数据。考虑到物联网采集终端部署环境可能缺少外接电源供应,本次设计采用2节18650锂电池作为移动电源,通过LDO及DCDC提供5V及12V各5组系统电源接口,带有电源电量指示功能,同时还通过USB Type-C接口实现5V输入升压充电功能。考虑到采集终端固件升级的便利性需求,实现了USB程序自升级功能。


【应用背景】

随着现代农业技术的不断进步,越来越多的植物可以通过人工方式进行培育和种植。在各类环境因素中,温湿度和光照强度对于植物的生长具有非常显著的影响,而且不同的植物对于温湿度和光照强度的要求更是具有很大的差异。在大面积、多品种开展同步对比试验的情况下,依靠人工方式每天记录这些环境参数已经几乎不可能,基于“物联网平台+边缘计算+传感器”的解决方案已成为该领域的标配。虽然应用需求旺盛,市场前景广阔,但目前在能耗、采样精度、通信、存储、便携性及边缘计算能力等方面依然存在诸多问题需要技术解决。

【方案设计】


1、整体架构:本项目隶属于智慧农业物联网解决方案的一部分,重点解决终端数据采集问题。详见下图。

2、硬件框图:本项目涉及的硬件包括独立电源、主控、温湿度传感器、光照强度传感器、WIFI通信模块和OLED显示屏等部分,下图展示了具体的系统结构、硬件型号和主要技术参数。

3、软件框架:本项目以“RASC配置器+KEILv5”方式开发,依托瑞萨官方提供的FSP(灵活软件配置包)代码框架,快速实现各类应用层逻辑及功能,整体框架及应用层各模块功能说明如下图所示。


【成果展示】

1、实现功能清单:

(1)电源模块:2节18650锂电池独立供电,提供5组LDO降压5V输出接口及5组DCDC升压12V输出接口,提供TYPE-C充电接口,5V升压充电,提供5段电量指示功能,带USB接口OVP。本模块通过自制PCB方式设计制作。

(2)温湿度测量模块:实现温湿度参数测量、分辨率设置、获取当前传感器分辨率、获取传感器ID、切换工作模式(配置模式及工作模式)等功能。通过单一I2C硬件接口,以“挂载多个从设备”方式与主控通信,通过从设备地址切换实现多设备通信功能。

(3)光照强度测量模块:实现光照强度参数测量、单字节读写数据、批量读写数据、工作模式切换、ADC分辨率设置、设备ID获取等功能。由于本模块与温湿度测量模块从设备硬件地址相同,只能以INT引脚的中断信号通过切换模块工作模式实现单一I2C硬件接口多个从设备同时挂载目标。

(4)OLED显示模块:实现命令与数据的发送、屏幕开启和关闭、数据与字符显示、清屏等功能。根据项目目标,通过自定义屏幕显示字库,实现界面显示框架及各项参数动态显示。通过单一I2C硬件接口,以“挂载多个从设备”方式与主控通信,通过从设备地址切换实现多设备通信功能。

(5)WIFI通信模块:实现设备初始化、模式设置(AP、STA及AP+STA模式)、联网、数据发送、数据获取等功能。根据项目目标,通过调用互联网API接口实现北京时间获取;由于接口返回数据采用JSON格式,通过将KEIL官方JANSSON库移植到RA4M2主控,实现了结果数据解析。实现相关传感器测量结果实时传送至中移物联OneNET平台。

2、功能模块代码展示:考虑到本文篇幅有限,且网页编辑器代码展示效果有限(无缩进格式支持),本部分仅展示部分模块代码,完整KEIL工程及代码请下载附件。

(1)HS3003模块:

  1. /**********************************************************************************************************************
  2. 模块说明
  3. **********************************************************************************************************************/
  4. /*
  5. 描述:本模块为HS3003温湿度传感器驱动程序,该传感器采用I2C接口通信;HS3003硬件地址:0x44
  6. MCU接口描述:I2C接口选择:I2C3;I2C引脚:SDA:0409;SCL:0408
  7. 作者:yagi@2023-2-18
  8. 转载请注明出处,版权由@yagi所有
  9. */

  10. /**********************************************************************************************************************
  11. 文件引用
  12. **********************************************************************************************************************/
  13. #include "bsp_hs3003_i2c.h"
  14. #include "bsp_sci_i2c.h"
  15. #include "bsp_api.h"
  16. #include "common_data.h"
  17. #include "hal_data.h"

  18. //#define HS300X_DEBUG



  19. /**********************************************************************************************************************
  20. 全局变量定义
  21. **********************************************************************************************************************/
  22. double Humidity = 0.0;                                                                                                                        //湿度测量结果(百分数)
  23. double Temperature = 0.0;                                                                                                           //温度测量结果
  24. extern volatile bool I2C_send_complete_flag;                                //I2C发送完成标志
  25. extern volatile bool I2C_receive_complete_flag;                 //I2C接收完成标志

  26. #ifdef HS300X_DEBUG
  27. uint8_t tmp01,tmp02,tmp03,tmp04;
  28. #endif


  29. /**********************************************************************************************************************
  30. 函数定义
  31. **********************************************************************************************************************/
  32. /******************************
  33. * @brief         测量函数
  34. * @param
  35. *         @arg         无
  36. * @retval 无
  37. ******************************/
  38. void Measurement(void)
  39. {
  40.         uint16_t timeout_ms = 100;                                     //等待超时时间(100毫秒)
  41.         //uint8_t Slaver_Addr = 0x88;                                    //采用大端格式,bit0:读写方向(0),bit1~bit7:从设备地址(0x44)
  42.         uint8_t p_dest[4] = {};                                                                 //接收从设备数据指针
  43.         bool MeasurementCompleted = false;    //测量完成标志位

  44.         //向从设备(hs3003)发送测量请求
  45.         R_SCI_I2C_Write (g_sci3_i2c.p_ctrl,NULL,0,false);
  46.         I2C_send_complete_flag = false;
  47.         //等待I2C发送完毕
  48.         while ((true != I2C_send_complete_flag) && timeout_ms)
  49.         {
  50.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  51.                 timeout_ms--;
  52.         }
  53.         timeout_ms = 100;
  54.         //向从设备(hs3003)获取数据,根据标志位状态,判断测量是否完成
  55.         while(true != MeasurementCompleted)
  56.         {
  57.                 R_SCI_I2C_Read (g_sci3_i2c.p_ctrl,&p_dest[0],4,false);
  58.                 I2C_receive_complete_flag = false;
  59.                 //等待I2C接收完毕
  60.                 while ((true != I2C_receive_complete_flag) && timeout_ms)
  61.                 {
  62.                         R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  63.                         timeout_ms--;
  64.                 }
  65.                 timeout_ms = 100;
  66.                 //判断测量标志位:00表示测量结果数据有效,01表示测量结构数据已过期
  67.                 if(0 == ((p_dest[0] & 0xC0) >> 6))
  68.                 {
  69.                         MeasurementCompleted = true;
  70.                 }
  71.         }
  72.         //计算测量结果
  73. #ifdef HS300X_DEBUG
  74.         tmp01 = p_dest[0];
  75.         tmp02 = p_dest[1];
  76.         tmp03 = p_dest[2];
  77.         tmp04 = p_dest[3];
  78. #endif
  79.         Humidity = (double)(((p_dest[0] & 0x3F) << 8) | p_dest[1]) / (double)(16383U) * 100.0 ;
  80.         Temperature = (((p_dest[2] << 8) | (p_dest[3] & 0xFC)) >>2 ) * 165.0 / (double)(16383U) - 40 ;
  81. }

  82. /******************************
  83. * @brief         HS3003工作模式切换(上电后10ms内执行)
  84. * @param
  85. *         @arg         tmp_mode:工作模式
  86. *                                                设置模式:hs3003_cmd_enter_programming_mode
  87. *                                                普通模式:hs3003_cmd_enter_normal_mode
  88. * @retval 无
  89. ******************************/
  90. void Mode_Set(hs3003_cmd_t tmp_mode)
  91. {
  92.         uint16_t timeout_ms = 100;                                     //等待超时时间(100毫秒)
  93.         uint8_t src[3] =        {(uint8_t)tmp_mode,0x00,0x00};                                //组装成完整指令
  94.         R_SCI_I2C_Write (g_sci3_i2c.p_ctrl,&src[0],3,false);                //发送指令
  95.         I2C_send_complete_flag = false;
  96.         //等待I2C发送完毕
  97.         while ((true != I2C_send_complete_flag) && timeout_ms)
  98.         {
  99.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  100.                 timeout_ms--;
  101.         }
  102. }

  103. /******************************
  104. * @brief         读取HS3003温湿度分辨率
  105. * @param
  106. *   @arg  tmp_type:温度/湿度选择
  107. *                                          湿度:0x01
  108. *                                                温度:0x02
  109. *        @retval        分辨率:
  110. *                                                8位精度  : resolution_8bit
  111. *                                                10位精度 : resolution_10bit
  112. *                                                12位精度 : resolution_12bit
  113. *                                                14位精度 : resolution_14bit
  114. ******************************/
  115. hs3003_resolution_t Resolution_Get(uint8_t tmp_type)
  116. {
  117.         uint8_t tmp_r[3];                                                                                        //保存HS3003中当前分辨率结果
  118.         uint16_t timeout_ms = 100;                                     //等待超时时间(100毫秒)
  119.         if(0x01 == tmp_type)
  120.         {
  121.                 Mode_Set(hs3003_cmd_Humidity_read_reg);                                                //发送读取湿度分辨率指令
  122.         }
  123.         else
  124.         {
  125.                 Mode_Set(hs3003_cmd_Temperature_read_reg);                                //发送读取温度分辨率指令(默认)
  126.         }
  127.         R_SCI_I2C_Read (g_sci3_i2c.p_ctrl,&tmp_r[0],3,false);                        //接收HS3003返回的分辨率读取结果
  128.         I2C_receive_complete_flag = false;
  129.         while ((true != I2C_receive_complete_flag) && timeout_ms)                //等待I2C接收完毕
  130.         {
  131.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  132.                 timeout_ms--;
  133.         }
  134.         if(0x81 == tmp_r[0])                                                        //判断返回结果状态(0x81表示获取成功)
  135.         {
  136.                 switch ((uint8_t)((tmp_r[1] & 0x0C) >> 2))
  137.                 {
  138.                         case 0x00:
  139.                         {
  140.                                 return hs3003_resolution_8bit;
  141.                                 break;
  142.                         }
  143.                         case 0x01:
  144.                         {
  145.                                 return hs3003_resolution_10bit;
  146.                                 break;
  147.                         }
  148.                         case 0x02:
  149.                         {
  150.                                 return hs3003_resolution_12bit;
  151.                                 break;
  152.                         }
  153.                         case 0x03:
  154.                         {
  155.                                 return hs3003_resolution_14bit;
  156.                                 break;
  157.                         }
  158.                 }                       
  159.         }
  160.         return hs3003_resolution_14bit;                                        //默认返回结果为14位精度
  161. }

  162. /******************************
  163. * @brief         设置HS3003温湿度分辨率
  164. * @param
  165. *   @arg  tmp_type:温度/湿度选择
  166. *                                          湿度:0x01
  167. *                                                温度:0x02
  168. *                @arg        tmp_res:分辨率
  169. *                                                8位精度  : resolution_8bit
  170. *                                                10位精度 : resolution_10bit
  171. *                                                12位精度 : resolution_12bit
  172. *                                                14位精度 : resolution_14bit
  173. * @retval 无
  174. ******************************/
  175. void Resolution_Set(uint8_t tmp_type,hs3003_resolution_t tmp_res)
  176. {
  177.         uint8_t tmp_r[3];                                                                                        //保存HS3003中当前分辨率结果
  178.         uint16_t timeout_ms = 100;                                     //等待超时时间(100毫秒)
  179.         if(0x01 == tmp_type)
  180.         {
  181.                 Mode_Set(hs3003_cmd_Humidity_read_reg);                                                //发送读取湿度分辨率指令
  182.         }
  183.         else
  184.         {
  185.                 Mode_Set(hs3003_cmd_Temperature_read_reg);                                //发送读取温度分辨率指令(默认)
  186.         }
  187.         R_SCI_I2C_Read (g_sci3_i2c.p_ctrl,&tmp_r[0],3,false);                        //接收HS3003返回的分辨率读取结果
  188.         I2C_receive_complete_flag = false;
  189.         while ((true != I2C_receive_complete_flag) && timeout_ms)                //等待I2C接收完毕
  190.         {
  191.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  192.                 timeout_ms--;
  193.         }
  194.         if(0x81 == tmp_r[0])                                                        //判断返回结果状态(0x81表示获取成功)
  195.         {
  196.                 if(0x01 == tmp_type)
  197.                 {
  198.                         tmp_r[0] = (uint8_t)hs3003_cmd_Humidity_write_reg;                                                //写入湿度分辨率指令
  199.                 }
  200.                 else
  201.                 {
  202.                         tmp_r[0] = (uint8_t)hs3003_cmd_Temperature_write_reg;                                        //写入温度分辨率指令
  203.                 }
  204.                 tmp_r[1] = (uint8_t)(tmp_res << 2);                                                                                                                                                //分辨率值
  205.                 timeout_ms = 100;                                                                                                                                                                             //设置等待超时时间(100毫秒)               
  206.                 R_SCI_I2C_Write (g_sci3_i2c.p_ctrl,&tmp_r[0],3,false);                                        //发送指令
  207.                 I2C_send_complete_flag = false;
  208.                 while ((true != I2C_send_complete_flag) && timeout_ms)                                        //等待I2C发送完毕
  209.                 {
  210.                         R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  211.                         timeout_ms--;
  212.                 }
  213.         }
  214. }

  215. /******************************
  216. * @brief         读取HS3003设备ID
  217. * @param
  218. *   @arg  无
  219. *        @retval        设备ID(32bit)
  220. ******************************/
  221. uint32_t ID_Get(void)
  222. {
  223.         uint32_t tmp_id;                                                                                                                                        //保存HS3003设备ID读取结果
  224.         uint8_t tmp_r[3] = {0x00,0x00,0x00};                                                        //保存I2C读取结果
  225.         uint16_t timeout_ms = 100;                                                                                     //等待超时时间(100毫秒)
  226.         Mode_Set(hs3003_cmd_Sensor_ID_UPPER_reg);                                        //发送读取设备ID高16位指令
  227.         R_SCI_I2C_Read (g_sci3_i2c.p_ctrl,&tmp_r[0],3,false);                                //接收I2C读取结果
  228.         I2C_receive_complete_flag = false;
  229.         while ((true != I2C_receive_complete_flag) && timeout_ms)                //等待I2C接收完毕
  230.         {
  231.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  232.                 timeout_ms--;
  233.         }
  234.         timeout_ms = 100;
  235.         if(0x81 == tmp_r[0])                                                                                                                                                                //判断返回结果状态(0x81表示获取成功)
  236.         {
  237.                 tmp_id = (uint32_t)((tmp_r[1] << 24) | (tmp_r[2] << 16));                //保存设备ID高16位
  238.         }
  239.         Mode_Set(hs3003_cmd_Sensor_ID_LOWER_reg);                                        //发送读取设备ID低16位指令
  240.         R_SCI_I2C_Read (g_sci3_i2c.p_ctrl,&tmp_r[0],3,false);                                //接收I2C读取结果
  241.         I2C_receive_complete_flag = false;
  242.         while ((true != I2C_receive_complete_flag) && timeout_ms)                //等待I2C接收完毕
  243.         {
  244.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  245.                 timeout_ms--;
  246.         }
  247.         if(0x81 == tmp_r[0])                                                                                                                                                                //判断返回结果状态(0x81表示获取成功)
  248.         {
  249.                 tmp_id = (uint32_t)((tmp_r[1] << 8) | (tmp_r[2]));                //保存设备ID低16位
  250.         }
  251.         return tmp_id;
  252. }

(2)OLED模块:

  1. /**********************************************************************************************************************
  2. 模块说明
  3. **********************************************************************************************************************/
  4. /*
  5. 描述:本模块为OLED屏幕显示驱动程序,该显示屏采用I2C接口通信;ISL29035硬件地址:0x78
  6. MCU接口描述:I2C接口选择:I2C3;I2C引脚:SDA:0409;SCL:0408
  7. 作者:yagi@2023-2-20
  8. 转载请注明出处,版权由@yagi所有
  9. */

  10. /**********************************************************************************************************************
  11. 文件引用
  12. **********************************************************************************************************************/
  13. #include "bsp_oled_i2c.h"
  14. #include "bsp_sci_i2c.h"
  15. #include "bsp_api.h"
  16. #include "common_data.h"
  17. #include "hal_data.h"
  18. #include "bsp_font.h"

  19. //#define OLED_DEBUG



  20. /**********************************************************************************************************************
  21. 全局变量定义
  22. **********************************************************************************************************************/
  23. extern volatile bool I2C_send_complete_flag;                                //I2C发送完成标志
  24. extern volatile bool I2C_receive_complete_flag;                 //I2C接收完成标志



  25. /**********************************************************************************************************************
  26. 函数定义
  27. **********************************************************************************************************************/
  28. /******************************
  29. * @brief         oled写命令
  30. * @param
  31. *         @arg         tmp_cmd:命令
  32. * @retval 无
  33. ******************************/
  34. void oled_write_cmd(uint8_t tmp_cmd)
  35. {
  36.         uint16_t timeout_ms = 100;                                                                                                                     //等待超时时间(100毫秒)
  37.         uint8_t p_dest[2] = {0x00,tmp_cmd};                                                                                                 //指令存放空间
  38.         R_SCI_I2C_Write (g_sci3_i2c.p_ctrl,&p_dest[0],2,false);                //发送指令
  39.         I2C_send_complete_flag = false;
  40.         //等待I2C发送完毕
  41.         while ((true != I2C_send_complete_flag) && timeout_ms)
  42.         {
  43.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  44.                 timeout_ms--;
  45.         }
  46. }

  47. /******************************
  48. * @brief         oled写数据
  49. * @param
  50. *         @arg         tmp_data:数据
  51. * @retval 无
  52. ******************************/
  53. void oled_write_data(uint8_t tmp_data)
  54. {
  55.         uint16_t timeout_ms = 100;                                                                                                                     //等待超时时间(100毫秒)
  56.         uint8_t p_dest[2] = {0x40,tmp_data};                                                                                                 //数据存放空间
  57.         R_SCI_I2C_Write (g_sci3_i2c.p_ctrl,&p_dest[0],2,false);                //发送数据
  58.         I2C_send_complete_flag = false;
  59.         //等待I2C发送完毕
  60.         while ((true != I2C_send_complete_flag) && timeout_ms)
  61.         {
  62.                 R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
  63.                 timeout_ms--;
  64.         }
  65. }

  66. /******************************
  67. * @brief         oled初始化
  68. * @param
  69. *         @arg         无
  70. * @retval 无
  71. ******************************/
  72. void oled_init(void)
  73. {
  74.         R_BSP_SoftwareDelay(200U, BSP_DELAY_UNITS_MILLISECONDS);                //延时200ms
  75.         oled_write_cmd(0xA8);                                                //设置分辨率
  76.         oled_write_cmd(0x3F);                                                //128*64
  77.         oled_write_cmd(0xDA);                                                //设置COM硬件引脚配置,适应分辨率       
  78.         oled_write_cmd(0x12);                                                //128*64
  79.         oled_write_cmd(0xD3);                                                //设置显示偏移
  80.         oled_write_cmd(0x00);                                                //0x00为没有偏移
  81.         oled_write_cmd(0x40);                                                //设置显示存储器开始行(40-7F,对应行0-63)
  82.         oled_write_cmd(0xA1);                                                //设置SEGMENT重映射
  83.         oled_write_cmd(0x81);                                                //设置对比度
  84.         oled_write_cmd(0xFF);                                                //00-FF,数值越大对比度越高
  85.         oled_write_cmd(0xA4);                                                //恢复RAM内容显示(RESET),0xA5:进入显示开启状态(不管RAM内容)
  86.         oled_write_cmd(0xA6);                                                //设置显示方式:正常显示,0xA7:反向显示
  87.         oled_write_cmd(0xD5);                                                //设置显示时钟分频([A0:A3])及振荡器频率([A7:A4])
  88.         oled_write_cmd(0xF0);                                                //(RESET:10000000)
  89.         oled_write_cmd(0x8D);                                                //充电泵设置(使能充电)
  90.         oled_write_cmd(0x14);                                                //0x14:允许在显示开启的时候使用  0x10:不允许在显示开启的时候使用
  91.         oled_write_cmd(0xAE);                                                //显示关
  92.         oled_write_cmd(0x20);                                                //设置内存地址模式
  93.         oled_write_cmd(0x02);                                                //0x00:水平模式;0x01:垂直模式;0x02:页地址模式(RESET)
  94.         oled_write_cmd(0xB0);                                                //设置GDDRAM页起始地址(页地址模式:B0-B7)
  95.         oled_write_cmd(0xC8);                                                //设置COM扫描方式(0xC0:上下反置左到右,0xC8:正常右到左)
  96.         oled_write_cmd(0x00);                                                //设置列的起始地址(页地址模式)
  97.         oled_write_cmd(0x10);                                                //设置列的最低有效位(LSB)地址(页地址模式)
  98.         oled_write_cmd(0x40);                                                //设置显示存储器开始行(40-7F,对应行0-63)
  99.         oled_write_cmd(0xD9);                                                //设置预充电时间
  100.         oled_write_cmd(0x22);                                                //预充电时间
  101.         oled_write_cmd(0xDB);                                                //设置取消选择级别
  102.         oled_write_cmd(0x20);                                                //0.65*VCC:0x00;0.77*VCC:0x20(RESET);0.83*VCC:0x30
  103.         oled_write_cmd(0xAF);                                                //显示开
  104.        
  105.         oled_clear();
  106.         oled_off();
  107. }

  108. /******************************
  109. * @brief         oled清屏
  110. * @param
  111. *         @arg         无
  112. * @retval 无
  113. ******************************/
  114. void oled_clear(void)
  115. {
  116.         for(uint8_t i = 0;i<8;i++)
  117.         {
  118.                 oled_write_cmd(0xB0 | i);                                //设置GDDRAM页起始地址(页地址模式)
  119.                 oled_write_cmd(0x00);                                                //设置低列的起始地址(页地址模式)
  120.                 oled_write_cmd(0x10);                                                //设置高列的起始地址(页地址模式)
  121.                 for(uint8_t j = 0;j<128;j++)
  122.                 {
  123.                         oled_write_data(0x00);
  124.                 }
  125.         }
  126. }

  127. /******************************
  128. * @brief         oled屏幕测试
  129. * @param
  130. *         @arg         无
  131. * @retval 无
  132. ******************************/
  133. void oled_test(void)
  134. {
  135.         for(uint8_t i = 0;i<8;i++)
  136.         {
  137.                 oled_write_cmd(0xB0 | i);                                //设置GDDRAM页起始地址(页地址模式)
  138.                 oled_write_cmd(0x00);                                                //设置低列的起始地址(页地址模式)
  139.                 oled_write_cmd(0x10);                                                //设置高列的起始地址(页地址模式)
  140.                 for(uint8_t j = 0;j<128;j++)
  141.                 {
  142.                         oled_write_data(0x01);
  143.                 }
  144.         }
  145. }

  146. /******************************
  147. * @brief         oled开启
  148. * @param
  149. *         @arg         无
  150. * @retval 无
  151. ******************************/
  152. void oled_on(void)
  153. {
  154.         oled_write_cmd(0x8D);                                                //充电泵设置(使能充电)
  155.         oled_write_cmd(0x24);                                                //0x14:允许在显示开启的时候使用  0x10:不允许在显示开启的时候使用
  156.         oled_write_cmd(0xAF);                                                //显示开
  157. }

  158. /******************************
  159. * @brief         oled关闭
  160. * @param
  161. *         @arg         无
  162. * @retval 无
  163. ******************************/
  164. void oled_off(void)
  165. {
  166.         oled_write_cmd(0x8D);                                                //充电泵设置(使能充电)
  167.         oled_write_cmd(0x24);                                                //0x14:允许在显示开启的时候使用  0x10:不允许在显示开启的时候使用
  168.         oled_write_cmd(0xAE);                                                //显示关
  169. }

  170. /******************************
  171. * @brief         oled显示
  172. * @param
  173. *         @arg         x:起始页编号
  174. *         @arg         y:起始列编号
  175. *         @arg         g:字符高度(页)
  176. *         @arg         k:字符宽度(位)
  177. *         @arg         *data:指向存放显示数据空间的指针
  178. * @retval 无
  179. ******************************/
  180. void oled_display(uint8_t x,uint8_t y,uint8_t g,uint8_t k,uint8_t * data)
  181. {
  182.         for(uint8_t i = 0;i<g;i++)
  183.         {
  184.                 oled_write_cmd(0xB0 | (i + x));
  185.                 oled_write_cmd(0x10 + (y >> 4 & 0x0F));
  186.                 oled_write_cmd(y & 0x0F);
  187.                 for(uint8_t j = 0;j<k;j++)
  188.                 {
  189.                         oled_write_data(*data++);
  190.                 }
  191.         }
  192. }

  193. /******************************
  194. * @brief         oled显示3位数字(16*8)
  195. * @param
  196. *         @arg         x:起始页编号
  197. *         @arg         y:起始列编号
  198. *         @arg         n:位数(取值范围:2-5)
  199. *         @arg         tmp_num:指向存放显示数据空间的指针
  200. * @retval 无
  201. ******************************/
  202. void oled_display_num(uint8_t x,uint8_t y,uint8_t n,uint8_t tmp_num)
  203. {
  204.         switch (n)
  205.         {       
  206.                 case 0x02:
  207.                 {
  208.                         oled_display(x,y,2,8,font_char[tmp_num/10]);
  209.                         oled_display(x,y+8,2,8,font_char[tmp_num%10]);
  210.                         break;
  211.                 }
  212.                 case 0x03:
  213.                 {
  214.                         oled_display(x,y,2,8,font_char[tmp_num/100]);
  215.                         oled_display(x,y+8,2,8,font_char[tmp_num%100/10]);
  216.                         oled_display(x,y+16,2,8,font_char[tmp_num%10]);
  217.                         break;
  218.                 }
  219.                 case 0x04:
  220.                 {
  221.                         oled_display(x,y,2,8,font_char[tmp_num/1000]);
  222.                         oled_display(x,y+8,2,8,font_char[tmp_num%1000/100]);
  223.                         oled_display(x,y+16,2,8,font_char[tmp_num%100/10]);
  224.                         oled_display(x,y+24,2,8,font_char[tmp_num%10]);
  225.                         break;
  226.                 }
  227.                 case 0x05:
  228.                 {
  229.                         oled_display(x,y,2,8,font_char[tmp_num/10000]);
  230.                         oled_display(x,y+8,2,8,font_char[tmp_num%10000/1000]);
  231.                         oled_display(x,y+16,2,8,font_char[tmp_num%1000/100]);
  232.                         oled_display(x,y+24,2,8,font_char[tmp_num%100/10]);
  233.                         oled_display(x,y+32,2,8,font_char[tmp_num%10]);
  234.                         break;
  235.                 }
  236.                 default:
  237.                         break;
  238.         }
  239. }

3、主要功能演示效果:

(暂略)


【设计心得】

通过本项目的设计制作,基本掌握了瑞萨RA系列产品的开发方式和代码框架体系。与之前使用的意法半导体、兆易创新、国民技术、武汉芯源等同类基于ARM Cortex-M系列MCU产品相比,作为基于ARM内核的MCU产品起步较晚的瑞萨,目前已具有非常完整产品线,包括基于ARM Cortex-M4、M23、M33、M85等内核MCU产品,每种内核又包括入门(E)、增强(M)、低功耗(L)、联网应用(W)、电机(T)等系列产品。与此同时,瑞萨官方提供的开发体系非常成熟,支持e2studio和RASC+等两种开发方式,后者支持主流嵌入式开发平台(包括KEIL及IAR等)。依托于完整的FSP(灵活配置软件包)代码框架,极大减少了用户开发所需时间和代码编写工作量,有效提升了项目开发效率。例如:本项目中使用到的各类板载外设,包括GPIO、UART、I2C、RCU、AGT等,只需引用HAL库相关文件,通过调用其中的设备CTRL、CFG、API等对象(这部分对象的声明和定义已通过RASC可视化配置后自动生成代码),仅需寥寥几行代码即可轻松实现相关功能,相较于其他厂商基于寄存器、库函数及HAL库等开发方式,效率之高不言而喻。此外,瑞萨RA系列MCU产品在低功耗、触摸应用、RTOS及安全协议等方面具有显著的技术优势。

在本项目的制作过程中,也发现了一些有待完善的问题。一是FSP代码体系较为庞杂,要发挥其强大的开发辅助作用,需要开发人员熟悉其代码框架。同时,官方提供的FSP说明文档中描述的文件体系结构,仅适用于采用e2studio系统进行开发的场景,而KEIL或IAR中的文件体系与说明文档存在较大差异,对于刚接触的新手并不是十分友好。为此,我在论坛里专门发表了一篇帖子(【RA4M2设计挑战赛】第一步:熟悉瑞萨的代码框架(非常重要) ),以帮助大家尽快熟悉FSP体系。二是板载的部分功能(例如:触摸按键)必需使用特定的编程器(JLINK V9以上),而这些设备的价格不菲,且本次活动中官方并未提供,在一定程度上影响和制约了学生等群体对这些功能的体验和学习,希望在未来的活动中能提供更多支持。


附件: 您需要登录才可以下载或查看附件。没有帐号?注册

更多回帖

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