[其它] 基于瑞萨RA8单片机的智能小车项目方案代码分享

[复制链接]
581|5
流鱼 发表于 2025-11-28 15:48 | 显示全部楼层 |阅读模式
, , , ,
本帖最后由 流鱼 于 2025-11-28 15:52 编辑

智能小车是大学生参加电子相关竞赛的重要项目之一,其中包含的内容也是非常多,在这里我就简单的分享一些基于瑞萨RA8单片机以及瑞萨官方开发环境e2s的智能小车功能模块分享,希望对有需要的人有一定帮助。

在正贴部分我会简单的聊一聊智能小车的一些技术需求,然后在回帖中贴出相应的瑞萨RA8模块代码,希望能帮到大家。

电机驱动控制:
控制小车的左右电机,实现前进、后退、左转、右转、停止等基本运动功能。
实现方式:
使用电机驱动模块(如L298N)控制电机的正反转和速度。
通过PWM(脉宽调制)调节电机速度。
使用GPIO控制电机的方向。
关键技术:
PWM信号生成。
GPIO控制。

寻迹:
小车能够自动沿着预设的黑线或白线行驶
实现方式:
使用红外传感器或灰度传感器检测地面黑线。
根据传感器反馈的数据调整小车的运动方向
关键技术:
传感器数据采集。
控制算法(如PID控制)实现精准循迹

避障:
小车能够检测前方障碍物并自动避开
实现方式:
使用超声波传感器或红外避障模块检测前方障碍物。
根据检测结果调整小车的运动方向。
关键技术:
超声波测距或红外避障。
避障算法(如转向或后退)

通信:
小车能够与上位机(如PC或手机)进行通信,接收控制指令并发送传感器数据
实现方式:
使用UART、蓝牙、Wi-Fi等通信模块实现数据传输。
定义通信协议,如发送控制命令(前进、后退等)和接收传感器数据。
关键技术:
串口通信(UART)
无线通信(蓝牙、Wi-Fi)
通信协议设计

遥控:
用户可以通过遥控器或手机APP远程控制小车的运动
实现方式:
使用红外遥控器、蓝牙或Wi-Fi模块接收控制指令。
解析指令并控制小车的运动。
关键技术:
红外信号解码。
蓝牙/Wi-Fi通信。

环境检测:
用户可以通过遥控器或手机APP远程控制小车的运动
实现方式:
使用温湿度传感器、光照传感器等采集环境数据。
通过通信模块将数据发送到上位机或显示在LCD屏幕上。
关键技术:
传感器数据采集。
数据通信与显示。

路径规划与导航:
小车能够根据预设的路径或地图自主导航
实现方式:
使用地图数据或路径规划算法(如A*算法)。
结合传感器数据实现自主导航。
关键技术:
路径规划算法
传感器融合(如红外、超声波、摄像头)

显示与交互:
小车能够根据预设的路径或地图自主导航
实现方式:
小车能够通过LCD屏幕显示状态信息(如速度、方向、传感器数据等)。
用户可以通过按键或触摸屏与小车的交互
关键技术:
LCD驱动。
按键或触摸屏输入处理

电源管理:
管理小车的电源,确保系统稳定运行
实现方式:
使用电池供电,设计电源管理电路。
监测电池电量,低电量时提醒用户充电。
关键技术:
电源管理电路设计。
电池电量监测。

数据存储与日志:
小车能够记录运行日志或传感器数据,便于后续分析
实现方式:
使用EEPROM或SD卡存储数据。
定义数据格式,如时间戳、传感器数据等
关键技术:
数据存储(EEPROM、SD卡)。
数据格式设计

拓展功能:
根据需求扩展更多功能,如摄像头图像识别、语音控制等
实现方式:
使用摄像头模块实现图像识别。
使用语音识别模块实现语音控制。
关键技术:
图像处理与识别
语音识别与处理




 楼主| 流鱼 发表于 2025-11-28 15:58 | 显示全部楼层
我分享的项目主要实现了以下几个功能:
自主避障
超声波传感器实时检测前方障碍物距离。
当距离小于设定阈值时,小车停止前进并转向。
转向后继续前进,直到避开障碍物。
巡线行驶
红外传感器检测地面黑线。
根据传感器信号调整小车方向,使其沿黑线行驶。
遥控控制
手机APP通过蓝牙发送指令。
小车接收指令后执行相应的动作,例如前进、后退、左转、右转等。

在硬件部分,
主控MCU使用了瑞萨RA8D1单片机
电机驱动使用了L298N电机驱动模块
传感器使用了超声波传感器(HC-SR04)用于避障、红外传感器(TCRT5000)用于巡线、蓝牙模块(HC-05)用于遥控
电源选用了7.4锂电池

 楼主| 流鱼 发表于 2025-11-28 16:17 | 显示全部楼层
本帖最后由 流鱼 于 2025-11-28 16:23 编辑

电机驱动控制:

#include "r_smc_entry.h"
#include "r_gpio_rx_if.h"
#include "r_pwm_rx_if.h"


#define MOTOR_LEFT_FORWARD    (BSP_IO_PORT_01_PIN_00)  // 左电机前进
#define MOTOR_LEFT_BACKWARD   (BSP_IO_PORT_01_PIN_01)  // 左电机后退
#define MOTOR_RIGHT_FORWARD   (BSP_IO_PORT_01_PIN_02)  // 右电机前进
#define MOTOR_RIGHT_BACKWARD  (BSP_IO_PORT_01_PIN_03)  // 右电机后退
#define PWM_CHANNEL_LEFT      (0)  // 左电机PWM通道
#define PWM_CHANNEL_RIGHT     (1)  // 右电机PWM通道


// 初始化电机驱动
void motor_init(void){   
R_GPIO_PinCfg(MOTOR_LEFT_FORWARD, GPIO_CFG_OUTPUT | GPIO_CFG_PORT_DIRECTION_OUTPUT);   
R_GPIO_PinCfg(MOTOR_LEFT_BACKWARD, GPIO_CFG_OUTPUT | GPIO_CFG_PORT_DIRECTION_OUTPUT);   
R_GPIO_PinCfg(MOTOR_RIGHT_FORWARD, GPIO_CFG_OUTPUT | GPIO_CFG_PORT_DIRECTION_OUTPUT);   
R_GPIO_PinCfg(MOTOR_RIGHT_BACKWARD, GPIO_CFG_OUTPUT | GPIO_CFG_PORT_DIRECTION_OUTPUT);
R_PWM_Open(PWM_CHANNEL_LEFT, 1000);  // 初始化左电机PWM,频率1kHz   
R_PWM_Open(PWM_CHANNEL_RIGHT, 1000); // 初始化右电机PWM,频率1kHz
}


// 设置电机速度
void motor_set_speed(uint8_t channel, uint16_t speed){   
R_PWM_Write(channel, speed);  // 设置PWM占空比
}


// 控制小车运动
void car_move_forward(void){   
R_GPIO_PinWrite(MOTOR_LEFT_FORWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_LEFT_BACKWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_FORWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_RIGHT_BACKWARD, GPIO_LEVEL_LOW);
}


void car_move_backward(void){   
R_GPIO_PinWrite(MOTOR_LEFT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_LEFT_BACKWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_RIGHT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_BACKWARD, GPIO_LEVEL_HIGH);
}

void car_turn_left(void){   
R_GPIO_PinWrite(MOTOR_LEFT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_LEFT_BACKWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_RIGHT_FORWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_RIGHT_BACKWARD, GPIO_LEVEL_LOW);
}

void car_turn_right(void){   
R_GPIO_PinWrite(MOTOR_LEFT_FORWARD, GPIO_LEVEL_HIGH);   
R_GPIO_PinWrite(MOTOR_LEFT_BACKWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_BACKWARD, GPIO_LEVEL_HIGH);
}

void car_stop(void){   
R_GPIO_PinWrite(MOTOR_LEFT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_LEFT_BACKWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_FORWARD, GPIO_LEVEL_LOW);   
R_GPIO_PinWrite(MOTOR_RIGHT_BACKWARD, GPIO_LEVEL_LOW);
}
 楼主| 流鱼 发表于 2025-11-28 16:27 | 显示全部楼层
寻迹功能:


#define IR_SENSOR_LEFT    (BSP_IO_PORT_02_PIN_00)  // 左侧红外传感器
#define IR_SENSOR_RIGHT   (BSP_IO_PORT_02_PIN_01)  // 右侧红外传感器


// 读取红外传感器状态
uint8_t read_ir_sensor(void){   
    uint8_t left = R_GPIO_PinRead(IR_SENSOR_LEFT);   
    uint8_t right = R_GPIO_PinRead(IR_SENSOR_RIGHT);   
    return (left << 1) | right;  // 返回传感器状态
}


// 自动寻迹
void car_line_following(void){   
    uint8_t sensor_state = read_ir_sensor();   
    switch (sensor_state)   
    {        
        case 0b01:  // 左侧检测到黑线            
           car_turn_left();            
           break;        
        case 0b10:  // 右侧检测到黑线            
           car_turn_right();            
           break;        
        case 0b11:  // 两侧都检测到黑线            
           car_move_forward();            
           break;        
        default:    // 未检测到黑线            
           car_stop();            
           break;   
    }
}
 楼主| 流鱼 发表于 2025-11-28 16:33 | 显示全部楼层
超声波与距离

// 超声波初始化
void ultrasonic_init(void){   
// 配置Trig引脚为输出模式,Echo引脚为输入模式   
R_IOPORT_PinCfg(&g_ioport_ctrl, TRIG_PIN, IOPORT_CFG_PORT_DIRECTION_OUTPUT);   
R_IOPORT_PinCfg(&g_ioport_ctrl, ECHO_PIN, IOPORT_CFG_PORT_DIRECTION_INPUT);
}


// 获取距离
uint32_t get_distance(void){   
   uint32_t duration = 0;
    // 发送10us的高电平脉冲   
   R_IOPORT_PinWrite(&g_ioport_ctrl, TRIG_PIN, IOPORT_LEVEL_HIGH);   
   R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MICROSECONDS);   
   R_IOPORT_PinWrite(&g_ioport_ctrl, TRIG_PIN, IOPORT_LEVEL_LOW);

    // 等待Echo引脚变高   
   while (R_IOPORT_PinRead(&g_ioport_ctrl, ECHO_PIN) == IOPORT_LEVEL_LOW);

    // 开始计时   
   R_GPT_Start(&g_timer0_ctrl);

    // 等待Echo引脚变低   
   while (R_IOPORT_PinRead(&g_ioport_ctrl, ECHO_PIN) == IOPORT_LEVEL_HIGH);

    // 停止计时并获取时间   
   R_GPT_Stop(&g_timer0_ctrl);   
   duration = R_GPT_CounterGet(&g_timer0_ctrl);

    // 计算距离   
   return duration * 0.034 / 2;
}
 楼主| 流鱼 发表于 2025-11-28 16:37 | 显示全部楼层
通信功能:


#define UART_CHANNEL    (2)  // 使用UART2
volatile bool g_uart_rx_complete = false;
char g_uart_rx_buffer[64] = {0};
uint16_t g_uart_rx_index = 0;


// UART回调函数
void uart_callback(uart_callback_args_t *p_args){   
     if (p_args->event == UART_EVENT_RX_CHAR)   
     {        
         if (p_args->data != '\r' && p_args->data != '\n')      
         {            
          g_uart_rx_buffer[g_uart_rx_index++] = p_args->data;        
         }        
         else if (p_args->data == '\n')        
         {            
          g_uart_rx_buffer[g_uart_rx_index] = '\0';            
          g_uart_rx_complete = true;           
          g_uart_rx_index = 0;      
         }   
      }
}

// 初始化UART
void uart_init(void){   
     uart_instance_ctrl_t uart_ctrl;   
     const uart_cfg_t uart_cfg =   
     {      
      .channel             = UART_CHANNEL,      
      .data_bits           = UART_DATA_BITS_8,     
      .parity              = UART_PARITY_OFF,     
      .stop_bits           = UART_STOP_BITS_1,     
      .p_callback          = uart_callback,     
      .p_context           = NULL,      
      .p_extend            = NULL,        
      .baud_rate           = 9600,      
      .rx_buffer_size      = 64,      
      .tx_buffer_size      = 64,   
      };   
      R_UART_Open(&uart_ctrl, &uart_cfg);
}

// 发送数据到上位机
void uart_send_data(char *data){  
    R_UART_Write(UART_CHANNEL, (uint8_t *)data, strlen(data));
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

27

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部
0