极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2142|回复: 1

求教几个关于舵机的问题

[复制链接]
发表于 2014-3-23 13:55:36 | 显示全部楼层 |阅读模式
最近在使用别的组件,arduino在做了红外那个实验后搁一边好多天了 - -

有几个关于舵机的问题,求教:
1、针对模拟舵机设计的程序,如果换成数字舵机,程序不变,是不是一样的效果?
2、如果接口的输出电流不够大,如何能让舵机直接接电流,而主控仅仅输出信号?
3、下面是该主控针对模拟舵机的函数,求解
void SVA_Pos(char Channel,char Angle)
{
        if(Channel<9)        Channel = 9;
        if(Channel > 11) Channel = 11;
        Channel = Channel - 9;
        Servoa[Channel][SER_ENDDEGREE] = T06MS + (int)((float)Angle * T10US);
        Servoa[Channel][SER_SPEED] = 0;
        Servoa[Channel][SER_NODEGREE]=Servoa[Channel][SER_ENDDEGREE];
        Servoa[Channel][SER_ENABLE] = 1;
        if((Servoa[0][SER_ENABLE]==0)&&(Servoa[1][SER_ENABLE]==0)&&(Servoa[2][SER_ENABLE]==0))
                TIM_Cmd(TIM1, DISABLE);
}
4、下面是针对485(数字舵机?)的函数
对于设计位置速度的:int PO16_Move(int id ,int iSpeed,int iPos),我不明白id这个参数是做什么用的,好像可以随便设置一个
读寄存器写寄存器是啥意思?可以设置角度,或者得到当前的角度的值?

/*******************************************************************************
**
**                485舵机控制相关函数
**
********************************************************************************/
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int

#define uchar unsigned char
#define uint unsigned int
/*
**        485端口初始化,读寄存器,写寄存器,开环设置,闭环设置,设置位置速度
*/

int PO16_Init(int baud)
{
        USART_InitTypeDef USART_InitStructure3;
       
  //RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
       
  GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_10;                       
  GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);       
  
  GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_12 ;
  GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);       
   
        GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_11;                       
        GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);  
       
  USART_InitStructure3.USART_BaudRate                 = baud;
  USART_InitStructure3.USART_WordLength         = USART_WordLength_8b;
  USART_InitStructure3.USART_StopBits                 = USART_StopBits_1;
  USART_InitStructure3.USART_Parity                 = USART_Parity_No;
  USART_InitStructure3.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
  USART_InitStructure3.USART_Mode                 = USART_Mode_Rx | USART_Mode_Tx;
  
  /* Configure USART */
  USART_Init(USART3, &USART_InitStructure3);
  /* Enable the USART */
  USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
  USART_Cmd(USART3, ENABLE);       
  
  return 0;       
}
void ServoRs485_Send(u8 *ptr,u16 length)
{
        u16 i;
        //GPIOB->BSRR = GPIO_Pin_0;       
        GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET);
        //USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
        for(i=0;i<=length;i++)
        {
                while (!(USART3->SR & USART_FLAG_TXE));
                USART3->DR = *ptr;
                ptr ++;
                //while((USART3->SR & 0x40)==0);
        }
        //GPIOB->BRR = GPIO_Pin_0;
        while (!(USART3->SR & USART_FLAG_TXE));
        GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);        
}

/*
接收程序
返回负值为错误
正值为接收到的数据长度,单位字节
*/
#define RECV_TIMEOUT (14000)
int ServoRs485_Recv(u8 *ptr)
{
        int i = -1;
        u16  dt = RECV_TIMEOUT;

        while(dt)
        {
                if(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET)
                {
                        if(i<0) i = 1;
                        else i++;
                        *ptr = USART3->DR;
                        ptr ++;
                        USART_ClearFlag(USART3, USART_FLAG_RXNE);
                        dt = RECV_TIMEOUT;
                }
                else
                        dt --;
        }
        if(i<5) i = 0;
        return i;
}

int PO16_WriteRegister(int id,int Reg,int dat)
{
        int i;
        u8 Buffer[32];
       
        switch(Reg)
        {
                //        双字节寄存器
                case 0:
                case 6:
                case 8:               
                case 14:
                case 20:
                case 22:
                case 30:       
                case 32:
                case 34:
                case 36:
                case 38:
                case 40:       
                        Buffer[0] = 0xFF;
                        Buffer[1] = 0xFF;
                        Buffer[2] = id;
                        Buffer[3] = 0x05;
                        Buffer[4] = 0x03;
                        Buffer[5] = Reg;
                        Buffer[7] = (u8)((dat>>8) & 0x00ff);
                        Buffer[6] = (u8)(dat&0x00ff);
                        Buffer[8] = (u8)( Buffer[2] + Buffer[3] + Buffer[4]  + Buffer[5]  + Buffer[6]  + Buffer[7] );
                        Buffer[8] = ~Buffer[8];
                        ServoRs485_Send(Buffer,9);
                        if(ServoRs485_Recv(Buffer)>0)                       
                                i = 1;
                        else
                                i = 0;                                                                                                       
                        break;
                //        单字节寄存器
                case 3:
                case 4:
                case 5:
                case 10:
                case 11:               
                case 12:
                case 13:
                case 16:
                case 17:
                case 18:       
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:       
                case 29:
                case 42:
                case 43:
                case 44:
                case 46:       
                case 47:
                case 48:       
                        Buffer[0] = 0xFF;
                        Buffer[1] = 0xFF;
                        Buffer[2] = id;
                        Buffer[3] = 0x04;
                        Buffer[4] = 0x03;
                        Buffer[5] = Reg;
                        Buffer[6] = dat;
                        Buffer[7] = (u8)( Buffer[2] + Buffer[3] + Buffer[4]  + Buffer[5]  + Buffer[6]);
                        Buffer[7] =~Buffer[7];
                        ServoRs485_Send(Buffer,8);
                        if(ServoRs485_Recv(Buffer)>0)
                                i = 1;
                        else
                                i = 0;
                        break;
                default:
                        i = 0;
                        break;       
        }
        return i;
}

int PO16_ReadRegister(int id,int Reg)
{
        int i;
        u8 Buffer[32];
        switch(Reg)
        {
                //        双字节寄存器
                case 6:
                case 8:               
                case 14:
                case 20:
                case 22:
                case 30:       
                case 32:
                case 34:
                case 36:
                case 38:
                case 40:       
                        Buffer[0] = 0xFF;
                        Buffer[1] = 0xFF;
                        Buffer[2] = id;
                        Buffer[3] = 0x04;
                        Buffer[4] = 0x02;
                        Buffer[5] = Reg;
                        Buffer[6] = 0x02;
                        Buffer[7] = (u8)( Buffer[2] + Buffer[3] + Buffer[4]  + Buffer[5]  + Buffer[6]);
                        Buffer[7] = ~Buffer[7];
                        ServoRs485_Send(Buffer,8);
                        if(ServoRs485_Recv(Buffer)>0)
                        {
                                i = Buffer[6];
                                i <<= 8;
                                i += Buffer[5];
                        }
                        else
                                i = 2012;                                                                       
                                break;
                //        单字节寄存器
                case 3:
                case 4:
                case 5:
                case 10:
                case 11:               
                case 12:
                case 13:
                case 16:
                case 17:
                case 18:       
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:       
                case 29:
                case 42:
                case 43:
                case 44:
                case 46:       
                case 47:
                case 48:       
                        Buffer[0] = 0xFF;
                        Buffer[1] = 0xFF;
                        Buffer[2] = id;
                        Buffer[3] = 0x04;
                        Buffer[4] = 0x02;
                        Buffer[5] = Reg;
                        Buffer[6] = 0x01;
                        Buffer[7] = (u8)( Buffer[2] + Buffer[3] + Buffer[4]  + Buffer[5]  + Buffer[6]);
                        Buffer[7] = ~Buffer[7];
                        ServoRs485_Send(Buffer,8);
                        if(ServoRs485_Recv(Buffer)>0)
                        {
                                i = Buffer[5];
                        }
                        else
                                i = 2012;
                                break;
                default:
                        i = 2012;
                        break;       
        }
        return i;
}

int PO16_EndlessMode(int id)
{
        PO16_WriteRegister(id,6,0);
        PO16_WriteRegister(id,8,0);
        return 0;
}

int PO16_ServoMode(int id)
{
        PO16_WriteRegister(id,6,0);
        PO16_WriteRegister(id,8,1023);
        return 0;       
}

int PO16_Move(int id ,int iSpeed,int iPos)
{
        u8 sendBuff[32];
        int iLength = 0;
        u8 bChecksum = 0;

        int i;
       
        if(iPos>1023)
                iPos = 1023;
        if(iSpeed>1023)
                iSpeed = 1023;
               
        if(iPos<-1023)
                iPos = -1023;
        if(iSpeed<-1023)
                iSpeed = -1023;
                               
        //FF FF 03 07 03 1E FF 03 SS SS D4
        iLength = 11;
        sendBuff[0] = 0xFF;
        sendBuff[1] = 0xFF;

        if(id >= 0 && id <= 254)
        {
                sendBuff[2] = id;
        }

        sendBuff[3] = 0x07;
        sendBuff[4] = 0x03;
        sendBuff[5] = 0x1E;
       
        if(iPos >= 0)                                // pos
        {
                sendBuff[6] = iPos & 0xFF;
                sendBuff[7] = (iPos >> 8) & 0xFF;
        }
        else
        {
                sendBuff[6] = 0x00;
                sendBuff[7] = 0x00;
        }

        if(iSpeed >= 0)                                // speed
        {
                sendBuff[8] = iSpeed & 0xFF;
                sendBuff[9] = (iSpeed >> 8) & 0xFF;
        }
        else
        {
                sendBuff[8] = 0x00;
                sendBuff[9] = 0x00;
        }

        for(i = 2; i < iLength - 1; i++)
        {
                bChecksum += sendBuff[i];
        }

        bChecksum = ~bChecksum;
        bChecksum = bChecksum & 0xFF;
        sendBuff[iLength - 1] = bChecksum;
       
        ServoRs485_Send(sendBuff,iLength);
        if(ServoRs485_Recv(sendBuff)>0)
                return 1;
        else
                return 0;                       
}
回复

使用道具 举报

发表于 2020-10-13 20:43:47 | 显示全部楼层
Hi, sorry that I write English. Can you auto translate this, where can I find this sources, that you added? I met PO16_ReadRegister function in my code, but without source
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-12-3 09:28 , Processed in 0.047257 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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