本帖最后由 jinglixixi_457498010 于 2023-10-26 09:47 编辑

云台是一种控制动态调节摄像头观察视角的装置,其角度调节的驱动器件主要是步进电机或舵机。这里所所用的双轴云台是以2个舵机来控制其精度的转动,并以PWM脉冲的方式来控制舵机的转角。
image.png
1  双轴云台

为简化设计的复杂度,这里是通过一个串口控制型的双通道PWM模块来控制舵机。
image.png
2  PWM调节模块

这样由Mini-G0001开发板向PWM模块发送相应的指令即可控制云台的转向,而转动的方向和角度则是通过开发板上的4个按键来控制。

对于PWM调节模块,它工作时要求采用9600bps的波特率通讯,PWM的工作频率为 50Hz
为便于调节控制,其指令是存放在指令数组中,其格式为:
uint8_tMLF[7]={'S','1','F','0','5','0','T'};
uint8_t MLP[7]={'S','1','D','0','0','4','T'};

其中,数组MLF[]用于存放工作频率的设置指令,而数组MLP[]则用于存放转动角度的设置指令。


用于设置工作频率的函数为:
int sendf(void)
  • {
  •            uint8_t i;
  •            for(i=0;i<7;i++)
  •            {
  •                    USART_SendData(USART2, MLF[i]);
  •                    while (RESET == USART_GetFlagStatus(USART2, USART_FLAG_TC));
  •            }
  • }
  • 复制代码
    用于设置转动角度的函数为:
    int sendp(void)
  • {
  •            uint8_t i;        
  •            for(i=0;i<7;i++)
  •            {
  •                    USART_SendData(USART2, MLP[i]);
  •                    while (RESET == USART_GetFlagStatus(USART2, USART_FLAG_TC));
  •            }
  • }
  • 复制代码
    在角度调节过程中,由于是采用4个按键来控制,各按键的作用为:
    K1:向左
    K2:向右
    K3:向上
    K4:向下

    4个按键所用引脚的配置函数为:
    void key_gpio(void)
  • {
  •     GPIO_InitTypeDefGPIO_InitStruct;
  •     RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
  •     GPIO_StructInit(&GPIO_InitStruct);
  •     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9;
  •     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  •     GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_IPU;
  •     GPIO_Init(GPIOA, &GPIO_InitStruct);
  •     GPIO_StructInit(&GPIO_InitStruct);
  •     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_2;
  •     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  •     GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_IPD;
  •     GPIO_Init(GPIOA, &GPIO_InitStruct);
  • }
  • 复制代码
    进行云台调节控制的主程序为:
    int main(void)
  • {
  •     uint8_t i=3,j=3;
  •     PLATFORM_Init();
  •     DELAY(1000);
  •     USART_Configure(9600);
  •     key_gpio();
  •     MLF[1]='1';
  •     sendf();
  •     DELAY(1000);
  •     MLF[1]='2';
  •     sendf();
  •     while (1)
  •     {
  •                         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==1)   // "K1"
  •                         {
  •                                         if(i<12)  i=i+1;
  •                                         MLP[1]='1';
  •                                         MLP[4]=i/10+'0';
  •                                         MLP[5]=i%10+'0';
  •                                         sendp();
  •                                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==1);
  •                         }
  •                         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)==0)   // "K2"
  •                         {
  •                                         if(i>3)  i=i-1;
  •                                         MLP[1]='1';
  •                                         MLP[4]=i/10+'0';
  •                                         MLP[5]=i%10+'0';
  •                                         sendp();
  •                                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)==0);
  •                         }
  •                         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)   // "K3"
  •                         {
  •                                         if(j<12)  j=j+1;
  •                                         MLP[1]='2';
  •                                         MLP[4]=j/10+'0';
  •                                         MLP[5]=j%10+'0';
  •                                         sendp();
  •                                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0);
  •                         }
  •                         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)   // "K4"
  •                         {
  •                                         if(j>3)  j=j-1;
  •                                         MLP[1]='2';
  •                                         MLP[4]=j/10+'0';
  •                                          MLP[5]=j%10+'0';
  •                                         sendp();
  •                                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0);
  •                         }
  •                         DELAY(10000);
  •     }
  • }
  • 复制代码
    在串口模块的RXD引脚连接PA1的情况下,其测试效果如图3至图5所示。
    image.png
    3 设置工作频率

    image.png
    4 测试通道1

    image.png
    5 测试通道2

    在完成整体电路连接的情况下,其形式如图6所示。通过按键的调节,即每按下一次用户键,则舵机就转动一个调节角度,其调节效果如图7和图8所示。
    image.png
    6 连接形式

    image.png
    7

    image.png
    8


    视频演示:
    https://www.bilibili.com/video/BV1NN4y1y7oE/?vd_source=f302fc0cc3a0425328db53a3b92082ca