浮云落笔

浮云落笔

首页
瞬间
反馈
浮云落笔

浮云落笔

首页 瞬间 反馈
  1. 首页
  2. 默认分类
  3. 档位控制

档位控制

  • 默认分类
  • 发布于 2026-05-16
  • 46 次阅读
flor
flor

明白了。帧只管切档,舵机自己连续往复。


新代码

全局变量(替换之前的 gear_mode)

uchar gear_mode = 0;                    // 当前档位 0/1/2/3
int  max_angle[4] = {0, 60, 120, 180}; // 每档最大角度
bit  sweep_up = 1;                      // 1=上升 0=下降
uint cur_angle = 0;                     // 当前角度(0~180)

angle_to_duty(不变)

uint angle_to_duty(uint angle) {
    return (uint)(250 + ((unsigned long)angle * 1000 / 180));
}

servo_sweep() — 走一步(新函数)

void servo_sweep(void) {
    uint step = 3;                     // 步长3°, 越大越快
    uint target = max_angle[gear_mode];

    if(gear_mode == 0) {
        cur_angle = 0;
        PWM_change(20, 250);           // 停住0°
        return;
    }

    if(sweep_up) {
        cur_angle += step;
        if(cur_angle >= target) {
            cur_angle = target;
            sweep_up = 0;              // 到顶, 转头
        }
    } else {
        if(cur_angle <= step) {
            cur_angle = 0;
            sweep_up = 1;              // 到底, 转头
        } else {
            cur_angle -= step;
        }
    }

    PWM_change(20, angle_to_duty(cur_angle));
}

main() 里 while(1) 改成这样

void main(void) {
    // ===== 初始化 (不变) =====
    GPIO_init_allpin(0);
    GPIO_init_pin(27, 1);
    UART_init(1, 115200, 1, 1);
    UART_init(2, 115200, 1, 0);
    PWM_init(20, 50, 250);    // 初始0°
    EA = 1;

    uint sweep_timer = 0;     // 往复计时器

    while(1) {
        // ===== ① 串口帧处理 (不变) =====
        if(next != current) {
            switch(UART_FLAG) {
                case 0: {
                    if(UART_DATA[current] == 0x5a) {
                        uart2_data[ia] = UART_DATA[current];
                        ia++;
                        UART_FLAG = 1;
                    }
                } break;
                case 1: {
                    if(UART_DATA[current] == 0xa5) {
                        uart2_data[ia] = UART_DATA[current];
                        ia++;
                        UART_FLAG = 2;
                    }
                } break;
                case 2: {
                    if(ia == 2) {
                        uart2_data[ia] = UART_DATA[current];
                        ia++;
                        ja = uart2_data[2] + 1;
                        UART_FLAG = 3;
                    }
                } break;
                case 3: {
                    ja--;
                    uart2_data[ia] = UART_DATA[current];
                    ia++;
                    if(ja == 1) {
                        ia = 0;

                        // ★ 每收一帧 → 切一档, 不复位方向
                        gear_mode++;
                        if(gear_mode >= 4) gear_mode = 0;

                        UART_1(1, uart2_data);
                        led01(uart2_data);
                        UART_FLAG = 0;
                    }
                } break;
            }
            current++;
        }

        // ===== ② 舵机自动往复 (只此一处新增) =====
        sweep_timer++;
        if(sweep_timer >= 600) {       // 调这个数改速度
            sweep_timer = 0;
            servo_sweep();             // 每600次循环走1步
        }
    }
}

🎯 改动总结

原来的 pwm_p20():  收帧→切档+走一步  (删掉不用了)
新的 servo_sweep(): 只做往复运动, 自己循环跑

main() 里:
  收帧 → gear_mode++  (只切档)
  while(1)末尾 → 自动调 servo_sweep() (舵机一直动)

🔧 调速

if(sweep_timer >= 600)    // 600 = 慢
if(sweep_timer >= 200)    // 200 = 快
if(sweep_timer >= 50)     // 50  = 飞快

你觉得太快或太慢就改这个数。


✅ 预期效果

上电 → 0°静止
发1帧 → 切1档 → 舵机自己 0↔60° 来回摆
发1帧 → 切2档 → 舵机自己 0↔120° 来回摆
发1帧 → 切3档 → 舵机自己 0↔180° 来回摆
发1帧 → 切0档 → 舵机回0° 停住

目录
湘ICP备2025147565号-1
gongan beian 湘公网安备43102602000213号