基于单片机的小车循迹避障 程序 仿真 原文都有 利用超声波检测,对前方的障碍物进行躲避,前方遇到障碍物小车掉头继续循迹行驶; 对小车循迹行驶的过程中的车速检测并显示在LCD1602上; 系统的主控模块选择使用STC89C52单片机,除此之外,还要有避障模块以及电机驱动模块等组成。 避障中的传感器检测到信号输出到STC89C52单片机,电机驱动模块改变电机的状态,实现智能行驶,同时要加入测速电路将小车行驶时的速度检测出来并且显示在屏幕上。 为了更好地完成此设计任务,我们使用了四轮车,该四轮车由四个直流电机进行驱动,从而调节四个轮子的速度以启动和停止。 其中,在同一侧的轮子的电机状态保持一致,达到控制转向的目的。 由软件程序控制,并结合硬件体系结构,这样就实现了循迹和避障的功能。

最近在搞一个单片机小车的项目,挺有意思的。这货能自己沿着黑线跑,遇到障碍物还能自动掉头,速度还能实时显示在液晶屏上。今天就跟大伙儿唠唠这玩意儿的实现过程,特别是代码里那些有意思的坑。

先说硬件架构,核心用了老当益壮的STC89C52,这单片机虽然年纪大但扛造啊。电机驱动直接上L298N模块,四路PWM输出带四个直流电机。重点来了——左右两侧电机并联控制,这样转向时同侧轮子转速一致,转弯半径贼稳。

避障部分用HC-SR04超声波模块,这货的代码挺有意思:

void GetDistance(){
    Trig = 1;
    delay_20us();
    Trig = 0;
    while(!Echo);  // 等回响信号
    TR0 = 1;       // 启动定时器
    while(Echo);
    TR0 = 0;       // 停止定时器
    distance = (TH0*256+TL0)*0.017; // 算距离
}

这段代码有个坑,定时器记得用模式1(16位)。实测超过4米会溢出,不过咱们小车工作范围1米足够。当检测到距离小于15cm时,直接触发中断让电机反转1秒,配合循迹模块重新规划路线。

速度检测用的是槽型光耦,在轮轴上贴了片遮光片。每转一圈触发两次中断,通过定时器计算转速:

void EX0_IRQHandler() interrupt 0 { 
    pulse_count++;
    if(pulse_count >= 8){  // 转4圈计算一次
        speed = 120000/(TH1*256+TL1); // 根据时间算RPM
        TH1 = TL1 = 0;
        pulse_count = 0;
    }
}

这里120000是经验值,需要根据车轮周长校准。显示部分用LCD1602,注意它的初始化时序特别矫情,必须严格按照数据手册来。建议直接套用现成的驱动库,省得折腾。

电机控制是重头戏,PWM用定时器2实现:

void PWM_Init(){
    T2MOD = 0x00;
    T2CON = 0x00;
    RCAP2 = 0xDC;  // 100Hz PWM
    TR2 = 1;
}

void SetMotor(){
    if(left_speed > 0)  // 正转
        P1 |= 0x03; 
    else                // 反转
        P1 &= 0xFC;
    CCAP0H = left_speed;
    CCAP1H = right_speed;
}

实测发现占空比超过80%时电机发热明显,所以程序里做了限幅。转向时左右轮差速建议不超过30%,否则容易原地打滑。

最后说说调试经验:遇到电磁干扰导致超声波误触发,在VCC和GND之间加了个104电容搞定;循迹传感器夜间受环境光影响大,后来改用红外对管加遮光罩;电机启动瞬间会引起电压跌落,记得在电源处并个4700μF的电容。

这项目最爽的是看着小车灵活地蛇形走位避开障碍,液晶屏上的速度值跟着实时变化。虽然现在很多现成的智能车方案,但自己从寄存器层面撸代码的感觉确实不一样。下次准备给它加个蓝牙遥控,搞成可编程的玩具车应该挺有意思。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐