建设生活 2024-04-04 22:56 采纳率: 33.3%
浏览 26
已结题

51单片机蓝牙连接手机控制舵机,求解。同志们,非常困难

在做一个基于51单片机连接bt06蓝牙模块控制SG90舵机。 由于我买错舵机型号了买的360度的 不能像180度的可以有多种角度
只能顺时针或者逆时针 所以我就想到了用Delay延时函数来控制运行时间从而控制角度。

  • 为什么我用独立按键测试舵机的时候就可以

-我先用单片机自带的串口和电脑通信试试 结果是可以运行但是会一直转我加的那个延时函数不起作用。

  • 我又接上蓝牙模块试试,结果手机控制都没反应。我反复确认了接线没错,蓝牙模块和电脑也可以互传信息配置AT指令什么的。

卡两天了。b站 CSDN什么的都翻光了。

以下这3个是主要的函数, Delay延时函数是1ms的。

这是主函数

main.c
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
#include "UART.h"

//360度舵机
//0.5ms~1.5ms顺时针只是速度不同 3
//1.5ms~2ms逆针 5

sbit SG_PWM=P2^0; //宏定义引脚
unsigned int count=0; //计次
unsigned int PWM_count=0;
unsigned int NUM;
void main()
{
Timer0_Init();
    UART_Init();


    while(1)
    {
//        if(P3_1==0)                                                     //独立按键测试
//        {    Delay(20);while(P3_1==0);Delay(20);
//            PWM_count=2;
//            count=0;
//                        Delay(100);
//            PWM_count=0;
//        }
//        if(P3_0==0)
//        {    Delay(20);while(P3_0==0);Delay(20);
//        PWM_count=4;
//        count=0;
//            Delay(100);
//            PWM_count=0;
//            
//        }
        
        
    }


}
void Timer0_Routine() interrupt 1  
{
    
    TL0 = 0x33;                //设置定时初始值
    TH0 = 0xFE;                //设置定时初始值

    count++;
    count%=40;


    if(count<PWM_count)
    {
        SG_PWM=1;
    }
    
    else
    {
        SG_PWM=0;
    }
}


void UART_Routine() interrupt 4
{
    
    if(RI==1)
    {
        NUM=SBUF;
        if(NUM==1)
        {
            PWM_count=2;
            Delay(100);
    }
}
     if(NUM==2)                 
     {
       PWM_count=3;
    }
        RI=0;
    
    }

串口函数

#include <REGX52.H>


   //@brief  串口初始化 //4800bps@11.0592MHz
   //@param  无
   //@retval 无
  
    
void UART_Init(void)    //9600bps@11.0592MHz
{
    PCON &= 0x7F;        //波特率不倍速
    SCON = 0x50;        //8位数据,可变波特率
    TMOD &= 0x0F;        //设置定时器模式
    TMOD |= 0x20;        //设置定时器模式
    TL1 = 0xFD;            //设置定时初始值
    TH1 = 0xFD;            //设置定时重载值
    ET1 = 0;            //禁止定时器中断
    TR1 = 1;            //定时器1开始计时
    EA=1;
    ES=1;
}




   //@brief  串口发送一个字节数据
  //@param  Byte 要发送的一个字节数据
  //@retval 无
  

void UART_BsendByte(unsigned char Byte)
{
    SBUF=Byte;
    while(TI==0);
    TI=0;        
}

定时器函数

#include <REGX52.H>

void Timer0_Init(void)        //1毫秒@11.0592MHz
{

    TMOD &= 0xF0;            //设置定时器模式
    TMOD |= 0x01;            //设置定时器模式
    TL0 = 0x33;                //设置定时初始值
    TH0 = 0xFE;                //设置定时初始值
    TF0 = 0;                //清除TF0标志
    TR0 = 1;                //定时器0开始计时
    ET0=1;
    EA=1;
}

  • 写回答

20条回答 默认 最新

  • 关注
    获得0.45元问题酬金

    晚上好🌙🌙🌙
    本答案参考ChatGPT-3.5

    问题分析:

    1. 你使用了延时函数来控制舵机的角度,但由于舵机是360度的,无法像180度舵机那样有多种角度,只能顺时针或逆时针转动。
    2. 你使用了独立按键测试舵机的时候可以正常运行,但连接蓝牙模块后无反应。
    3. 在串口中断中处理接收到的数据进行控制。

    解决方案:

    1. 修改舵机的控制方式,使用PWM来控制舵机的角度。可以通过改变PWM脉宽的占空比来控制舵机的角度。
    2. 使用蓝牙模块连接手机后,手机发送指令给单片机,单片机接收到指令后解析并控制舵机的转动。
    3. 在串口中断中接收手机发送的指令,根据指令控制舵机的转动。

    具体步骤:

    1. 修改舵机控制部分的代码,使用PWM来控制舵机的角度。
    2. 修改主函数,添加蓝牙模块通过串口发送的指令接收。
    3. 在串口中断中添加代码,根据接收到的指令控制舵机的转动。

    修改后的代码如下:

    #include <REGX52.H>
    #include "Delay.h"
    #include "Timer0.h"
    #include "UART.h"
    
    sbit SG_PWM = P2^0; //宏定义引脚
    unsigned int PWM_width = 1500; // 初始PWM脉宽,对应舵机0度
    unsigned int NUM;
    bit isBluetoothControl = 0; // 是否通过蓝牙控制舵机
    
    void main()
    {
        Timer0_Init();
        UART_Init();
    
        while(1)
        {
            if (isBluetoothControl) {
                // 通过蓝牙控制舵机
                if (NUM >= 1000 && NUM <= 2000) {
                    PWM_width = NUM;
                }
            } else {
                // 独立按键控制舵机
                if (P3_1 == 0) {
                    Delay(20);
                    while (P3_1 == 0);
                    Delay(20);
                    PWM_width = 1500; // 舵机归零度
                }
                if (P3_0 == 0) {
                    Delay(20);
                    while (P3_0 == 0);
                    Delay(20);
                    PWM_width = 2000; // 舵机逆时针转动
                }
            }
        }
    }
    
    void Timer0_Routine() interrupt 1  
    {
        TL0 = 0x33; // 设置定时初始值
        TH0 = 0xFE; // 设置定时初始值
    
        if (PWM_width > 1000 && PWM_width < 2000) {
            SG_PWM = 1;
            Delayus(PWM_width - 1000);
            SG_PWM = 0;
            Delayus(20000 - (PWM_width - 1000));
        } else {
            SG_PWM = 0;
            Delayus(20000);
        }
    }
    
    void UART_Routine() interrupt 4
    {
        if(RI == 1)
        {
            NUM = SBUF;
            if (NUM == 255) {
                isBluetoothControl = 1; // 通过蓝牙控制舵机
            } else {
                isBluetoothControl = 0; // 独立按键控制舵机
            }
            RI = 0;
        }
    }
    

    请注意,上述代码只是一个修改示例,可能仍然存在其他问题,需要根据具体情况进行调试和修改。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 4月12日
  • 赞助了问题酬金15元 4月4日
  • 创建了问题 4月4日

悬赏问题

  • ¥15 陆空双模式无人机飞控设置
  • ¥15 sentaurus lithography
  • ¥100 求抖音ck号 或者提ck教程
  • ¥15 关于#linux#的问题:子进程1等待子进程A、B退出后退出(语言-c语言)
  • ¥20 web页面如何打开Outlook 365的全球离线通讯簿功能
  • ¥15 io.jsonwebtoken.security.Keys
  • ¥15 急,ubuntu安装后no caching mode page found等
  • ¥15 联想交换机NE2580O/NE1064TO安装SONIC
  • ¥15 防火墙的混合模式配置
  • ¥15 Ubuntu不小心注销了要怎么恢复啊