学习目标

  1. 实现舵机控制
  2. 实现板级舵机驱动

    学习内容

    原理图

    071.png
    8路PWM来控制舵机转动,需要用到timer1和timer2。

    驱动封装

    ```c

    ifndef _BSP_DOG_STEERING_H

    define _BSP_DOG_STEERING_H

include “gd32f4xx.h”

include “systick.h”

//PWM周期:1ms PWM频率:1000hz //预分频:10 1s: 240 000 000 pwm周期计数: 240 000 000/10000=24000

define TIMER_PRESCALER (240 - 1)

//pwm周期计数

define TIMER_PERIOD (20000 - 1)

//PWM0

define PWM0_RCU RCU_GPIOA

define PWM0_PORT GPIOA

define PWM0_PIN GPIO_PIN_3

define PWM0_AF GPIO_AF_1

define PWM0_CH TIMER_CH_3

//PWM1

define PWM1_RCU RCU_GPIOA

define PWM1_PORT GPIOA

define PWM1_PIN GPIO_PIN_2

define PWM1_AF GPIO_AF_1

define PWM1_CH TIMER_CH_2

//PWM2

define PWM2_RCU RCU_GPIOA

define PWM2_PORT GPIOA

define PWM2_PIN GPIO_PIN_0

define PWM2_AF GPIO_AF_1

define PWM2_CH TIMER_CH_0

//PWM3

define PWM3_RCU RCU_GPIOA

define PWM3_PORT GPIOA

define PWM3_PIN GPIO_PIN_1

define PWM3_AF GPIO_AF_1

define PWM3_CH TIMER_CH_1

//PWM4

define PWM4_RCU RCU_GPIOB

define PWM4_PORT GPIOB

define PWM4_PIN GPIO_PIN_4

define PWM4_AF GPIO_AF_2

define PWM4_CH TIMER_CH_0

//PWM5

define PWM5_RCU RCU_GPIOB

define PWM5_PORT GPIOB

define PWM5_PIN GPIO_PIN_5

define PWM5_AF GPIO_AF_2

define PWM5_CH TIMER_CH_1

//PWM6

define PWM6_RCU RCU_GPIOB

define PWM6_PORT GPIOB

define PWM6_PIN GPIO_PIN_0

define PWM6_AF GPIO_AF_2

define PWM6_CH TIMER_CH_2

//PWM7

define PWM7_RCU RCU_GPIOB

define PWM7_PORT GPIOB

define PWM7_PIN GPIO_PIN_1

define PWM7_AF GPIO_AF_2

define PWM7_CH TIMER_CH_3

//舵机的角度偏差

define a1 5

define a2 0

define a3 5

define a4 0

define a5 5

define a6 0

define a7 5

define a8 5

void bsp_dog_config(void); //控制每个舵机转动角度 void bsp_pwm0_angle(float angle); void bsp_pwm1_angle(float angle); void bsp_pwm2_angle(float angle); void bsp_pwm3_angle(float angle); void bsp_pwm4_angle(float angle); void bsp_pwm5_angle(float angle); void bsp_pwm6_angle(float angle); void bsp_pwm7_angle(float angle); //给定8个舵机角度 void bsp_dog_angles(double steering_angles[8]); //狗安装角度 void dog_install_angle(void);

endif

  1. ```c
  2. #include "bsp_dog_steering.h"
  3. static void timer1_config(void){
  4. /*************** GPIO config **************/
  5. //PA3
  6. rcu_periph_clock_enable(PWM0_RCU);
  7. gpio_mode_set(PWM0_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM0_PIN);
  8. gpio_output_options_set(PWM0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM0_PIN);
  9. gpio_af_set(PWM0_PORT, PWM0_AF, PWM0_PIN);
  10. //PA2
  11. rcu_periph_clock_enable(PWM1_RCU);
  12. gpio_mode_set(PWM1_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM1_PIN);
  13. gpio_output_options_set(PWM1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM1_PIN);
  14. gpio_af_set(PWM1_PORT, PWM1_AF, PWM1_PIN);
  15. //PA0
  16. rcu_periph_clock_enable(PWM2_RCU);
  17. gpio_mode_set(PWM2_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM2_PIN);
  18. gpio_output_options_set(PWM2_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM2_PIN);
  19. gpio_af_set(PWM2_PORT, PWM2_AF, PWM2_PIN);
  20. //PA1
  21. rcu_periph_clock_enable(PWM3_RCU);
  22. gpio_mode_set(PWM3_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM3_PIN);
  23. gpio_output_options_set(PWM3_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM3_PIN);
  24. gpio_af_set(PWM3_PORT, PWM3_AF, PWM3_PIN);
  25. /*************** Timer config *************/
  26. // 时钟配置
  27. rcu_periph_clock_enable(RCU_TIMER1);
  28. // 复位定时器
  29. timer_deinit(TIMER1);
  30. // 倍频配置
  31. rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
  32. // 初始化定时器
  33. timer_parameter_struct tps;
  34. timer_struct_para_init(&tps);
  35. tps.prescaler = TIMER_PRESCALER; // 分频计数 240 000 000 预分频:10000 1s:24000
  36. tps.period = TIMER_PERIOD; // 周期计数 1s
  37. //定时器初始化
  38. timer_init(TIMER1, &tps);
  39. // pwm0
  40. timer_oc_parameter_struct tops;
  41. timer_channel_output_struct_para_init(&tops);
  42. //输出OP的PWM
  43. tops.outputstate = TIMER_CCX_ENABLE;
  44. timer_channel_output_config(TIMER1, PWM0_CH, &tops);
  45. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  46. timer_channel_output_mode_config(TIMER1, PWM0_CH, TIMER_OC_MODE_PWM0);
  47. // pwm1
  48. timer_channel_output_struct_para_init(&tops);
  49. //输出OP的PWM
  50. tops.outputstate = TIMER_CCX_ENABLE;
  51. timer_channel_output_config(TIMER1, PWM1_CH, &tops);
  52. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  53. timer_channel_output_mode_config(TIMER1, PWM1_CH, TIMER_OC_MODE_PWM0);
  54. // pwm2
  55. timer_channel_output_struct_para_init(&tops);
  56. //输出OP的PWM
  57. tops.outputstate = TIMER_CCX_ENABLE;
  58. timer_channel_output_config(TIMER1, PWM2_CH, &tops);
  59. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  60. timer_channel_output_mode_config(TIMER1, PWM2_CH, TIMER_OC_MODE_PWM0);
  61. // pwm3
  62. timer_channel_output_struct_para_init(&tops);
  63. //输出OP的PWM
  64. tops.outputstate = TIMER_CCX_ENABLE;
  65. timer_channel_output_config(TIMER1, PWM3_CH, &tops);
  66. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  67. timer_channel_output_mode_config(TIMER1, PWM3_CH, TIMER_OC_MODE_PWM0);
  68. // 初始化
  69. timer_enable(TIMER1);
  70. }
  71. static void timer2_config(void){
  72. /*************** GPIO config **************/
  73. //PB4
  74. rcu_periph_clock_enable(PWM4_RCU);
  75. gpio_mode_set(PWM4_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM4_PIN);
  76. gpio_output_options_set(PWM4_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM4_PIN);
  77. gpio_af_set(PWM4_PORT, PWM4_AF, PWM4_PIN);
  78. //PB5
  79. rcu_periph_clock_enable(PWM5_RCU);
  80. gpio_mode_set(PWM5_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM5_PIN);
  81. gpio_output_options_set(PWM5_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM5_PIN);
  82. gpio_af_set(PWM5_PORT, PWM5_AF, PWM5_PIN);
  83. //PB0
  84. rcu_periph_clock_enable(PWM6_RCU);
  85. gpio_mode_set(PWM6_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM6_PIN);
  86. gpio_output_options_set(PWM6_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM6_PIN);
  87. gpio_af_set(PWM6_PORT, PWM6_AF, PWM6_PIN);
  88. //PB1
  89. rcu_periph_clock_enable(PWM7_RCU);
  90. gpio_mode_set(PWM7_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM7_PIN);
  91. gpio_output_options_set(PWM7_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, PWM7_PIN);
  92. gpio_af_set(PWM7_PORT, PWM7_AF, PWM7_PIN);
  93. /*************** Timer config *************/
  94. // 时钟配置
  95. rcu_periph_clock_enable(RCU_TIMER2);
  96. // 复位定时器
  97. timer_deinit(TIMER2);
  98. // 倍频配置
  99. rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
  100. // 初始化定时器
  101. timer_parameter_struct tps;
  102. timer_struct_para_init(&tps);
  103. tps.prescaler = TIMER_PRESCALER; // 分频计数 240 000 000 预分频:10000 1s:24000
  104. tps.period = TIMER_PERIOD; // 周期计数 1s
  105. //定时器初始化
  106. timer_init(TIMER2, &tps);
  107. // pwm4
  108. timer_oc_parameter_struct tops;
  109. timer_channel_output_struct_para_init(&tops);
  110. //输出OP的PWM
  111. tops.outputstate = TIMER_CCX_ENABLE;
  112. timer_channel_output_config(TIMER2, PWM4_CH, &tops);
  113. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  114. timer_channel_output_mode_config(TIMER2, PWM4_CH, TIMER_OC_MODE_PWM0);
  115. // pwm5
  116. timer_channel_output_struct_para_init(&tops);
  117. //输出OP的PWM
  118. tops.outputstate = TIMER_CCX_ENABLE;
  119. timer_channel_output_config(TIMER2, PWM5_CH, &tops);
  120. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  121. timer_channel_output_mode_config(TIMER2, PWM5_CH, TIMER_OC_MODE_PWM0);
  122. // pwm6
  123. timer_channel_output_struct_para_init(&tops);
  124. //输出OP的PWM
  125. tops.outputstate = TIMER_CCX_ENABLE;
  126. timer_channel_output_config(TIMER2, PWM6_CH, &tops);
  127. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  128. timer_channel_output_mode_config(TIMER2, PWM6_CH, TIMER_OC_MODE_PWM0);
  129. // pwm7
  130. timer_channel_output_struct_para_init(&tops);
  131. //输出OP的PWM
  132. tops.outputstate = TIMER_CCX_ENABLE;
  133. timer_channel_output_config(TIMER2, PWM7_CH, &tops);
  134. // 输出模式配置 TIMER_OC_MODE_PWM0有效点平是高电平
  135. timer_channel_output_mode_config(TIMER2, PWM7_CH, TIMER_OC_MODE_PWM0);
  136. // 初始化
  137. timer_enable(TIMER2);
  138. }
  139. void bsp_dog_config(void){
  140. timer1_config();
  141. timer2_config();
  142. }
  143. static void pwm0_update(float duty) {//0-100
  144. //10
  145. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  146. // 配置输出的占空比 占空比 计数值
  147. timer_channel_output_pulse_value_config(TIMER1, PWM0_CH, pulse);
  148. }
  149. static void pwm1_update(float duty) {//0-100
  150. //10
  151. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  152. // 配置输出的占空比 占空比 计数值
  153. timer_channel_output_pulse_value_config(TIMER1, PWM1_CH, pulse);
  154. }
  155. static void pwm2_update(float duty) {//0-100
  156. //10
  157. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  158. // 配置输出的占空比 占空比 计数值
  159. timer_channel_output_pulse_value_config(TIMER1, PWM2_CH, pulse);
  160. }
  161. static void pwm3_update(float duty) {//0-100
  162. //10
  163. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  164. // 配置输出的占空比 占空比 计数值
  165. timer_channel_output_pulse_value_config(TIMER1, PWM3_CH, pulse);
  166. }
  167. static void pwm4_update(float duty) {//0-100
  168. //10
  169. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  170. // 配置输出的占空比 占空比 计数值
  171. timer_channel_output_pulse_value_config(TIMER2, PWM4_CH, pulse);
  172. }
  173. static void pwm5_update(float duty) {//0-100
  174. //10
  175. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  176. // 配置输出的占空比 占空比 计数值
  177. timer_channel_output_pulse_value_config(TIMER2, PWM5_CH, pulse);
  178. }
  179. static void pwm6_update(float duty) {//0-100
  180. //10
  181. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  182. // 配置输出的占空比 占空比 计数值
  183. timer_channel_output_pulse_value_config(TIMER2, PWM6_CH, pulse);
  184. }
  185. static void pwm7_update(float duty) {//0-100
  186. //10
  187. uint32_t pulse = (uint32_t)(duty*TIMER_PERIOD/100);
  188. // 配置输出的占空比 占空比 计数值
  189. timer_channel_output_pulse_value_config(TIMER2, PWM7_CH, pulse);
  190. }
  191. void bsp_pwm0_angle(float angle){
  192. pwm0_update(2.5+(angle+a1)*10.0/180.0);
  193. }
  194. void bsp_pwm1_angle(float angle){
  195. pwm1_update(2.5+(angle+a2)*10.0/180.0);
  196. }
  197. void bsp_pwm2_angle(float angle){
  198. pwm2_update(2.5+(angle+a3)*10.0/180.0);
  199. }
  200. void bsp_pwm3_angle(float angle){
  201. pwm3_update(2.5+(angle+a4)*10.0/180.0);
  202. }
  203. void bsp_pwm4_angle(float angle){
  204. pwm4_update(2.5+(angle+a5)*10.0/180.0);
  205. }
  206. void bsp_pwm5_angle(float angle){
  207. pwm5_update(2.5+(angle+a6)*10.0/180.0);
  208. }
  209. void bsp_pwm6_angle(float angle){
  210. pwm6_update(2.5+(angle+a7)*10.0/180.0);
  211. }
  212. void bsp_pwm7_angle(float angle){
  213. pwm7_update(2.5+(angle+a8)*10.0/180.0);
  214. }
  215. //给定8个舵机角度
  216. void bsp_dog_angles(double steering_angles[8]){
  217. bsp_pwm0_angle(steering_angles[0]);
  218. bsp_pwm1_angle(steering_angles[1]);
  219. bsp_pwm2_angle(steering_angles[2]);
  220. bsp_pwm3_angle(steering_angles[3]);
  221. bsp_pwm4_angle(steering_angles[4]);
  222. bsp_pwm5_angle(steering_angles[5]);
  223. bsp_pwm6_angle(steering_angles[6]);
  224. bsp_pwm7_angle(steering_angles[7]);
  225. }
  226. //狗的安装角度
  227. void dog_install_angle(void){
  228. bsp_pwm0_angle(90);
  229. bsp_pwm1_angle(0);
  230. bsp_pwm2_angle(90);
  231. bsp_pwm3_angle(0);
  232. bsp_pwm4_angle(0);
  233. bsp_pwm5_angle(90);
  234. bsp_pwm6_angle(0);
  235. bsp_pwm7_angle(90);
  236. }