本帖最后由 sujingliang 于 2026-3-11 13:33 编辑
张驰车队在比赛中途换胎的举动,本质上是在资源受限的困境下,将战术创新与赛道规则进行极致博弈的结果。而自己做遥控小车时,有时也需要换掉整个底盘,来一次移花接木的改装。这既能盘活旧底盘上的可用零件,也为自己开辟了一条新技术路线的学习之旅。
买过带电机和RX2驱动的小车底盘,很遗憾没有TX2遥控部分。
一、关于RX-2/TX-2集成电路
RX-2/TX-2集成电路是一对专为遥控玩具设计的发射(TX-2)与接收(RX-2)大规模集成电路组合,属于配套专用遥控集成电路类别,主要应用于玩具汽车、家用电器及照明设备的无线或红外遥控控制
发射端TX-2可输出带载波或不带载波的编码信号,兼容无线电和红外遥控模式,并内置自动关机功能以降低能耗。接收端RX-2通过外接反相放大器解码信号,输出五路独立控制电平,其五路控制功能在遥控玩具车中通常对应前进、后退、左转、右转和加速。
手头的RX-2型号是8D420L,下面是相关资料:
需要发送2种脉冲信号控制小车:
W1:频率1khz,占空比 50%。
W2:频率500hz,占空比75%。 W2是引导码,一个引导码要连续发4个PWM信号。
W1是功能码,发送个数视功能而定。 举例说明:
如果要小车前进:先发4个W2,再发10个W1;
如果要小车左转:先发4个W2,再发58个W1;
二、改装
思路是RX-2芯片的VI1(第一放大器输入)接MCU,MCU通过串口和蓝牙模块连接。
跳过RX-2外围模拟接收电路,直接用MCU发送编码信息到RX-2的芯片控制信号输入端。
实际连线图:
三、程序
下面仅介绍如何直接驱动RX-2芯片
1、初始化脉冲发送引脚PB5
- #define GPIO_PIN GPIO_PIN_5
- void gpio_pwm_init(void)
- {
- // 配置GPIO为输出
- rcu_periph_clock_enable(RCU_GPIOB);
- gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN);
- gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN);
-
- // 初始低电平
- gpio_bit_reset(GPIOB, GPIO_PIN);
- }
2、发送一个脉冲
- // 发送一个脉冲
- void send_pulse_gpio(uint16_t high_us, uint16_t low_us)
- {
- gpio_bit_set(GPIOB, GPIO_PIN); // 输出高电平
- delay_us(high_us);
-
- gpio_bit_reset(GPIOB, GPIO_PIN); // 输出低电平
- delay_us(low_us);
- }
3、发送完整指令脉冲
- void send_nrz_pulse(uint16_t pulse_width_us, uint16_t freq_hz, float duty_cycle)
- {
- uint16_t period_us = 1000000 / freq_hz; // 周期,单位微秒
- uint16_t high_us = period_us * duty_cycle;
- uint16_t low_us = period_us - high_us;
-
- // 发送指定数量的周期
- uint16_t cycles = pulse_width_us / period_us;
-
- for(uint16_t i = 0; i < cycles; i++) {
- send_pulse_gpio(high_us, low_us);
- }
-
-
- gpio_bit_reset(GPIOB, GPIO_PIN);
- }
4、向前运动
- void forward_gpio(void)
- {
- // 发送W2: 500Hz, 75%占空比, 8ms
- // 500Hz周期 = 2000us = 2ms
- // 75%占空比 = 1500us高, 500us低
- // 8ms需要4个周期 (8ms/2ms = 4)
- for(int i = 0; i < 4; i++) {
- send_pulse_gpio(1500, 500); // 高1500us, 低500us
- }
-
- // 归零间隔
- //delay_us(1000); // 1ms归零时间
-
- // 发送W1: 1000Hz, 50%占空比, 10ms
- // 1000Hz周期 = 1000us = 1ms
- // 50%占空比 = 500us高, 500us低
- // 10ms需要10个周期
- for(int i = 0; i < FORWARD_CMD; i++) {
- send_pulse_gpio(500, 500);
- }
-
- // 最终归零
- gpio_bit_reset(GPIOB, GPIO_PIN);
- }
5、向后运动
- void backward_gpio(void)
- {
- // 发送W2: 500Hz, 75%占空比, 8ms
- // 500Hz周期 = 2000us = 2ms
- // 75%占空比 = 1500us高, 500us低
- // 8ms需要4个周期 (8ms/2ms = 4)
- for(int i = 0; i < 4; i++) {
- send_pulse_gpio(1500, 500); // 高1500us, 低500us
- }
-
- // 归零间隔
- //delay_us(1000); // 1ms归零时间
-
- // 发送W1: 1000Hz, 50%占空比, 10ms
- // 1000Hz周期 = 1000us = 1ms
- // 50%占空比 = 500us高, 500us低
- // 10ms需要10个周期
- for(int i = 0; i < BACK_CMD; i++) {
- send_pulse_gpio(500, 500);
- }
-
- // 最终归零
- gpio_bit_reset(GPIOB, GPIO_PIN);
- }
6、左转
- void left_gpio(void)
- {
- // 发送W2: 500Hz, 75%占空比, 8ms
- // 500Hz周期 = 2000us = 2ms
- // 75%占空比 = 1500us高, 500us低
- // 8ms需要4个周期 (8ms/2ms = 4)
- for(int i = 0; i < 4; i++) {
- send_pulse_gpio(1500, 500); // 高1500us, 低500us
- }
-
- // 归零间隔
- //delay_us(1000); // 1ms归零时间
-
- // 发送W1: 1000Hz, 50%占空比, 10ms
- // 1000Hz周期 = 1000us = 1ms
- // 50%占空比 = 500us高, 500us低
- // 10ms需要10个周期
- for(int i = 0; i < LEFT_CMD; i++) {
- send_pulse_gpio(500, 500);
- }
-
- // 最终归零
- //gpio_bit_reset(GPIOB, GPIO_PIN);
- }
7、发送任一命令
参数CMD对应功能码个数,如10对应前进
- void car_action(uint8_t CMD)
- {
- for(int i = 0; i < 4; i++) {
- send_pulse_gpio(1500, 500); // 高1500us, 低500us
- }
- for(int i = 0; i < CMD; i++) {
- send_pulse_gpio(500, 500);
- }
- }
8、主函数while(1)
#define FORWARD_CMD 10
#define FORWARD_SU_CMD 16
#define FORWARD_SU_LEFT_CMD 28
#define FORWARD_SU_RIGHT_CMD 34
#define STOP_CMD 4
#define BACK_CMD 40
#define BACK_RIGHT_CMD 46
#define BACK_LEFT_CMD 52
#define LEFT_CMD 58
#define RIGHT_CMD 64
- while(1)
- {
- if(rxComplete==1)
- {
- rxComplete=0;
-
- for(i=0;i<rxcount;i++)
- {
- action=receiver_buffer[i];
- switch(receiver_buffer[i])
- {
- case 'a':
- gpio_bit_toggle(GPIOC,GPIO_PIN_13);
- car_action(FORWARD_SU_CMD);
- break;
- case 'b':
- car_action(FORWARD_CMD);
- break;
- case 'c':
- car_action(BACK_LEFT_CMD);
- break;
- case 'd':
- car_action(BACK_RIGHT_CMD);
- break;
- case 'e':
- car_action(STOP_CMD);
- break;
- }
- }
- memset(receiver_buffer,0,32);
- rxcount=0;
- usart_interrupt_enable(USART0, USART_INT_RBNE);
- usart_interrupt_enable(USART0, USART_INT_TC);
- }
-
-
- switch(action)
- {
- case 'a':
- car_action(BACK_CMD);
- break;
- case 'b':
- car_action(FORWARD_CMD);
- break;
- case 'c':
- car_action(BACK_RIGHT_CMD);
- break;
- case 'd':
- car_action(BACK_LEFT_CMD);
- break;
- case 'e':
- car_action(STOP_CMD);
- break;
-
- }
-
- }
这是一个利旧或改造项目,在没有TX2芯片的情况下,继续发挥RX-2芯片的作用驱动小车。
|