当前位置:   article > 正文

stm32c8t6 pca9685 16路舵机(固件库)_pac9685

pac9685

概述

        项目需要使用多路舵机,为了体型得选择stm32c8t6,同时需要用八个舵机sg90,很麻烦,于是找到了pac9685的拓展驱动板,买回来之后发现了问题,商家给的都是51的代码,网上搜到的都是32其他型号的,或者是c8t6 HAL库的,在网上不是用不了就是要钱,最终找到一个古老的博客。

GitHub - github150620/stm32-pca9685-sg90

这个是接线图,其中建议v+连5v,不然舵机可能动不了,下面给出代码

代码

main.c

  1. #include "sg90.h"
  2. void delay(int i) {
  3. while (i) {
  4. i--;
  5. }
  6. }
  7. int main(void) {
  8. SG90_Init();
  9. while(1){
  10. SG90_SetAngle(0, 0);
  11. delay(80000000);
  12. SG90_SetAngle(0, 90);
  13. delay(80000000);
  14. SG90_SetAngle(0, 180);
  15. delay(80000000);
  16. }
  17. }

里面SG90_SetAngle(id,angle)

id就是连接的号0~15,看原理图,angle是要旋转的角度

pac9685.c

  1. #include "stm32f10x.h"
  2. #define PCA9685_I2C_ADDR 0x40
  3. #define MODE1 0x00
  4. #define MODE2 0x01
  5. #define SUBADR1 0x02
  6. #define SUBADR2 0x03
  7. #define SUBADR3 0x04
  8. #define ALLCALLADR 0x05
  9. #define LED0_ON_L 0x06
  10. #define LED0_ON_H 0x07
  11. #define LED0_OFF_L 0x08
  12. #define LED0_OFF_H 0x09
  13. #define LED1_ON_L 0x0A
  14. #define LED1_ON_H 0x0B
  15. #define LED1_OFF_L 0x0C
  16. #define LED1_OFF_H 0x0D
  17. #define LED2_ON_L 0x0E
  18. #define LED2_ON_H 0x0F
  19. #define LED2_OFF_L 0x10
  20. #define LED2_OFF_H 0x11
  21. #define LED3_ON_L 0x12
  22. #define LED3_ON_H 0x13
  23. #define LED3_OFF_L 0x14
  24. #define LED3_OFF_H 0x15
  25. #define LED4_ON_L 0x16
  26. #define LED4_ON_H 0x17
  27. #define LED4_OFF_L 0x18
  28. #define LED4_OFF_H 0x19
  29. #define LED5_ON_L 0x1A
  30. #define LED5_ON_H 0x1B
  31. #define LED5_OFF_L 0x1C
  32. #define LED5_OFF_H 0x1D
  33. #define LED6_ON_L 0x1E
  34. #define LED6_ON_H 0x1F
  35. #define LED6_OFF_L 0x20
  36. #define LED6_OFF_H 0x21
  37. #define LED7_ON_L 0x22
  38. #define LED7_ON_H 0x23
  39. #define LED7_OFF_L 0x24
  40. #define LED7_OFF_H 0x25
  41. #define LED8_ON_L 0x26
  42. #define LED8_ON_H 0x27
  43. #define LED8_OFF_L 0x28
  44. #define LED8_OFF_H 0x29
  45. #define LED9_ON_L 0x2A
  46. #define LED9_ON_H 0x2B
  47. #define LED9_OFF_L 0x2C
  48. #define LED9_OFF_H 0x2D
  49. #define LED10_ON_L 0x2E
  50. #define LED10_ON_H 0x2F
  51. #define LED10_OFF_L 0x30
  52. #define LED10_OFF_H 0x31
  53. #define LED11_ON_L 0x32
  54. #define LED11_ON_H 0x33
  55. #define LED11_OFF_L 0x34
  56. #define LED11_OFF_H 0x35
  57. #define LED12_ON_L 0x36
  58. #define LED12_ON_H 0x37
  59. #define LED12_OFF_L 0x38
  60. #define LED12_OFF_H 0x39
  61. #define LED13_ON_L 0x3A
  62. #define LED13_ON_H 0x3B
  63. #define LED13_OFF_L 0x3C
  64. #define LED13_OFF_H 0x3D
  65. #define LED14_ON_L 0x3E
  66. #define LED14_ON_H 0x3F
  67. #define LED14_OFF_L 0x40
  68. #define LED14_OFF_H 0x41
  69. #define LED15_ON_L 0x42
  70. #define LED15_ON_H 0x43
  71. #define LED15_OFF_L 0x44
  72. #define LED15_OFF_H 0x45
  73. #define PRE_SCALE 0xFE
  74. #define MODE1_RESTART 0x80
  75. #define MODE1_EXTCLK 0x40
  76. #define MODE1_AI 0x20
  77. #define MODE1_SLEEP 0x10
  78. #define MODE1_ALLCALL 0x01
  79. static void delay(int i) {
  80. while (i) {
  81. i--;
  82. }
  83. }
  84. void I2C2_Init() {
  85. GPIO_InitTypeDef GPIO_InitStructure;
  86. I2C_InitTypeDef I2C_initStructure;
  87. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  88. RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
  89. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  90. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  91. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  92. GPIO_Init(GPIOB, &GPIO_InitStructure);
  93. GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);
  94. I2C_initStructure.I2C_ClockSpeed = 400000; // 400KHz
  95. I2C_initStructure.I2C_Mode = I2C_Mode_I2C;
  96. I2C_initStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  97. I2C_initStructure.I2C_OwnAddress1 = 0x77;
  98. I2C_initStructure.I2C_Ack = I2C_Ack_Enable;
  99. I2C_initStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  100. I2C_Init(I2C2, &I2C_initStructure);
  101. I2C_Cmd(I2C2, ENABLE);
  102. }
  103. void PCA9685_WriteReg(u8 addr, u8 value) {
  104. I2C_AcknowledgeConfig(I2C2, ENABLE);
  105. I2C_GenerateSTART(I2C2, ENABLE);
  106. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
  107. I2C_Send7bitAddress(I2C2, (PCA9685_I2C_ADDR<<1)&0xfe, I2C_Direction_Transmitter);
  108. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  109. I2C_SendData(I2C2, addr);
  110. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  111. I2C_SendData(I2C2, value);
  112. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  113. I2C_GenerateSTOP(I2C2, ENABLE);
  114. }
  115. void PCA9685_ReadReg(u8 addr, u8 *value) {
  116. I2C_AcknowledgeConfig(I2C2, ENABLE);
  117. I2C_GenerateSTART(I2C2, ENABLE);
  118. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
  119. I2C_Send7bitAddress(I2C2, (PCA9685_I2C_ADDR<<1)&0xfe, I2C_Direction_Transmitter);
  120. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  121. I2C_SendData(I2C2, addr);
  122. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  123. I2C_GenerateSTOP(I2C2, ENABLE);
  124. I2C_GenerateSTART(I2C2, ENABLE);
  125. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
  126. I2C_Send7bitAddress(I2C2, (PCA9685_I2C_ADDR<<1)|0x01, I2C_Direction_Receiver);
  127. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  128. I2C_AcknowledgeConfig(I2C2, DISABLE);
  129. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED));
  130. *value = I2C_ReceiveData(I2C2);
  131. I2C_GenerateSTOP(I2C2, ENABLE);
  132. }
  133. void PCA9685_SetChannelDuty(u8 channel, u32 on, u32 off) {
  134. I2C_AcknowledgeConfig(I2C2, ENABLE);
  135. I2C_GenerateSTART(I2C2, ENABLE);
  136. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
  137. I2C_Send7bitAddress(I2C2, (PCA9685_I2C_ADDR<<1)&0xfe, I2C_Direction_Transmitter);
  138. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  139. I2C_SendData(I2C2, LED0_ON_L+4*channel);
  140. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  141. I2C_SendData(I2C2, on&0xff);
  142. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  143. I2C_SendData(I2C2, (on>>8)&0xff);
  144. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  145. I2C_SendData(I2C2, off&0xff);
  146. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  147. I2C_SendData(I2C2, (off>>8)&0xff);
  148. while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  149. I2C_GenerateSTOP(I2C2, ENABLE);
  150. }
  151. void PCA9685_Init() {
  152. u8 value;
  153. I2C2_Init();
  154. // The PRE_SCALE register can only be set when the SLEEP bit of MODE1 register is set to logic 1.
  155. PCA9685_WriteReg(MODE1, MODE1_SLEEP);
  156. PCA9685_WriteReg(PRE_SCALE, 121); // (25000000/4096/50)-1
  157. PCA9685_WriteReg(MODE1, 0);
  158. PCA9685_WriteReg(MODE1, MODE1_RESTART|MODE1_AI|MODE1_ALLCALL);
  159. while (1) {
  160. PCA9685_ReadReg(MODE1, &value);
  161. if ((value&MODE1_RESTART)==0) { // Restart OK.
  162. break;
  163. }
  164. delay(100000);
  165. }
  166. }

pca9685.h

  1. #ifndef _PCA9685_H
  2. #define _PCA9685_H
  3. #include "stm32f10x.h"
  4. void PCA9685_Init();
  5. // channel: 0 ~ 15
  6. // on: 0 ~ 4095
  7. // off: 0 ~ 4095
  8. void PCA9685_SetChannelDuty(u8 channel, u32 on, u32 off);
  9. #endif

sg90.c

  1. #include "pca9685.h"
  2. void SG90_Init() {
  3. PCA9685_Init();
  4. }
  5. void SG90_SetAngle(u8 id, u8 angle) {
  6. PCA9685_SetChannelDuty(id, 0, (u32)(4095*((angle/180.0)*2.0+0.5)/20.0));
  7. }

sg90.h

  1. #ifndef _SG90_H
  2. #define _SG90_H
  3. #include "pca9685.h"
  4. void SG90_Init();
  5. void SG90_SetAngle(u8 id, u8 angle);
  6. #endif

完整测试项目见百度网盘信息

项目链接

链接:https://pan.baidu.com/s/1pV6lL0C0lDvbcEoQoQF-qw?pwd=1234 
提取码:1234 
--来自百度网盘超级会员V3的分享

参考文章

树莓派16路PWM舵机驱动板(PCA9685)_adafruit pca9685-CSDN博客

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

闽ICP备14008679号