eefocus_4062187 发表于 2026-5-31 20:40:12

【EK-RA4C1开发套件】步进电机串口控制与Web上位机设计

# 【EK-RA4C1开发套件】步进电机串口控制与Web上位机设计

本文介绍了 EK-RA4C1 开发套件结合 TMC2209 模块和 LCD 显示屏,实现串口控制,进一步设计Web网页上位机实现步进电机的可视化UI界面控制的项目设计,包括硬件连接、串口指令控制、网页上位机设计等。

## 项目介绍

- 准备工作:步进电机参数、环境搭建、硬件连接等;
- 工程测试:工程配置、流程图、关键代码,串口 JSON 指令控制步进电机旋转方向、角度和速度;
- 网页设计:Web 界面及功能模块设计,连接串口并发送 JSON 消息,实现步进电机的转速和角度控制。

## 硬件连接

- 使用 Type-C 数据线连接开发板和电脑;
- TMC 2209 驱动板、EK-RA4C1 开发板的接线方式如下

| RA4C1 | TMC2209 | Note            |
| :---- | :------ | :---------------- |
| P510| Dir   | Direction         |
| P509| STEP    | Steps             |
| P511| EN      | Enable            |
| 5V    | VM      | Power for stepper |
| 3.3V| VCC   | Power for MCU   |
| GND   | GND   | Ground            |

> 注意,若步进电机额定电压较高或带负载运行,需使用外部电源连接 TMC2209 驱动板 VM 引脚供电。

由原理图可知, P509、P510、P511 分别对应 Arduino UNO 接口的 D10、D7、D8 引脚。

- TMC2209 与 42 步进电机的接线方式如下

| 42步进电机 | TMC2209 | Note    |
| ---------- | ------- | ------- |
| A+         | 1A      | A phase |
| A-         | 1B      | A phase |
| B+         | 2A      | B phase |
| B-         | 2B      | B phase |

### 实物图

!(//m.qjumbo.com/forum/data/attachment/forum/202605/31/203946tiq4x0qnts4kzzti.jpg)



## 环境搭建

搭建 FSP 开发环境。

- 下载并安装 [瑞萨FSP (flexible software package) 灵活配置软件包](https://www.renesas.cn/zh/software-tool/flexible-software-package-fsp) ;
- 下载并安装 [串口调试助手](https://apps.microsoft.com/detail/9nblggh43hdm?launch=true&hl=zh-cn&gl=cn) 软件;
- [下载](https://www.ni.com/zh-cn/support/downloads/software-products/download.labview.html) 并安装 LabVIEW 软件.

详见:[【EK-RA4C1开发套件】介绍、环境搭建、工程测试](//m.qjumbo.com/forum/thread-235467-1-1.html) .

## 工程创建

- [下载](https://www.renesas.cn/zh/design-resources/boards-kits/ek-ra4c1) 官方示例工程软件包;
- 打开 e2 studio 软件;
- 从文件目录 `..\ek_ra4c1\slcdc\slcdc_ek_ra4c1_ep\e2studio` 加载LCD 示例工程;

## 工程配置

- 双击左侧目录文件 `configuration.xml` 进入 FSP Configuration 界面;
- 进入 Pins 标签页,将 P509、P510、P511 配置为输出模式,初始为低电平;
- 设置 JLINK 虚拟串口对应的 GPIO 引脚

- 依次选择 `Pins` - `Peripherals` - `Connectivity:SCI` - `SCI4` 对应 P206 (RXD4) 和 P207 (TXD4) 引脚;
- 新建串口通信堆栈

- `New Stack` - `Connectivity` - `UART (r_sci_uart)`
- 选中 uart 堆栈方框,打开属性标签,配置串口参数;
- 属性设置: `属性` - `Module g_uart4 UART (r_sci_uart)` - `General` 、`Baud`、`Interrupts` 设置回调函数;
- 点击 `Generate Code` 按钮,生成工程代码。

详见:[【EK-RA4C1开发套件】步进电机驱动](//m.qjumbo.com/forum/thread-235479-1-1.html) .

## 流程图
!(//m.qjumbo.com/forum/data/attachment/forum/202605/31/203920nvvvsg6fdjzg2v4z.jpg)


## 工程代码

打开 `./src/hal_entry.c` 文件,添加如下代码

```c++
#include "common_utils.h"
#include "slcdc_ep.h"
#include <stdio.h>
#include "stepmotor.h"

static fsp_err_t slcd_init(void);
static fsp_err_t set_segments_digits( uint32_t value );
static void set_err_segments(void);
static void deinit_slcdc(void);

fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
volatile bool uart_rx_ready = false;
uint8_t uart_rx_buf = {0};
uint32_t uart_rx_len = 0;

void user_uart4_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_RX_CHAR)
    {
      uint8_t ch = (uint8_t)p_args->data;
      if(uart_rx_len < sizeof(uart_rx_buf)-1)
      {
            uart_rx_buf = ch;
      }
      if(ch == '\n' || ch == '}')
      {
            uart_rx_ready = true;
      }
    }
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
      uart_send_complete_flag = true;
    }
}

// 重定向 printf 到 UART4
#ifdef __GNUC__
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE {
    fsp_err_t err = R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)&ch, 1);
    if (FSP_SUCCESS != err) __BKPT();
    while (uart_send_complete_flag == false) {}
    uart_send_complete_flag = false;
    return ch;
}

// 重定向 _write 函数
int _write(int fd, char *pBuffer, int size) {
    for (int i = 0; i < size; i++) {
      __io_putchar(*pBuffer++);
    }
    return size;
}

// 清屏
static void lcd_clear_all(void)
{
    for (int i = 0; i < NUMBER_OF_DIGITS_ON_DISPLAY; i++)
    {
      R_SLCDC_Modify(&g_slcdc_ctrl, digit_start_addresses, 0x00, 0xFF);
      R_SLCDC_Modify(&g_slcdc_ctrl, digit_start_addresses, 0x00, 0xFF);
    }
}

// 解析JSON {"angle":-90,"speed":2}
static void parse_json_cmd(int *angle, uint32_t *speed)
{
    char *p = (char*)uart_rx_buf;
    sscanf(p, "{\"angle\":%d,\"speed\":%lu}", angle, speed);
}

void hal_entry(void)
{
    fsp_err_t err               = FSP_SUCCESS;
    fsp_pack_version_t version= {RESET_VALUE};
    int target_angle = 0;
    uint32_t target_speed = 2; // ms

    err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
    assert(FSP_SUCCESS == err);

    step_motor_init(); // initialize stepper

    while(1){
      if(uart_rx_ready)
      {
            // 解析指令
            parse_json_cmd(&target_angle, &target_speed);
            printf("OK: angle=%d, speed=%lu\r\n", target_angle, target_speed);

            // 显示角度
            lcd_clear_all(); // clear LCD
            set_segments_digits(target_angle); // show rotate angle

            // 电机使能 + 转动
            step_motor_enable();
            step_motor_rotate_degrees((float)target_angle, target_speed);
            step_motor_stop();

            // 转动结束 → 释放扭矩
            step_motor_disable();

            // 清空接收
            memset(uart_rx_buf, 0, sizeof(uart_rx_buf));
            uart_rx_len = 0;
            uart_rx_ready = false;
      }
      else
      {
            // 无数据 → 释放扭矩
            step_motor_disable();
      }
    }
}
```

保存代码。

- 驱动代码文件 `stepmotor.c` 和 `stepmotor.h` 详见:[【EK-RA4C1开发套件】步进电机驱动](//m.qjumbo.com/forum/thread-235479-1-1.html) .

## 编译调试

- 右键工程文件夹,点击构建项目(或点击工具栏小锤子按钮);
- 右键工程文件夹 - 调试/运行项目 - 上传固件至开发板(或点击工具栏小虫子按钮,进入 Debug 模式并运行)。

## 串口测试

- 运行串口调试助手软件,配置波特率 115200 bps 等参数,打开串口;
- 串口发送 JSON 指令 `{"angle": 48, "speed": 2}` ,步进电机以 2ms 延时速度顺时针旋转 48 度;
- 串口发送 JSON 指令 `{"angle": -92, "speed": 2}` ,步进电机以 2ms 延时速度逆时针旋转 92 度;

!(//m.qjumbo.com/forum/data/attachment/forum/202605/31/203854bqsrdodptv9jh1ks.jpg)



## 网页设计

网页设计包括串口配置、发送测试、运行测试、日志打印等模块。

### 上位机代码

```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>42步进电机控制器 - TMC2209</title>
    <style>
      * {
            box-sizing: border-box;
            font-family: Arial, sans-serif;
      }
      body {
            max-width: 480px;
            margin: 30px auto;
            background: #f5f5f5;
      }
      .card {
            background: white;
            padding: 25px;
            border-radius: 14px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
      }
      h2 {
            text-align: center;
            color: #333;
            margin-top: 0;
      }
      .group {
            margin: 18px 0;
      }
      label {
            display: block;
            margin-bottom: 6px;
            font-weight: bold;
            color: #555;
      }
      input {
            width: 100%;
            padding: 12px;
            font-size: 16px;
            border: 1px solid #ddd;
            border-radius: 8px;
      }
      button {
            width: 100%;
            padding: 14px;
            font-size: 16px;
            font-weight: bold;
            color: white;
            background: #007bff;
            border: none;
            border-radius: 8px;
            margin: 6px 0;
            cursor: pointer;
      }
      button.gray {
            background: #6c757d;
      }
      .log {
            margin-top: 20px;
            padding: 12px;
            background: #fafafa;
            border: 1px solid #eee;
            border-radius: 8px;
            height: 140px;
            overflow-y: auto;
            font-size: 13px;
            color: #333;
      }
    </style>
</head>
<body>
<div class="card">
    <h2>步进电机串口控制器</h2>

    <div class="group">
      <label>角度(如 -90、180)</label>
      <input type="number" id="angle" value="-90">
    </div>

    <div class="group">
      <label>速度(延时毫秒)</label>
      <input type="number" id="speed" value="2" min="1" max="20">
    </div>

    <button onclick="connectSerial()">连接串口</button>
    <button onclick="sendCmd()">发送控制指令</button>
    <button class="gray" onclick="disconnectSerial()">断开连接</button>

    <div class="log" id="log"></div>
</div>

<script>
let port;
let writer;
let reader;
let connected = false;

function log(msg) {
    let d = document.getElementById("log");
    d.innerHTML += `→ ${msg}<br>`;
    d.scrollTop = d.scrollHeight;
}

// 连接串口
async function connectSerial() {
    try {
      port = await navigator.serial.requestPort();
      await port.open({ baudRate: 115200 });

      writer = port.writable.getWriter();
      reader = port.readable.getReader();
      connected = true;
      log("串口连接成功 ✅");
    } catch (e) {
      log("连接失败:" + e.message);
    }
}

// 断开串口
async function disconnectSerial() {
    if (!connected) return;
    try {
      await writer.close();
      await reader.cancel();
      await port.close();
      connected = false;
      log("已断开连接 ❌");
    } catch (e) {
      log("断开异常");
    }
}

// 发送JSON指令
async function sendCmd() {
    if (!connected) {
      log("请先连接串口!");
      return;
    }

    let angle = document.getElementById("angle").value;
    let speed = document.getElementById("speed").value;

    // 发送你单片机需要的JSON格式
    let cmd = `{"angle":${angle},"speed":${speed}}\n`;

    try {
      const encoder = new TextEncoder();
      await writer.write(encoder.encode(cmd));
      log(`已发送:${cmd.trim()}`);
    } catch (e) {
      log("发送失败:" + e.message);
    }
}
</script>
</body>
</html>
```

保存代码。

### 控制方案

- 双击打开网页,或使用浏览器加载 HTML 文件;
- 点击连接串口按钮,选择目标串口并连接;
- 设置目标旋转角度、速度;
- 点击发送指令按钮,步进电机转动,完成后反馈结果;

!(//m.qjumbo.com/forum/data/attachment/forum/202605/31/203830drn75f4hll54ojoj.jpg)



### 动态演示

- Web 网页上位机运行后,步进电机按照设定的角度和速度旋转;

!(//m.qjumbo.com/forum/data/attachment/forum/202605/31/203809edvn3lbpllvwqapw.gif)



## 总结

本文介绍了 EK-RA4C1 开发套件结合 TMC2209 模块和 LCD 显示屏,实现串口控制,进一步设计Web网页上位机实现步进电机的可视化UI界面控制的项目设计,包括硬件连接、串口指令控制、网页上位机设计等,为相关产品的快速开发和应用设计提供了参考。

页: [1]
查看完整版本: 【EK-RA4C1开发套件】步进电机串口控制与Web上位机设计

Baidu
map