迟睁 2024-03-28 19:32 采纳率: 0%
浏览 10

舵机和电机的控制问题

#单片机同时控制舵机和电机

手机蓝牙可以与单片机实现通信
以下是程序,可以做到控制舵机左与复位,电机正反转
但无法控制舵机右转,删除电机代码后舵机恢复控制三个方向。
求解答

#include<reg52.h>
#include<intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar ;
uchar R_data;
unsigned char count;
unsigned char num;
sbit model1 =P0^0;
sbit model2 =P0^1;
sbit model3 =P0^2;
sbit model4 =P0^3;
sbit pwm =P1^7;
bit R_flag=0;
uchar num_model=0; 

void Uart_Init(void)
{
     TMOD = 0x21;   //定时器工作在定时器1的方式2
     PCON = 0x00;   //不倍频
     SCON = 0x50;    //串口工作在方式1,并且启动串行接收    
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;        //启动定时器1
     IE  = 0x82;
     TH0 = 0xfe;
     TL0 = 0x33;     //11.0592MZ晶振,0.5ms
     TR0 = 1;    
     ES  = 1;        //开串口中断
     EA  = 1;        //开总中断
     
}

void Uart_SendByte(uchar Byte)
{
    SBUF =    Byte;
    while(!TI)                   //如果发送完毕,硬件会置位TI
    {
        _nop_();    
    }    
}

void start()
{
    switch(num_model)//根据不同的按钮启动不同的模式
    {
        case 1://后退
        model1=1;
        model2=0;
        model3=1;
        model4=0;
        break;
        case 2://前进
        model1=0;
        model2=1;
        model3=0;
        model4=1;
        break;
        case 0://停止
        model1=0;
        model2=0;
        model3=0;
        model4=0;
        break;
    }    
}

void main()
{
    Uart_Init();//初始化
    while(1)
    {
        if(R_flag==1)//接收蓝牙信号
        {
            Uart_SendByte(R_data );
            R_flag=0;
        }
        start();    
    }        
}

void Uart_Int(void) interrupt 4
{
    EA = 0;
    if(RI == 1)   //当硬件接收到一个数据时,RI会置位
    {
        R_data= SBUF;
        if(R_data==0x01)//右转模式    
        {
            count=0;
            num=4;
        }
        if(R_data==0x02)//左转模式    
        {
            count=0;
               num=2;
        }
        if(R_data==0x03)//直行
        {
            count=0;
               num=3;
        }
        if(R_data==0x04)//前进
        {
            num_model=2;
        }
        if(R_data==0x05)//停止
        {
            num_model=0;
        }
        if(R_data==0x06)//后退
        {
            num_model=1;
        }  
        RI = 0;  
        R_flag=1; 
    }
    EA = 1;
}

void Time0_Int() interrupt 1 //定时器中断程序
{
       TH0  = 0xfe;        
       TL0  = 0x33;
       count++;
       switch(num)
       {
           case 1:
         pwm=1;
         break;
         case 2://左转    
         pwm=1;
         if(count==3)
         num=0;
         break;
         case 3://直行
         pwm=1;
         if(count==4)
         num=0;
         break;
         case 4://右转
         pwm=1;
         if(count==5)
         num=0;
         break;
         case 0://停止转动
         pwm=0;
         break;
      }
}          




  • 写回答

3条回答 默认 最新

  • 专家-皆知 2024-03-28 19:32
    关注

    引自免费微信小程序:皆我百晓生

    下面是解决舵机和电机控制问题的代码,其中主要逻辑为通过单片机编程对舵机和电机进行精确控制。这个程序包含以下几个部分:

    1. Uart_Init():初始化UART模块,包括定时器、寄存器和串口的配置。设置波特率为9600bps并启动串口接收。
    void Uart_Init(void)
    {
        TMOD = 0x21;   //定时器工作在定时器1的方式2
        PCON = 0x00;   //不倍频
        SCON = 0x50;    //串口工作在方式1,并且启动串行接收    
        TH1 = 0xFd;    //设置波特率 9600
        TL1 = 0xFd;
        TR1 = 1;        //启动定时器1
        IE  = 0x82;     //启动定时器1
        TH0 = 0xfe;
        TL0 = 0x33;     //11.0592MZ晶振,0.5ms
        TR0 = 1;    
        ES  = 1;        //开串口中断
        EA  = 1;        //开总中断
       
        // Initialize UART peripheral.
        UART_Init();
    }
    
    1. Uart_SendByte():发送一个指定的字节到UART模块。
    void Uart_SendByte(uchar Byte)
    {
        SBUF = (uint)(Byte);  // Convert byte to Word using SWAP to set word low and high bits as desired
        
        while (!TI) {   // If transmission is successful, hardware will clear TI
            _nop_();
        }
        
        SBUF = (uint)((~SBUF) & 0xFF);  // Set word high and low bits back to original values after transmission
    }
    
    1. start():根据模型值(即控制舵机左/右转)调用对应的Mode2(数字模式2),该模式下舵机的动作是两个转向互斥的,只有当右转模式被按下时才开始执行左边转向,左转模式被按下时才开始执行右边转向。启动外部的电机驱动器。
    void start()
    {
        switch(num_model)
        {
            case 1: // 后退
            model1 = 1;
            model2 = 0;
            model3 = 1;
            model4 = 0;
            break;
            case 2: // 前进
            model1 = 0;
            model2 = 1;
            model3 = 0;
            model4 = 1;
            break;
            case 0: // 停止
            model1 = 0;
            model2 = 0;
            model3 = 0;
            model4 = 0;
            break;
        }
    
        // Initialize Mode2 for forward and backward movements
        mode2 = P0^model1 | P0^model2 | P0^model3 | P0^model4;
    
        // Enable interrupts for the timer and uart module
        TR1 = 1;     
        EA = 1; 
    
        // Start the motor control
        MotorStart(mode2);
    
        // Start the timer
        Timer0_ScheduleIdleCallback(&Time0_Int);
        Timer0_Start();
    
        // Start UART module
        UART_Init();
    }
    
    1. MotorStart():初始化电机驱动器,将模式设置为前方的转速模式(forward speed mode)。
    void MotorStart(unsigned char mode)
    {
        bit mask = 0x1 << (mode - 1);  // Mask the right shift register to select the desired direction (forward or backward)
    
        PWMReg = mode;                // Set the PWM duty cycle register to the desired speed value
    
        // Wait for 1 ms before initiating the motor drive
        while (!(PWMReg & PWM脑子))  { // Clear PWM duty cycle register to prevent any delay in the motor drive
            _nop_();
        }
    
        PWMReg &= ~mask;                 // Clear the right shift register to enable operation in forward direction
    }
    
    1. Main():进入主循环,持续接收蓝牙信号并处理和发送事件。在此函数中:
    • 如果蓝牙接收到信号,则发送一个接收码(R_data),用于检测设备是否连接成功。
    • 当R_flag为1时,开始监听定时器和UART模块的状态。
    • 使用start()函数调用对应的Mode2模式,并根据模型值设置舵机左右转所需的模型值。根据模型值的不同,右转模式对应于模为0和1,左转模式对应于模为1和2。
    • 开启外部电机驱动器,将电机的模式设置为前方的速度模式。
    • 将定时器设置为定时运行,并开启定时器1的中断服务(Timer0_Int)。
    • 调用Uart_Init()函数初始化相应的UART接口。
    • 根据R_flag状态更新和调用相应控制器(Mode2, Time0_Int)来切换舵机的控制模式。

    注意,这段代码中的WIP标记表示此代码仍在开发阶段,可能存在的问题和改进之处需要在实际项目中进一步完善和优化。此外,由于码制转换、底层操作符、字符集选择等问题可能会有所不同,具体实现细节需要结合实际情况进行调整。如果你需要帮助绘制模拟图,可以提供舵机和电机的草图或者部分电路原理图,我可以帮助绘制。另外,这只是一个基础示例,实际应用中可能还需要考虑更多的功能,例如数据读取、故障检查、延时等。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月28日

悬赏问题

  • ¥15 Fatal error in Process MEMORY
  • ¥15 labelme生成的json有乱码?
  • ¥30 arduino vector defined in discarded section `.text' of wiring.c.o (symbol from plugin)
  • ¥20 如何训练大模型在复杂因素组成的系统中求得最优解
  • ¥15 关于#r语言#的问题:在进行倾向性评分匹配时,使用“match it"包提示”错误于eval(family$initialize): y值必需满足0 <= y <= 1“请问在进行PSM时
  • ¥45 求17位带符号原码乘法器verilog代码
  • ¥20 PySide6扩展QLable实现Word一样的图片裁剪框
  • ¥15 怎样才能让IDEA不爆红
  • ¥15 matlab数据降噪处理,提高数据的可信度,确保峰值信号的不损失?
  • ¥15 怎么看我在bios每次修改的日志