目录
概述
1 软硬件
1.1 软硬件环境信息
1.2 开发板信息
1.3 调试器信息
2 硬件架构
2.1 硬件框架结构
2.2 测速功能原理介绍
2.2.1 理论描述
2.2.2 实现原理
2.2.3 系统硬件结构
3 软件实现
3.1 FSP配置项目
3.2 代码实现
3.2.1 初始化函数
3.2.2 功能函数
3.3 源代码
4 系统测试
4.1 编译代码
4.2 测试
【野火】第二期瑞萨RA MCU创意氛围赛:自适应蓝牙控制智能小车-01
【野火】第二期瑞萨RA MCU创意氛围赛:自适应蓝牙控制智能小车-02
【野火】第二期瑞萨RA MCU创意氛围赛:自适应蓝牙控制智能小车-03
源代码下载地址:
https://www.firebbs.cn/forum.php?mod=viewthread&tid=37943&extra=page%3D1
概述
本文主要介绍Renesas R7FA8D1BH (Cortex®-M85) 上光电编码器测速功能,笔者介绍了测速功能的实现原理,FSP配置MCU资源的方法,还编写系统的软件代码,实现测速的功能。
1 软硬件
1.1 软硬件环境信息
软硬件信息 | 版本信息 |
---|---|
Renesas MCU | R7FA8D1BH |
Keil | MDK ARM 5.38 |
FSP 版本 | 5.3.0 |
调试工具:N32G45XVL-STB | DAP-LINK |
1.2 开发板信息
笔者选择使用野火耀阳开发板_瑞萨RA8,该板块的主控MCU为R7FA8D1BHECBD,7FA8D1BHECBD的内核为ARM Contex-M85。
1.3 调试器信息
对于R7FA8D1BHECBD芯片,其使用的内核为Cortex®-M85 Core, ST-LINK-V2或者J-LINK-V9不支持下载和调试功能。笔者经过多次尝试,发现N32G45XVL-STB板卡上自带的DAP-LINK可以下载和调试R7FA8D1BHECBD。
下图为N32G45XVL-STB开发板实物图:
2 硬件架构
2.1 硬件框架结构
IO接口配置功能:
IRQ1和IRQ11配置为外部中断模式,用于接收两个光电编码器的输入信号
TIMER-7: 配置为10us响应间隔,计算1s时间内总共经过的脉冲个数
系统工作框架结构如下:
2.2 测速功能原理介绍
2.2.1 理论描述
M法又叫做频率测量法。这种方法是在一个固定的定时时间内(以秒为单位),统计这段时间的编码器脉冲数,计算速度值。设编码器单圈总脉冲数为 C,在时间 T0 内,统计到的编码器脉冲数为 M0,则转速 n 的计算公式为:
参数介绍:
M0 : T0时间内的编码器脉冲数
C: 编码器单圈总脉冲数
T0: 单位时间
n: 转速
公式中的编码器单圈总脉冲数 C 是常数,所以转速 n 跟 M0 成正比。这就使得在高速测量时 M0变大,可以获得较好的测量精度和平稳性,但是如果速度很低,低到每个 T0 内只有少数几个脉冲,此时算出的速度误差就会比较大,并且很不稳定。也有一些方法可以改善 M 法在低速测量的准确性,例如:增量式编码器倍频技术就是其中一种,比如原本捕获到的脉冲 M0 只有4 个,经过 4 倍频后,相同电机状态 M0 变成了 16 个,也就提升了低速下的测量精度。
2.2.2 实现原理
M0: 表示基准时钟周期,一般为1s
T0: 表示在一个M0时间内计数的秒冲总数
该码盘一周总共有20个孔,则其将一个圆分为20个等分,在测速的时候。只需记录其在M0(1 second)时间内走过孔的个数T0,然后通过轮胎的周长与孔等分的关系,就能计算出速度。
根据轮胎的直径,计算出周长
光电感应器用于实现脉冲计数功能
2.2.3 系统硬件结构
光电编码器接在后轮平行的两个电机上,,用于测试两组电机的转动速度:
左边编码器: 测试左边1组电机的转动速度
右边编码器: 测试右边1组电机的转动速度
3 软件实现
3.1 FSP配置项目
1)配置IO口外部中断
step -1: 配置P508接口
配置外部中断参数:
step-2: 配置P708接口
配置中断函数
step-3: 配置定时器函数
3.2 代码实现
3.2.1 初始化函数
在3.1节中完成参数配置后,就可以生成代码,实现定时器配置和外部中断配置的功能。接下来实现具体的测速功能。
函数:void gpt_counter_Init (void)的功能介绍
代码25行: 打开定时器
代码29行: 启动定时器
函数:void Motor_speed_Init( void )的功能介绍
代码36行:打开IRQ1外部中断
代码40行:使能IRQ1的外部中断功能
代码44行:打开IRQ1外部中断
代码48行:使能IRQ1的外部中断功能
代码53行:使能外部中断
3.2.2 功能函数
1)定时器回调函数,其主要实现计算速度的功能
代码62行:计数器的值加1
代码63行:实现1s的计数功能
代码65、66行:计算速度
2)计算速度和外部中断响应函数
函数: static float calculate_speeds( uint32_t cnt )
功能: 计算当前的转动速度
函数:void g_external_irq1_Callback (external_irq_callback_args_t * p_args)
功能:外部中断IRQ1的中断回调函数
函数:void g_external_irq11_Callback (external_irq_callback_args_t * p_args)
功能:外部中断IRQ11的中断回调函数
3.3 源代码
/*FILE NAME : motor_speed.cDescription: calculate the motor running speedAuthor : tangmingfei2013@126.comDate : 2024/09/28*/
#include "motor_speed.h"
#include "bsp_led.h"#define PI 3.14159
#define R 6.8 // unit: cm
#define DIV_CNT 20Stru_MotorSpeed stru_MotorSpeed;
static uint32_t trig_LeftCnt = 0,trig_RightCnt=0;
static uint32_t count;static float calculate_speeds( uint32_t cnt );void gpt_counter_Init (void)
{fsp_err_t err = FSP_SUCCESS;/* Initializes the module. */err = R_GPT_Open(&g_timer7_ctrl, &g_timer7_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Start the timer. */(void) R_GPT_Start(&g_timer7_ctrl);
}void Motor_speed_Init( void )
{/* Configure the external interrupt. */fsp_err_t err = R_ICU_ExternalIrqOpen(&g_external_irq1_ctrl, &g_external_irq1_cfg);assert(FSP_SUCCESS == err);/* Enable the external interrupt. *//* Enable not required when used with ELC or DMAC. */err = R_ICU_ExternalIrqEnable(&g_external_irq1_ctrl);assert(FSP_SUCCESS == err);/* Configure the external interrupt. */err = R_ICU_ExternalIrqOpen(&g_external_irq11_ctrl, &g_external_irq11_cfg);assert(FSP_SUCCESS == err);/* Enable the external interrupt. *//* Enable not required when used with ELC or DMAC. */err = R_ICU_ExternalIrqEnable(&g_external_irq11_ctrl);assert(FSP_SUCCESS == err);// init timer as 1ms gpt_counter_Init();
}void g_timer7_CallBack (timer_callback_args_t * p_args)
{if (TIMER_EVENT_CYCLE_END == p_args->event){/* Add application code to be called periodically here. */MONTIOR_TOGGLE;count++;if((count%1000) == 0){stru_MotorSpeed.leftSpeed = calculate_speeds(trig_LeftCnt);stru_MotorSpeed.rightSpeed = calculate_speeds(trig_RightCnt);trig_RightCnt = 0;trig_LeftCnt = 0;}}
}static float calculate_speeds( uint32_t cnt )
{float speeds;speeds = (float)(((PI*R)/20) * cnt);return speeds;
}/* Called from icu_irq_isr */
void g_external_irq1_Callback (external_irq_callback_args_t * p_args)
{(void) p_args;trig_RightCnt++;
}/* Called from icu_irq_isr */
void g_external_irq11_Callback (external_irq_callback_args_t * p_args)
{(void) p_args;trig_LeftCnt++;
}/* End of this file */
4 系统测试
4.1 编译代码
编译代码下载到板卡中运行代码,系统通过OLED显示速度的值
4.2 测试
1)电机停止状态下的速度
2)电机转动之后的速度值