股间一郎 2024-03-09 19:54 采纳率: 0%
浏览 28

51单片机通过蓝牙控制SG90舵机

在运行程序时经常出现蓝牙模块断线及舵机只出声不动的问题,怀疑和中断以及电压有关。代码如下:

#include <REGX52.H>
#include "timer0.h"
#include "Uart.h"
 //模拟舵机控制原理:0~180°;0.5ms-----0度;1.0ms-----45度;1.5ms-----90度;2.0ms-----135度;2.5ms-----180//电机控制原理:1ms占空比最小速度 2ms占空比最大速度 区间内模拟调速
sbit SG_PWM = P1^1;                            //信号控制引脚

unsigned char count = 0;                         //计次  赋初值为0
unsigned char PWM_count = 0;                  //0--0度,2--45度,4--90度,6--135度,8--180度

void main()
{
  TMOD &= 0xF0;        //设置定时器模式
    TMOD |= 0x01;        //设置定时器模式
    TL0 = 0x33;        //设置定时初始值
    TH0 = 0xFE;        //设置定时初始值
    ET0 = 1;      //打开定时器0的中断
    TF0 = 0;            //清除溢出中断标志位
    TR0 = 1;            //定时器0开始计时
    EA = 1;          //开总中断
     PCON |= 0x80;        //使能波特率加倍    
    SCON = 0x50;        //接收8位数据
    TMOD &= 0x0F;        //清除定时器1模式
//00 
    TMOD |= 0x20;        //设定定时器8为自动
    TL1 = 0xFA;            //设定初始值
    TH1 = 0xFA;            //设定初始值
    ET1 = 0;        
  TR1 = 1;
  EA = 1;
  ES =1 ;     
  while(1)
  {
        
   }
}

void Timer0() interrupt 1      //特别注意此处,0--外部中断01--定时器中断02--外部中断13--定时器中断14--串行口中断1
{
  
  TL0 = 0x33;        
  TH0 = 0xFE;                 //重新赋计数初值为0.5ms
  
  count++;                    //计次,每500us  count+1
    count%=40;                //周期为20ms
    
  if(count<PWM_count)
  {                                    
    SG_PWM=1;
  }
  else
  {
    SG_PWM=0;
  }
}


void UART_Routine()  interrupt 4    //串口中断服务函数
{    
    if(RI==1)                        //如果接收中断标志位为1
    {    
      P1=SBUF;                       //发送的数据SBUF,赋给P1
     if(P1==0X01)                   //0x01这个值可以通过蓝牙调试器编辑模式设置
     {
       PWM_count=1;
     }
     if(P1==0X02)                  
     {
       PWM_count=2;
     }
     if(P1==0X03)                 
     {
       PWM_count=3;
     }
     if(P1==0X04)                  
     {
       PWM_count=4;
     }
     if(P1==0X05)                  
     {
       PWM_count=5;
     }
     
      RI=0;                        //接收中断标志位软件清零
    }
}


  • 写回答

4条回答 默认 最新

  • 关注

    股间一郎 晚上好🌙🌙🌙
    本答案参考ChatGPT-3.5

    问题分析: 从提供的代码来看,您正在尝试通过51单片机的定时器0(Timer0)产生PWM波来控制SG90舵机,并通过串口中断(UART_Routine)接收蓝牙模块发送的数据来调节舵机的角度。但是,在运行过程中遇到了蓝牙模块断线以及舵机只出声不动的问题。

    解决方案:

    1. 蓝牙模块断线问题

      • 检查蓝牙模块与单片机之间的连接是否稳定,包括电源供电、TX/RX信号线等。
      • 蓝牙通信协议和波特率设置是否正确一致,确保数据传输无误。
      • 增加软件层面的重连机制,当检测到蓝牙断开时,尝试重新连接。
    2. 舵机只出声不动问题

      • 检查SG90舵机供电电压是否足够,通常需要4.8V-6V。
      • 根据舵机的工作原理,确认PWM信号频率是否在50Hz左右,占空比调整是否正确对应舵机角度。根据代码,PWM周期约为20ms,符合SG90舵机的要求,但需要检查PWM_count值的变化是否能正确控制占空比。
      • 检查P1^1引脚(SG_PWM)与舵机信号线之间是否有接触不良或短路等问题。

    针对代码优化建议:

    #include <REGX52.H>
    #include "timer0.h"
    #include "Uart.h"
    
    sbit SG_PWM = P1^1; // 舵机PWM信号输出
    
    unsigned char PWM_count = 0; // PWM占空比控制变量(映射舵机角度)
    
    void main()
    {
        // ... 设置定时器0、串口及中断等配置
        
        while(1)
        {
            // 可以在此处加入蓝牙状态检查及处理逻辑
        }
    }
    
    // 定时器0中断服务函数
    void Timer0() interrupt 1
    {
        TL0 = 0x33;
        TH0 = 0xFE;
    
        count++;
        if(count >= 40) count = 0; // 修正周期为20ms
    
        if(count < PWM_count)
        {
            SG_PWM=1;
        }
        else
        {
            SG_PWM=0;
        }
    }
    
    // 串口中断服务函数
    void UART_Routine() interrupt 4
    {
        if(RI == 1)
        {
            RI = 0; // 先清除接收中断标志位
            P1 = SBUF;
    
            switch(P1)
            {
                case 0x01:
                    PWM_count = 1;
                    break;
                case 0x02:
                    PWM_count = 2;
                    break;
                // ... 其他角度对应的PWM_count设置
            }
        }
    }
    

    注意:为了简化代码,这里使用了switch-case结构替代多个if语句,同时对count进行修正以确保周期正确。如果问题依然存在,请检查硬件连接及舵机工作电压。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月9日

悬赏问题

  • ¥100 对接美团闪购医药接口相关问题
  • ¥15 嵌入式软件电子烟开发
  • ¥15 职场 Excel 查重问题
  • ¥20 multisim方波发生电路产生的波形异常,学校没讲模电就留了实验qwq
  • ¥15 求怎么用idea2021.3.2创建web项目并配置tomcat
  • ¥100 or-tools的相关问题
  • ¥15 有可能用平板通过拓展坞来烧录程序吗(keil5的那种)
  • ¥15 状态图的并发态问题咨询
  • ¥15 PFC3D,plot
  • ¥15 VAE模型编程报错无法解决