找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 261|回复: 8
打印 上一主题 下一主题
收起左侧

请各位大佬帮我看下我的51单片机蓝牙小车代码

[复制链接]
跳转到指定楼层
楼主
ID:1147091 发表于 2025-5-21 17:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的蓝牙模块和避障模块单独使用没有问题,但是两个结合一起想要用蓝牙切换模式的时候蓝牙模块发送数据就没有反应了,也不能切换模式,请各位大佬指点一下,谢谢谢谢。
蓝牙代码:#include<reg52.h>  
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int                        //宏定义,减少后续变量类型书写工作量
sbit IN1=P1^0;                                                 //对应L298N        进行变量定义,通过给4个变量赋值来配置不同的电机运行状态
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;

uchar received;
bit mode_flag = 0;
// 初始化UART
void UART_Init()
{
                PCON = 0x00;  //关倍频
                SCON = 0x50;  // 串口工作模式1,8位数据,1位停止位,允许接收
    TMOD = 0x20;  // 定时器1模式2(8位自动重装)
    TH1 = 0xFD;   // 9600波特率(11.0592MHz晶振)
    TL1 = 0xFD;
                ET1 = 0;
    TR1 = 1;      // 启动定时器1
    EA = 1;       // 开启总中断
    ES = 1;       // 开启串口中断
                PX1 = 1;      // 设置串口中断为高优先级
}

void delay(uint ms)                                //延时函数
{
        uint x,y;
        for(x=ms;x>0;x--)
                for(y=114; y>0; y--);
}

void motor_forward()
{
        IN1=0; IN2=1;                                //智能车左轮正转
        IN3=0; IN4=1;                                //智能车右轮正转
}

void motor_back()
{
        IN1=1; IN2=0;                                //智能车左轮反转
        IN3=1; IN4=0;                                //智能车右轮反转
}

void motor_left()
{
        IN1=0; IN2=1;                                //智能车左轮正转
        IN3=0; IN4=0;                                //智能车右轮停止
}

void motor_right()
{
        IN1=0; IN2=0;                                //智能车左轮停止
        IN3=0; IN4=1;                                //智能车右轮正转
}

void motor_stop()
{
        IN1=0; IN2=0;                                //智能车左轮处于停止状态
        IN3=0; IN4=0;                                //智能车右轮处于停止状态
}

        
void UART_ISR() interrupt 4
{
        
                                RI = 0;                                                //接收中断标志位清零
        received = SBUF;                //从缓冲区接收数据
               
            switch (received)
        {
            case '2':  // 前进
                motor_forward();                                
                break;
            case '8':  // 后退
                motor_back();
                break;
            case '4':  // 左转
                motor_left();
                break;
            case '6':  // 右转
                motor_right();
                break;
            case '0':  // 停止
                motor_stop();
                break;
                                                case 'A':  // 切换到超声波测距避障模式
                                                                mode_flag = 1;
                                                                motor_stop();
                                                                break;
                                                case 'B':  // 切换回蓝牙模式
                                                                mode_flag = 0;
                                                                motor_stop();
                                                                break;
            default:
                motor_stop();
                break;
        }

}
超声波代码:#include <reg52.h>  
#include <intrins.h>
#include "lanya.h"

sbit Trig = P2^0;
sbit Echo = P2^1;

extern int sum;
extern int mindistance;

void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 43;
        j = 6;
        k = 203;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Delay20us()                //@11.0592MHz
{
        unsigned char i;

        _nop_();
        _nop_();
        _nop_();
        i = 22;
        while (--i);
}

void chaoshengbo()
{
        unsigned char timeout = 0;
               
                T2CON = 0x00;  // 配置定时器2为16位自动重装模式(非捕获)
    RCAP2H = 0x00; // 自动重装高字节(初始值0)
    RCAP2L = 0x00; // 自动重装低字节(初始值0)
    TH2 = 0x00;    // 定时器2高字节初始值(测量时从0开始计数)
    TL2 = 0x00;    // 定时器2低字节初始值
                PT2 = 0;
        
        Trig = 1;
        Delay20us();
        Trig = 0;
        
        while (!Echo) {
                if (++timeout > 200) {  
                        sum = 65535;
                        return;
                }
        }
        TL2 = 0;
        TH2 = 0;
        TR2 = 1;
        
        while (Echo);
        TR2 = 0;
        
        sum = ((TH2 * 256 + TL2) * 17) / 1000;
        
}
舵机代码:#include<reg52.h>  
#include<intrins.h>
#include "lanya.h"
#include "chaoshengbo.h"

sbit PWM = P2^6;

unsigned char counter,angle;
unsigned int sum,distance1,distance2,distance3;
unsigned int mindistance = 20;

void Delay500ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 22;
        j = 3;
        k = 227;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Delay20ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 1;
        j = 216;
        k = 35;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


void Timer0_Init()
{
    TMOD = 0x01; // 定时器 0 工作在模式 2(8 位自动重装)
    TL0 = 0x33;
    TH0 = 0xfe;
    TF0 = 0;
    TR0 = 1;
    ET0 = 1;
    EA = 1;
}

void Timer0_Routine() interrupt 1
{
    TL0 = 0x33; // 重装载定时初值
    TH0 = 0xfe;
    counter++;
    if(counter >= 40) // 假设 200 个计数值对应一个 PWM 周期
    {
        counter = 0;
    }
    if(counter < angle) // angle 的范围应根据占空比需求设置,例如 10~20 对应 5%~10% 占空比
    {
        PWM = 1;
    }
    else
    {
        PWM = 0;
    }
}

void control_2()
{
                counter = 0;
    angle = 3; // 舵机归中°
    Delay500ms();
}

void control()
{
    counter = 0;
    angle = 2; // 舵机转到 45°
    Delay500ms();
    chaoshengbo();
                distance1=sum;
        
    counter = 0;
    angle = 4; // 舵机转到 -45°
    Delay500ms();

    counter = 0;
    angle = 3; // 舵机转到中间角度
    Delay500ms();
                chaoshengbo();
                distance2=sum;

}

void chaoshengboduoji()
{
        chaoshengbo();
        distance3 = sum;
        
        if(distance3<mindistance)
        {
                motor_stop();
                Delay500ms();
                control();
                if(distance1<distance2 && distance1 > mindistance)
                {
                        motor_right();
                        Delay20ms();
                        motor_stop();
                        Delay500ms();
                        motor_forward();
                }
                if(distance2<distance1 && distance2 > mindistance)
                {
                        motor_left();
                        Delay20ms();
                        motor_stop();
                        Delay500ms();
                        motor_forward();
                }
                if(distance2==distance1)
                {
                        motor_left();
                        Delay20ms();
                        motor_stop();
                        Delay500ms();
                        motor_forward();
                }
        }
        else
                motor_forward();
}
主函数:
#include<reg52.h>  
#include"chaoshengbo.h"
#include"lanya.h"
#include"duoji.h"
extern bit mode_flag;
void main() {
    // 初始化各个模块
    UART_Init();        // 蓝牙串口初始化
    Timer0_Init();      // 舵机PWM定时器初始化

    while (1) {
        if (mode_flag == 0) {
            // 蓝牙模式,无需额外操作,蓝牙中断服务函数处理
        } else {
            // 超声波测距避障模式
                                                motor_forward();
            chaoshengboduoji();
        }
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1147091 发表于 2025-5-21 17:15 | 只看该作者
不好意思各位,Echo被论坛自动识别为回声了,三角是Trig;
回复

使用道具 举报

板凳
ID:844772 发表于 2025-5-22 15:18 | 只看该作者
TMOD = 0x01; // 定时器 0 工作在模式 2(8 位自动重装)
改为:  TMOD |= 0x01;
回复

使用道具 举报

地板
ID:1147091 发表于 2025-5-22 16:38 | 只看该作者
glinfei 发表于 2025-5-22 15:18
TMOD = 0x01; // 定时器 0 工作在模式 2(8 位自动重装)
改为:  TMOD |= 0x01;

好的,好的,解决了,感谢大佬
回复

使用道具 举报

5#
ID:1147091 发表于 2025-5-22 16:39 | 只看该作者
已经解决了,感谢大佬
回复

使用道具 举报

6#
ID:1147091 发表于 2025-5-22 23:21 | 只看该作者
glinfei 发表于 2025-5-22 15:18
TMOD = 0x01; // 定时器 0 工作在模式 2(8 位自动重装)
改为:  TMOD |= 0x01;

: 大佬,不会意思打扰您了,我改好TMOD后,蓝牙和超声波避障可以正常切换了,于是我就又加了个红外寻迹模式(没有使用定时器),然后我的蓝牙和红外寻迹可以正常切换,但是从蓝牙切换超声波模式,蓝牙就自己断联,请大佬帮我分析一下,谢谢
typedef enum {
    ULTRASONIC_MODE = 1,
                HONGWAIXUN_MODE,
                BLUETOOTH_MODE
}Mode;
#include<reg52.h>  
#include<intrins.h>
#include "lanya.h"

sbit D1 = P1^7;
sbit D2 = P1^6;
sbit D3 = P1^5;
sbit D4 = P1^4;

void Delay50ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 3;
        j = 26;
        k = 223;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void xunji()
{
        if(D1==1&&D2==1&&D3==1&&D4==1)  //全检测黑线
                motor_forward();
        if(D1==0&&D2==1&&D3==0&&D4==0)  //中间右侧检测到黑线,小车偏左,小车向右移动
        {
                motor_right();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                        motor_forward();
        }
        if(D1==0&&D2==0&&D3==1&&D4==0)  //中间左侧检测到黑线,小车偏右,小车向左移动
        {
                motor_left();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                        motor_forward();
        }
        if(D1==0&&D2==0&&D3==1&&D4==1)  //直角左转
        {
                motor_forward();
                Delay50ms();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                {
                        motor_stop();
                        Delay50ms();
                        motor_left();
                }
        }
        if(D1==1&&D2==1&&D3==0&&D4==0)  //直角右转
        {
                motor_forward();
                Delay50ms();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                {
                        motor_stop();
                        Delay50ms();
                        motor_right();
                }
        }
        if((D1==0&&D2==0&&D3==0&&D4==1)||(D1==0&&D2==1&&D3==0&&D4==1)||D1==0&&D2==1&&D3==1&&D4==1) //锐角左转
        {
                motor_forward();
                Delay50ms();
                Delay50ms();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                {
                        motor_stop();
                        Delay50ms();
                        motor_left();
                }
        }
        if((D1==1&&D2==0&&D3==0&&D4==0)||(D1==1&&D2==1&&D3==1&&D4==0)||D1==1&&D2==1&&D3==1&&D4==0) //锐角右转
        {
                motor_forward();
                Delay50ms();
                Delay50ms();
                if(D1==0&&D2==0&&D3==0&&D4==0)
                {
                        motor_stop();
                        Delay50ms();
                        motor_right();
                }
        }
        if(D1==0&&D2==1&&D3==1&&D4==0)
        {
                if(D1==1)
                        motor_right();
        }
        if(D1==0&&D2==1&&D3==1&&D4==0)
        {
                if(D4==1)
                        motor_right();
        }
}
void main() {
    // 初始化各个模块
    UART_Init();        // 蓝牙串口初始化
    Timer0_Init();      // 舵机PWM定时器初始化
                control_2();
       
    while (1) {
        if (current_mode == BLUETOOTH_MODE) {
            // 蓝牙模式
                                        lanya(received);
                                       
        } else if(current_mode ==HONGWAIXUN_MODE){
            // 红外寻迹模式
            xunji();
        } else {
                                                motor_forward();
            chaoshengboduoji();
                                }
    }
回复

使用道具 举报

7#
ID:844772 发表于 2025-5-23 10:39 | 只看该作者
蓝牙就自己断联,是指从状态灯看出,蓝牙断开连接了,而不是按键没反应?
如果就是一进入,就断开连接,那跟程序关系不大,基本是电源的问题,建议测试时使用双电源,临时拿个小充电宝给控制部分供电。
另外,觉得这个在中间跑偏,以及走直角弯的考虑不周全啊,难道车很慢吗?
回复

使用道具 举报

8#
ID:1147091 发表于 2025-5-23 12:12 | 只看该作者
glinfei 发表于 2025-5-23 10:39
蓝牙就自己断联,是指从状态灯看出,蓝牙断开连接了,而不是按键没反应?
如果就是一进入,就断开连接,那 ...

断联是,我发送切换超声波的数据,差不多一两秒左右,蓝牙调试器就显示未连接设备,我的车跑的确实慢,因为我只用了四节干电池给整个小车供电。但是我切换红外他就可以正常切换
回复

使用道具 举报

9#
ID:844772 发表于 2025-5-27 08:19 | 只看该作者
这是蓝牙连接断了,不是软件问题啊,因为车蓝牙模块连接的舵机,我觉的还是电源问题,能否先试用双电源供电,或使用18650电池。或你先屏蔽掉舵机工作程序,看看蓝牙是否掉线。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表