【瑞萨RA4系列开发板体验】基于PWM控制的无极调速电机控制
作者:HonestQiao
在RA系列板子上,GPT更重要的作用之一,是进行PWM输出,不然对不起他的全名:General PWM Timer。 要使用PWM输出功能,借助FSP工具,可以很方便的进行配置,然后在代码中进行对应的调用处理。 正好,我手头有一个MX1508的直流电机控制模块,以及一个带风扇的小直流电机,刚好可以用上。 MX1508一般是这样的: 可以同时控制两路直流电机,例如在小车上使用。
通常按照如下方式使用: 不过,我手头的这个,只能控制一个电机: 通过MX1508控制电机,需要两个信号接口,一个是PWM控制转速,一个是DIR控制方向。 通过查看RA4M2的硬件手册和原理图,最终进行如下的设计: - PWM控制使用GPT1,因为其两个PWM输出IO口,分别为P405、P406,而P405刚好接到了板子上的LED3,可以用其亮度,表示当前PWM的占空比情况,而P406则输出控制电机
- 使用LED2来表示电机运转的方向,其对应的控制引脚为P404,同时用于控制电机运转的方向
- 使用板载SW1按键,其对应的因较为P005,用来控制是否保持电机当前的转速;同时,使用LED1的亮灭表示是否保持。
对应的手册信息如下: 做好了设计规划,就先用FSP进行设置。
首先,P405默认设置为普通IO控制LED3,如果要使用PWM进行控制,则需要取消原有的设置,也就是禁用P405默认的配置: 然后,配置GPT1: 当选择GPIOCA and GPIOCB的时候,会自动设置GPIOC1A、GPIOC1B为P405、P406。如果用GPIOCA or GPIOCB,则只能二选一启用一个。 其次,进行gpt1 stack的设置:
先添加一个gpt: 在设置对应的配置,按照如下步骤设置或者检查对应的值是否正确: 各个部分的说明如下: - Common:主要是启用输出功能
- General:主要是设置变量名、通道、模式、周期、周期单位,这些会生成到代码文件中,作为配置调用
- Output:设置启用两个输出IO端口
- Pins:检查是否为对应的引脚设置即可
做好了设置,生成代码,就可以在进行实际的代码编写了。
其他部分的代码FSP都生成好了,我们只需要编写关键调用即可: - void hal_entry(void)
- {
- /* TODO: add your own code here */
- int32_t pwm_counter = 0; // PWM次数计数
- uint32_t key_counter = 0; // 按键次数计数
- bool status = false; // 按键状态
- bool direction = true; // 运转方向
- bsp_io_level_t Pin_P005; // 定义按键1
- fsp_err_t err = FSP_SUCCESS;// 定义调用返回结果
- err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg); // 初始化引脚
- assert(FSP_SUCCESS == err); // 判断是否初始化成功
- err = R_GPT_Open(&g_timer_gpt1_ctrl, &g_timer_gpt1_cfg); // 初始化GPT1
- assert(FSP_SUCCESS == err); // 判断是否初始化成功
- (void) R_GPT_Start(&g_timer_gpt1_ctrl); // 启用GPT1
- err = R_GPT_PeriodSet(&g_timer_gpt1_ctrl, 10000); // 设置运行频率为10KHz
- assert(FSP_SUCCESS == err);
- while (1)
- {
- R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &Pin_P005); // 读取按键1的结果
- if (Pin_P005 == BSP_IO_LEVEL_LOW && !status)
- { // 判断按键有没有按下
- status = true; // 设置按下状态
- key_counter++; // 按键次数+1
- }
- else if (Pin_P005 == BSP_IO_LEVEL_HIGH && status)
- { // 判断按键有没有松开
- status = false; // 设置松开状态
- }
- if(key_counter%2==0) {
- // 偶数次按下,则保持运转状态
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH); // 点亮LED
- // 设置占空比
- err = R_GPT_DutyCycleSet(&g_timer_gpt1_ctrl, pwm_counter, GPT_IO_PIN_GTIOCA_AND_GTIOCB);
- assert(FSP_SUCCESS == err);
- // 延时
- R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
- } else {
- // 奇数次按下,则正常运转
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW); // 关闭LED
- // 根据运转方向,设置是加速还是减速,实际运转,将类似呼吸灯,逐渐加速直到最大值,再逐渐减速直到最小值,如此反复
- if(direction) {
- pwm_counter += 100;
- } else {
- pwm_counter -= 100;
- }
- if (pwm_counter > 10000) {
- // 超过最大值,则保持最大值,但方向转向
- pwm_counter = 10000;
- direction = !direction;
- // 设置占空比
- err = R_GPT_DutyCycleSet(&g_timer_gpt1_ctrl, 0, GPT_IO_PIN_GTIOCA_AND_GTIOCB);
- assert(FSP_SUCCESS == err);
- }
- else if (pwm_counter < 0) {
- // 达到最小值,则保持最小值,但方向转向
- pwm_counter = 0;
- direction = !direction;
- // 设置占空比
- err = R_GPT_DutyCycleSet(&g_timer_gpt1_ctrl, 0, GPT_IO_PIN_GTIOCA_AND_GTIOCB);
- assert(FSP_SUCCESS == err);
- }
- else {
- // 设置占空比
- err = R_GPT_DutyCycleSet(&g_timer_gpt1_ctrl, pwm_counter, GPT_IO_PIN_GTIOCA_AND_GTIOCB);
- assert(FSP_SUCCESS == err);
- }
- // 设置运转方向及指示灯
- if(direction) {
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);
- } else {
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
- }
- // 延时
- R_BSP_SoftwareDelay (100, BSP_DELAY_UNITS_MILLISECONDS);
- }
- }
- #if BSP_TZ_SECURE_BUILD
- /* Enter non-secure code */
- R_BSP_NonSecureEnter();
- #endif
- }
复制代码上述代码的逻辑非常清晰,注解也很详细,就不一一说明了,几个重点说一下: - 按键采用了根据按下计数次数,来进行是否保持的设定;如果按下偶数次,则保持;如果按下奇数次,则不保持。这样做的目的,是为了防止按下的时候,如果一直检测到按下,则会不断地触发。也可以用按下来进行保持,松开则不包吃,但是这样并不方便。
- 占空比根据direction,来自动进行增加或者减小,在0~10000之间往复
- 实际运转的时候,如果处于非保持状态,则自动加速到最大速度,然后反向运转,自动减速到最小速度,如此往复;在次之间任意时刻按下按键,则会保持当前的转速运转;再按一次,则恢复往复运转状态。
在编译烧录上诉代码之前,把MX1508和电机节后,然后接到开发板上。
通过开发板的手册,可以得知,开发板上有两个PMOD接口,P406在PMOD1上,可以用该PMOD接口,直接驱动DC电机,非常方便: 具体的接线如下: 为了方便检查,点击电机按照预期的方向运转,我在点击前面挂了一张纸巾,这样就可以根据纸巾飘动方向,来判断运转是否正常了。 实际运转的效果如下: 具体控制效果,可以查看文章后面的视频。 通过视频可以看到,使用按键1,可以很方便的进行速度的保持,不管是在高速状态,还是在低速状态。
而在非保持状态下,电机按照预期的,先加速,再转向减速,纸巾的飘动方向和幅度也随之变化。
另外,当占空比过低的时候,电机会不启动。
|