当前位置:   article > 正文

四足机器人——舵机控制_stm32四足机器人陀机是怎样运行的

stm32四足机器人陀机是怎样运行的

目录

1、51定时器控制单个舵机

2、51定时器控制多路舵机

3、stm32控制舵机

4、pca9685驱动模块


1、51定时器控制单个舵机

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分,总间隔为2ms,比如说180度伺服角度,对应的关系如下。

PWM信号控制舵机的原理

  1. void main(void)
  2. {
  3. InitTimer0(); //定时器0初始化
  4. EA = 1; //开总中断
  5. while(1) //大循环
  6. {
  7. Servo0PwmDuty = 500; //脉冲宽度在500微秒,对应-90°
  8. DelayMs(1000); //延时1
  9. Servo0PwmDuty = 1000; //脉冲宽度在1000微秒,对应-45°
  10. DelayMs(1000);
  11. Servo0PwmDuty = 1500;
  12. DelayMs(1000);
  13. Servo0PwmDuty = 2000;
  14. DelayMs(1000);
  15. Servo0PwmDuty = 2500;
  16. DelayMs(1000);
  17. }
  18. }

2、51定时器控制多路舵机

  1. void main(void)
  2. {
  3. uint8 i;
  4. InitTimer0(); //定时器0初始化
  5. EA = 1; //开总中断
  6. while(1) //大循环
  7. {
  8. for(i = 0;i<8;i++)
  9. ServoPwmDuty[i] = 500; //脉冲宽度在500微秒,对应-90°
  10. DelayMs(1000); //延时1
  11. for(i = 0;i<8;i++)
  12. ServoPwmDuty[i] = 1000; //脉冲宽度在1000微秒,对应-45°
  13. DelayMs(1000);
  14. for(i = 0;i<8;i++)
  15. ServoPwmDuty[i] = 1500; //脉冲宽度在1500微秒,对应0°
  16. DelayMs(1000); //延时1
  17. for(i = 0;i<8;i++)
  18. ServoPwmDuty[i] = 2000; //脉冲宽度在2000微秒,对应45°
  19. DelayMs(1000);
  20. for(i = 0;i<8;i++)
  21. ServoPwmDuty[i] = 2500; //脉冲宽度在2500微秒,对应90°
  22. DelayMs(1000); //延时1
  23. }
  24. }

3、stm32控制舵机

PWM就是脉冲宽度调制,也就是占空比可变的脉冲波形.

pwm的占空比,就是指高电平保持的时间,与该pwm时钟周期时间之比。

在应用中就是通过调节pwm占空比来控制,也就是一个周期中高电平所占的百分比来控制舵机的转角的。

在代码中要特别注意的是时基结构体的TIM_Period(自动重装载寄存器值,简称arr)和TIM_Prescaler(预分频寄存器值,简称psc),因为这两个决定了输出PWM信号的周期。具体的周期计算公式为:周期=(arr+1)*(psc+1)/CLK。其中CLK为计数器的时钟频率,我的是72MHZ,也就是72000000。最后计算结果单位为秒,结果为0.02s,也就是20ms。这样的配置就是为了让输出的PWM信号达到前面说到的舵机要求的20ms周期。

  1. int main(void)
  2. {
  3. int delay_time;
  4. delay_init(); //延时函数初始化
  5. TIM_Init(); //定时器初始化
  6. while(1)
  7. {
  8. delay_ms(1000);
  9. TIM_SetCompare1(TIM1, 175); //对应180
  10. delay_ms(1000);
  11. TIM_SetCompare1(TIM1, 180); //对应135
  12. delay_ms(1000);
  13. TIM_SetCompare1(TIM1, 185); //对应90
  14. delay_ms(1000);
  15. TIM_SetCompare1(TIM1, 190); //对应45
  16. delay_ms(1000);
  17. TIM_SetCompare1(TIM1, 195); //对应0
  18. }
  19. }

4、pca9685驱动模块

stm32驱动程序:

  1. #include "pca9685.h"
  2. #include "myiic.h"
  3. #include "delay.h"
  4. #include "math.h"
  5. void pca_write(u8 adrr,u8 data)
  6. {
  7. IIC_Start();
  8. IIC_Send_Byte(pca_adrr);
  9. IIC_Wait_Ack();
  10. IIC_Send_Byte(adrr);
  11. IIC_Wait_Ack();
  12. IIC_Send_Byte(data);
  13. IIC_Wait_Ack();
  14. IIC_Stop();
  15. }
  16. u8 pca_read(u8 adrr)
  17. {
  18. u8 data;
  19. IIC_Start();
  20. IIC_Send_Byte(pca_adrr);
  21. IIC_Wait_Ack();
  22. IIC_Send_Byte(adrr);
  23. IIC_Wait_Ack();
  24. IIC_Start();
  25. IIC_Send_Byte(pca_adrr|0x01);
  26. IIC_Wait_Ack();
  27. data=IIC_Read_Byte(0);
  28. IIC_Stop();
  29. return data;
  30. }
  31. void pca_setfreq(float freq)
  32. {
  33. u8 prescale,oldmode,newmode;
  34. double prescaleval;
  35. freq *= 0.92;
  36. prescaleval = 25000000;
  37. prescaleval /= 4096;
  38. prescaleval /= freq;
  39. prescaleval -= 1;
  40. prescale =floor(prescaleval + 0.5f);
  41. oldmode = pca_read(pca_mode1);
  42. newmode = (oldmode&0x7F) | 0x10; // sleep
  43. pca_write(pca_mode1, newmode); // go to sleep
  44. pca_write(pca_pre, prescale); // set the prescaler
  45. pca_write(pca_mode1, oldmode);
  46. delay_ms(2);
  47. pca_write(pca_mode1, oldmode | 0xa1);
  48. }
  49. void pca_setpwm(u8 num, u32 on, u32 off)
  50. {
  51. pca_write(LED0_ON_L+4*num,on);
  52. pca_write(LED0_ON_H+4*num,on>>8);
  53. pca_write(LED0_OFF_L+4*num,off);
  54. pca_write(LED0_OFF_H+4*num,off>>8);
  55. }
  56. void Servo_Init(float hz,u8 angle)
  57. {
  58. u32 off=0;
  59. IIC_Init();
  60. pca_write(pca_mode1,0x0);
  61. pca_setfreq(hz);
  62. off=(u32)(145+angle*2.4);
  63. pca_setpwm(0,0,off);
  64. pca_setpwm(1,0,off);
  65. pca_setpwm(2,0,off);
  66. pca_setpwm(3,0,off);
  67. pca_setpwm(4,0,off);
  68. pca_setpwm(5,0,off);
  69. pca_setpwm(6,0,off);
  70. pca_setpwm(7,0,off);
  71. pca_setpwm(8,0,off);
  72. pca_setpwm(9,0,off);
  73. pca_setpwm(10,0,off);
  74. pca_setpwm(11,0,off);
  75. pca_setpwm(12,0,off);
  76. pca_setpwm(13,0,off);
  77. pca_setpwm(14,0,off);
  78. pca_setpwm(15,0,off);
  79. delay_ms(500);
  80. }
  81. void Servo_angle(u8 num,u8 angle)
  82. {
  83. u32 off = 0;
  84. off = (u32)(158+angle*2.2);
  85. pca_setpwm(num,0,off);
  86. }

stm32主函数:

  1. int main(void)
  2. {
  3. delay_init();//延时函数初始化
  4. Servo_Init(50,90);//初始化舵机驱动
  5. delay_ms(1000);
  6. uart_init(9600);
  7. Servo_angle(0,90);
  8. printf("this is a drill");
  9. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/414820
推荐阅读
相关标签
  

闽ICP备14008679号