野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 287|回复: 0

【野火】第二期瑞萨RAMCU创意氛围赛+压力、位移采集项目

[复制链接]

发表于 2024-11-14 20:25:27 | 显示全部楼层 |阅读模式
  自己有幸参加野火举办的第二期RAMCU创意氛围赛,下面简单介绍自己自己在这次项目中的学习经验和DIY的一个小项目。
 硬件资源:主板:野火RA6T2开发板、
      串口工业屏(湖南迪文科技)、50KG 压力传感器、50mm位移传感器、编码器、光电开关
 软件编译工具:MDK 5.38a 版本
 调试器:野火脱机烧写器、DAP调试器二合一版本

一:项目介绍:
 我参加本次活动所选择的开发板是RA6T2,当时选择这款开发板主要是考虑到该块开发板的优越性,提供的外设接口:比如IIC通讯的 eeprom、SPI的W25Q32、RS485接口、CAN通讯、TTL通讯的工业屏、ADC、DAC接口、隔离输入输出接口,步进电机、直流有刷电机/无刷电机等等,可谓是资源丰富,一块小小的板子我们既可以了解、学习到目前常用的几种通讯方式,也可以学到几种不同的电机控制方式。

 开发板图片如下:
野火论坛202411142053581902..png

二、整体硬件框架图
野火论坛202411182006571465..png

如上图所示:主控采用野火RA6T2开发板,外部采集压力传感器信号,由于输出信号在0-10MV,输出信号较小,无法通过单片机的内部ADC0/ADC1进行采集,所以这里我是用是AD620进行放大,将信号放大至3.3V,可以将压力传感器信号成功采集;
位移传感器采集电路:我这里使用的是电阻式的位移传感器,传感器内部是一个滑动电阻器,输出为电压信号,这里我直接使用的是板载3.3V对其进行供电,推动位移传感器,可以直接输出0-3.3V信号,这里可以直接使用单片机内部的ADC采集。
电机控制:使用的是步进电机,使用脉冲+方向控制方式,使用板载的定时8的PWM输出功能,使用的板载接口为J21,板载使用的隔离输出,可以直接驱动步进电机驱动器,不过使用的时候需要注意下:参考原理图,需要将板载的J16和J19的跳线冒进行短接,要不然输出PWM功能会异常的。
显示电路:采用串口工业屏进行,显示压力、位移、温湿度、编码器圈数等等信息。
温湿度采集:采用RS485电路接口,对温湿度变送器的数据进行采集,使用CRC16校验的方式,对数据的准确性进行判断。
编码器电路:采用板载的编码器接口对编码器的转动转动情况进行读取,软件采用的就是定时器的编码器正交模式。
三:软件框架(外设的分配)

野火论坛202411182051052159..png

如上图所示,该项目中所使用的外设及其负载的控制部分,部分电路直接使用板载的外设接口,由于自己在调试板载RS485电路出现了问题,这里使用的外扩一个485模块进行控制。
四:各个外设的配置过程及开发过程
4.1 硬件设计部分
4.1.1 电源板设计:
野火论坛202411211814558635..png


如框图所示:电源电路使用DC12对系统进行供电,使用XL4005芯片对供电电压进行降压至DC5V,分别为ATMS1117-3V3供电及其串口工业屏供电,以保证系统的显示稳定工作。
这里使用供电为DC12V(最高可以到36V)输出电流可以到3A,其中XL4005经过降压后,降至DC5V,为数字电路提供稳定的5V电压,可以为工业串口屏幕供电,DC5V降至3.3V,可以为单片机或者外设芯片供电使用。
模拟部分使用78M05降至AVDD,可以为模拟部分提供稳定的5V电源,为模拟芯片提供稳定的5V输出,使用LM317降至DC9V,为了使某些轨到轨的芯片可以稳定工作,这里使用的电荷泵芯片,为某些运算放大器提供稳定的电压。
4.1.2 压力采集电路设计
在工业控制中,经常会使用到数字信号或者模拟信号,比如0-5V,0-10mv,或者是4-20ma等等,而主控cpu,在采集这些信号的时候,需要使用单片机内的ADC功能,或者是外扩AD芯片,对外部的信号进行采样、分析,今天就和大家分享一个采集电压信号的方式方法
野火论坛202411211819022065..png
AD620:高精低失调电压和低失调漂移、低噪声、低功耗、易于设置增益、宽电源电压范围、低输入偏置电流的特点,该芯片是一款低成本、高精度仪表放大器,其特性和应用广泛。
TLE2072:双路运放:内部包含两个独立的运算放大器,可用于多种电路配置。
4.2 软件设计部分(所使用到的外设进行介绍)
如下所所示,为该项目中使用到的外设框图如下所示:
野火论坛202411211829466005..png
<1> SCI9接口,使用板载的CH340芯片,串口9的发送功能,将设备当前的状态信息回传到PC断,后续计划修改为使用亿佰特的无线串口模块,远程监测状态信息;
<2>SCI0接口, 这里使用的串口0的,外扩485电路,读取温湿度的模块的数据,(这里原本打算使用板载的RS485接口电路但是在调试的过程中,遇到些问题,目前还没有解决,后续解决了,在更新一版)
<3>SCI3接口,  这里使用的时串口3,使用的板载的串口屏接口,使用一款湖南迪文科技的串口工业屏,显示设备的状态信息,目前已经实现屏幕与MCU的交互功能。
<4> TIMER0:   在该项目中使用定时器0作为系统时钟,主要完成系统基本的时钟,主要完成系统运行的基本时基。
<5> TIMER8:  在该项目中使用定时器8用作PWM的输出功能,使用板载的J21,步进电机驱动接口3,外接一个两相步进电机驱动器,通过控制PE14引脚输出PWM的频率改变电机的运行速度。
<6> TIMER3: 在该项目中使用定时器3的输入捕获功能,使用板载的J25,编码器的接口,捕捉旋转编码器的脉冲个数,从而控制电机的运行(将在视频中进行演示)
<7> ADC0:    在该项目中使用ADC0的通道0、通道1分别采集压力、位移的数据,分别为0-2.5V和0-3.3V的电平变化
<8>外部中断:使用外部中断4 和外部中断13,为板载的按键监测,可以控制板载LED灯的工作状态,可以根据实际的项目需求设计为具体的功能。只需要回调函数中添加就可以了。
上述使用的模块外设,底层驱动均使用FSP库自动生成,只是在配置过程中遇到的问题,可参考野火官方提供的视频资料和FSP的开发指南进行配置,基本上配置起来很方便,只需要配置好回调函数即可,这里我和大家分享一下外设的配置过程。

4.2.1 系统时钟的配置选择
野火论坛202411211857467728..png
这里是系统时钟的配置,由于在该项目中对系统的基本时基要求不高,这里我配置的是100ms中断一次,
回调函数中代码如下:
  1. /* 定时器溢出 中断回调函数  运行时间100MS   */
  2. void agt0_timing_callback(timer_callback_args_t * p_args)
  3. {
  4.     if (TIMER_EVENT_CYCLE_END == p_args->event)
  5.     {
  6.         /* 翻转 LED1 */
  7.                                 LED1_TOGGLE;    //每100毫秒翻转一次
  8.                                 iTimeSampleCount++;
  9.                                 MotorSoftControl();
  10. /*每500ms,,,界面刷新函数*/
  11.                                 if( iTimeSampleCount%5 == 0 )
  12.                                                 {
  13.                                                         GuiDisplay();
  14.                                                 }
  15.                                 if(iTimeSampleCount >=10)   
  16.                                 {
  17.                                         iTimeSampleCount = 0 ;
  18.                                         ReadTemperData(0xFF);
  19.                                         OutputCounts ++ ;
  20.                                         if(OutputCounts >5)
  21.                                         OutputCounts = 0 ;
  22.                                         OutputInformation(OutputCounts);
  23.                                 }
  24.     }
  25. }
复制代码
4.2.2 串口3的配置过程
野火论坛202411211902444217..png
这里我配置使用的是串口3,然后连接串口工业屏,已实现屏幕的交互功能(这里感谢一下野火的客服,一位技术支持,当初我调试好久,发现使用keil进行编程的时候,串口发送数据不正常,在配置好串口参数后,单片机发送异常),下面我分享一下串口部分的驱动代码
  1. void Dwin_Send_Example(uint8_t ch)
  2. {
  3.   /* 把串口接收到的数据发送回去 */
  4.   R_SCI_B_UART_Write(&g_uart3_ctrl, (uint8_t *)&ch, 1);
  5. }
  6. /***********************************************************************************************
  7.   * @brief   void SendTestData(char ID)
  8.   * @param   切换界面显示功能
  9.   * @retval  无
  10.   * @author  聪聪哥哥
  11.   * @version V1.1.0
  12.   * @date    1-8-2024
  13. *************************************************************************************************/
  14. void SendTestData(char ID)
  15. {
  16.          static uint8_t DWIN_Buffer[64];
  17.          volatile int i = 0 ;
  18.          ucDispMode = ID ;
  19.          DWIN_Buffer[0] = 0x5A ;
  20.          DWIN_Buffer[1] = 0xA5 ;        
  21.          DWIN_Buffer[2] = 0x07 ;
  22.          DWIN_Buffer[3] = 0x82 ;        
  23.          DWIN_Buffer[4] = 0x00 ;
  24.          DWIN_Buffer[5] = 0x84 ;        
  25.          DWIN_Buffer[6] = 0x5A ;
  26.          DWIN_Buffer[7] = 0x01 ;        
  27.          DWIN_Buffer[8] = 0x00 ;
  28.          DWIN_Buffer[9] = ID ;               
  29.         for(i= 0 ;i < 10 ; i++)
  30.         {
  31.                 Dwin_Send_Example(DWIN_Buffer[i]);
  32.                 uart_send3_complete_flag = false;
  33.         }
  34. }
复制代码
如上述代码所示,在发送一组数据时候,完成完成每个字节之后,需要添加 串口3的发送的状态位,否则引脚串口在发送完成之后,不停的发送0xFF的情况,
下面和大家分享一下串口3的串口接收部分代码
  1. void UART3_CALLBACK(uart_callback_args_t * p_args)
  2. {
  3.     switch (p_args->event)
  4.     {
  5.         case UART_EVENT_RX_CHAR:
  6.         {
  7.                                                         temp = (unsigned char )p_args->data ;
  8.                                                         switch(BackState3)
  9.                                                         {
  10.                                                                 case 0:        if(temp == 0x5A)        BackState3 = 1;
  11.                                                                                 else        {BackState3 = 0;}
  12.                                                                 case 1:        if(temp == 0xA5)        BackState3 = 2;
  13.                                                                                 else        {BackState3 = 0;}        
  14.                                                                         break;
  15.                                                                 case 2:        ReceiveLength = temp;
  16.                                                                                 if(ReceiveLength>32)        BackState3 = 0;
  17.                                                                                 else
  18.                                                                                 {
  19.                                                                                         ReceiveLength = ReceiveLength - 1;
  20.                                                                                         BackState3 = 3;
  21.                                                                                 }
  22.                                                                         break;
  23.                                                         case 3:        ReceiveBuffer3[ReceivePoint3] = temp;
  24.                                                                         ReceivePoint3++;
  25.                                                                         if(ReceivePoint3 > ReceiveLength)
  26.                                                                         {
  27.                                                                                 back3Flag = 1;
  28.                                                                                 BackState3 = 0;
  29.                                                                         }
  30.                                                                         else
  31.                                                                         {
  32.                                                                                 BackState3 = 3;        
  33.                                                                         }        
  34.                                                                 break;
  35.                                                         default:
  36.                                                                 break;
  37.                                                         }
  38.             break;
  39.         }
  40.         case UART_EVENT_TX_COMPLETE:
  41.         {
  42.             uart_send3_complete_flag = true;
  43.             break;
  44.         }
  45.         default:
  46.             break;
  47.     }
  48. }
复制代码
在串口3的回调函数中,将接收到的字节放到接收数组内,这里需要根据基本的屏幕指令进行调试了,这里就不做过多的介绍,不过主要注意的是,配置引脚,串口的优先级的问题,错误的配置参数可能回导致工业串口屏在交互的时候出现丢失数据情况出现。
4.2.3 定时8的配置过程(PWM输出功能)
野火论坛202411211915077589..png
脉宽调试技术在工业控制中有着举足轻重的角色,这里我再配置的时候参考野火的视频,进行配置,这里我设计最大为5Khz的脉冲频率,在整个项目中,实现脉宽的调节和电机的软启动功能,代码如下:
  1. /*设置电机速度函数*/
  2. void  SetMotorSpeed(uint32_t value)
  3. {
  4.     timer_info_t info;
  5.     /* 获得GPT的信息 */
  6.     R_GPT_InfoGet(&g_timer8_PWM_ctrl, &info);
  7.      R_GPT_PeriodSet(&g_timer8_PWM_ctrl,value);   
  8.     /* 获得计时器一个周期需要的计数次数 */
  9.     /* 最后调用FSP库函数设置占空比 */
  10.     R_GPT_DutyCycleSet(&g_timer8_PWM_ctrl, value/2, GPT_IO_PIN_GTIOCB);
  11.     /* 初始化 GPT 模块 */
  12. //    R_GPT_Open(&g_timer8_PWM_ctrl, &g_timer8_PWM_cfg);   
  13.     /* 启动 GPT 定时器 */
  14.     R_GPT_Start(&g_timer8_PWM_ctrl);
  15. }
复制代码
主要是使用 R_GPT_PeriodSet(&g_timer8_PWM_ctrl,value); 函数调节PWM的输出周期,这里不过需要注意下需要同步更新占空比,调用函数如下:    R_GPT_DutyCycleSet(&g_timer8_PWM_ctrl, value/2, GPT_IO_PIN_GTIOCB); 否则会导致PWM的输出不正常。
4.2.4编码器的检测
野火论坛202411211920337502..png
主要是使用定时器的输入捕获功能,完成对编码器的计数,代码如下:
  1. /* 定时器1中断回调函数 */
  2. void encoder_callback(timer_callback_args_t * p_args)
  3. {
  4.     switch(p_args->event)
  5.     {
  6.         /* 捕获事件 -- A沿触发 (A') 上升沿 */
  7.         case TIMER_EVENT_CAPTURE_A:
  8.         uiEncoderData ++;
  9.             break;
  10.         /* 捕获事件 -- B沿触发 */
  11.         case TIMER_EVENT_CAPTURE_B:
  12.         uiEncoderData --;
  13.            // 进行相关处理
  14.             break;
  15.         /* 定时周期结束事件 */
  16.         case TIMER_EVENT_CYCLE_END:
  17.             break;
  18.         default:
  19.             break;
  20.     }
  21. }
复制代码
如上图代码所示:只需要配置号定时器底层输入捕获功能,就可以完成对编码器A相、B相的检测功能,可以说很简单,方便。大家在测试和也可以使用PWM输出固定脉冲个数的,来测试定时器的捕获功能是否正常,这里。
4.2.5 ADC的检测功能
野火论坛202411211931143129..png
代码如下:这里参考官方的例程电位器采集代码即可。
  1. /*读取压力通道的ADC数据*/
  2. double Read_Press_Voltage_Value(void)
  3. {
  4. //    uint16_t adc_data0;
  5.     double a0;
  6.          R_ADC_B_ScanGroupStart(&g_adc0_ctrl, ADC_GROUP_MASK_0);
  7.          scan_complete_flag0 = false;
  8.          while (!scan_complete_flag0)                  //等待扫描完成
  9.          {
  10.                         ;
  11.          }
  12.          R_ADC_B_Read(&g_adc0_ctrl,ADC_CHANNEL_0, &uiAdcSample1);
  13.          a0 = (double)(1.0*uiAdcSample1/4095)*3.3;
  14.          return a0;
  15. }
复制代码
5.屏幕工程
这里我所使用迪文的一款工业串口屏
该项目中,主工作界面如下:
显示一些设备状态信息(通过指令将数据从MCU中显示到工业屏中)、按键操作。可以控制电机的启动。

野火论坛202411211941456081..png
  1. /*工作界面下 数据显示部分 */
  2. void  WorkPage(void)
  3. {
  4. /*温度 显示函数*/
  5.                 Add_Write_Data(0x0000 ,iTemperture);
  6. /*湿度 显示函数*/
  7.                 Add_Write_Data(0x0002 ,ihunidata);
  8. /*编码器    显示函数*/
  9.                 Add_Write_Data(0x0004 ,uiEncoderData);
  10. /*压力  1 显示函数*/
  11.                 Add_Write_Data(0x0006 ,uiPressData);
  12. /*位移  1 显示函数*/
  13.                 Add_Write_Data(0x0008 ,uiLengtData);
  14. /*湿度  1 显示函数*/
  15.                 Add_Write_Data(0x000A ,uiAdcSample1);        
  16. }
复制代码
参数的设置界面:
野火论坛202411211943456642..png
当检测到的温湿度、压力位移数据与实际值出现偏差时,我们可以通过屏幕上面的按键对其进行校准,减小设备采集的误差。
  1. /*温度修正 显示函数*/
  2.                 Add_Write_Data(0x0010 ,iCorrectTemperture);
  3. /*湿度修正 显示函数*/
  4.                 Add_Write_Data(0x0012 ,iCorrecthunidata);
  5. /*压力修正    显示函数*/
  6.                 Add_Write_Data(0x0014 ,iCorrectPressData);
  7. /*位移修正  1 显示函数*/
  8.                 Add_Write_Data(0x0016 ,iCorrectLengthData);
  9. /*电机速度 1 显示函数*/
  10.                 Add_Write_Data(0x0018 ,iRunSpeed);
  11. /*编码器修正  1 显示函数*/
  12.                 Add_Write_Data(0x001A ,iCorrectLengthData);
复制代码
实物图片如下:
野火论坛202411241640134682..png
6.活动感想
项目的优化空间:可以增加一个无线串口模块,可以远程去监测环境的温湿度、控制电机的启动等等功能。板载接口引出的很多,可以设计将野火小智的模块功能,增加至该项目中,实现一个多功能的模块。
记得是半年前,自己在关注野火的推出的这款开发板时,由于自己平时工作的原因,对单片机的控制比较感兴趣,恰好自己空闲时间比较多,就报名了野火举办第二期瑞萨创意氛围赛,自己呢也是有幸获得了参赛资格。由于自己对瑞萨的知识了解比较少,而且对e2 studio了解的比较少,所以就是用keil5的编程工具,对其开发。还好keil5也可以配合FSP库的开发,这里自己配置的时候也是按照野火的视频一步步的进行配置,可以说视频讲解的很详细,通俗易懂。从开始的板载的LED灯控制,再到定时器、PWM、定时器的输入捕获、串口的调试、中断、ADC的学习,在自己遇到困难时,去看野火的视频、资料、到论坛上去查看大佬们有没有解决的办法、有时候也会向野火的淘宝店铺的客服寻求帮助,这里也感谢一下野火淘宝的技术支持 客服2,我在本次活动的最后的时间内,该客服提供了很大的帮助,服务也很多,对我实现项目的功能,提供了解决的办法。在软件调试的时,使用FSP软件配置底层驱动代码真的时很方便,可以说相对于其他的mcu芯片,瑞萨有着很多的优势,通过野火举办的创意赛,在一定的成都上,提高的自己的动手能力,也学到了瑞萨的许多的珍贵实践、开发的经验。
活动快结束,但是学习瑞萨的道路刚刚开始踏上征程,后期打算使用e2studio对瑞萨进行开发,希望有共同爱好的DIY者共同学习。
最后的最后,感谢瑞萨举办的创意赛的活动,为自己提供一个学习瑞萨的机会和平台。
B站视频链接如下:
https://www.bilibili.com/video/BV14yBxYHEJt/?vd_source=fb5a6d1a3332aab1989e0f3e24f2afc1

软件代码分享:
work_ra6t2.zip (1.63 MB, 下载次数: 1)
屏幕工程分享:
迪文工程.zip (2.6 MB, 下载次数: 1)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-12-27 04:59 , Processed in 0.161161 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表