极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: eagler8

【Arduino】168种传感器系列实验(170)---L293D四路电机驱动板

[复制链接]
 楼主| 发表于 2020-11-13 08:45:54 | 显示全部楼层
msold5 发表于 2020-11-13 08:22
早鸟的连续剧越来越丰富了

谢谢老师的鼓励
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 09:00:08 | 显示全部楼层
附录:AFMotor.h库文件
目录—adafruit/Adafruit-Motor-Shield-library
链接—https://github.com/adafruit/Adaf ... ob/master/AFMotor.h

  1. // Adafruit Motor shield library
  2. // copyright Adafruit Industries LLC, 2009
  3. // this code is public domain, enjoy!

  4. /*
  5. * Usage Notes:
  6. * For PIC32, all features work properly with the following two exceptions:
  7. *
  8. * 1) Because the PIC32 only has 5 PWM outputs, and the AFMotor shield needs 6
  9. *    to completely operate (four for motor outputs and two for RC servos), the
  10. *    M1 motor output will not have PWM ability when used with a PIC32 board.
  11. *    However, there is a very simple workaround. If you need to drive a stepper
  12. *    or DC motor with PWM on motor output M1, you can use the PWM output on pin
  13. *    9 or pin 10 (normally use for RC servo outputs on Arduino, not needed for
  14. *    RC servo outputs on PIC32) to drive the PWM input for M1 by simply putting
  15. *    a jumber from pin 9 to pin 11 or pin 10 to pin 11. Then uncomment one of the
  16. *    two #defines below to activate the PWM on either pin 9 or pin 10. You will
  17. *    then have a fully functional microstepping for 2 stepper motors, or four
  18. *    DC motor outputs with PWM.
  19. *
  20. * 2) There is a conflict between RC Servo outputs on pins 9 and pins 10 and
  21. *    the operation of DC motors and stepper motors as of 9/2012. This issue
  22. *    will get fixed in future MPIDE releases, but at the present time it means
  23. *    that the Motor Party example will NOT work properly. Any time you attach
  24. *    an RC servo to pins 9 or pins 10, ALL PWM outputs on the whole board will
  25. *    stop working. Thus no steppers or DC motors.
  26. *
  27. */
  28. // <BPS> 09/15/2012 Modified for use with chipKIT boards


  29. #ifndef _AFMotor_h_
  30. #define _AFMotor_h_

  31. #include <inttypes.h>
  32. #if defined(__AVR__)
  33.     #include <avr/io.h>

  34.     //#define MOTORDEBUG 1

  35.     #define MICROSTEPS 16                       // 8 or 16

  36.     #define MOTOR12_64KHZ _BV(CS20)             // no prescale
  37.     #define MOTOR12_8KHZ _BV(CS21)              // divide by 8
  38.     #define MOTOR12_2KHZ _BV(CS21) | _BV(CS20)  // divide by 32
  39.     #define MOTOR12_1KHZ _BV(CS22)              // divide by 64

  40.     #define MOTOR34_64KHZ _BV(CS00)             // no prescale
  41.     #define MOTOR34_8KHZ _BV(CS01)              // divide by 8
  42.     #define MOTOR34_1KHZ _BV(CS01) | _BV(CS00)  // divide by 64
  43.    
  44.     #define DC_MOTOR_PWM_RATE   MOTOR34_8KHZ    // PWM rate for DC motors
  45.     #define STEPPER1_PWM_RATE   MOTOR12_64KHZ   // PWM rate for stepper 1
  46.     #define STEPPER2_PWM_RATE   MOTOR34_64KHZ   // PWM rate for stepper 2
  47.    
  48. #elif defined(__PIC32MX__)
  49.     //#define MOTORDEBUG 1
  50.    
  51.     // Uncomment the one of following lines if you have put a jumper from
  52.     // either pin 9 to pin 11 or pin 10 to pin 11 on your Motor Shield.
  53.     // Either will enable PWM for M1
  54.     //#define PIC32_USE_PIN9_FOR_M1_PWM
  55.     //#define PIC32_USE_PIN10_FOR_M1_PWM

  56.     #define MICROSTEPS 16       // 8 or 16

  57.     // For PIC32 Timers, define prescale settings by PWM frequency
  58.     #define MOTOR12_312KHZ  0   // 1:1, actual frequency 312KHz
  59.     #define MOTOR12_156KHZ  1   // 1:2, actual frequency 156KHz
  60.     #define MOTOR12_64KHZ   2   // 1:4, actual frequency 78KHz
  61.     #define MOTOR12_39KHZ   3   // 1:8, acutal frequency 39KHz
  62.     #define MOTOR12_19KHZ   4   // 1:16, actual frequency 19KHz
  63.     #define MOTOR12_8KHZ    5   // 1:32, actual frequency 9.7KHz
  64.     #define MOTOR12_4_8KHZ  6   // 1:64, actual frequency 4.8KHz
  65.     #define MOTOR12_2KHZ    7   // 1:256, actual frequency 1.2KHz
  66.     #define MOTOR12_1KHZ    7   // 1:256, actual frequency 1.2KHz

  67.     #define MOTOR34_312KHZ  0   // 1:1, actual frequency 312KHz
  68.     #define MOTOR34_156KHZ  1   // 1:2, actual frequency 156KHz
  69.     #define MOTOR34_64KHZ   2   // 1:4, actual frequency 78KHz
  70.     #define MOTOR34_39KHZ   3   // 1:8, acutal frequency 39KHz
  71.     #define MOTOR34_19KHZ   4   // 1:16, actual frequency 19KHz
  72.     #define MOTOR34_8KHZ    5   // 1:32, actual frequency 9.7KHz
  73.     #define MOTOR34_4_8KHZ  6   // 1:64, actual frequency 4.8KHz
  74.     #define MOTOR34_2KHZ    7   // 1:256, actual frequency 1.2KHz
  75.     #define MOTOR34_1KHZ    7   // 1:256, actual frequency 1.2KHz
  76.    
  77.     // PWM rate for DC motors.
  78.     #define DC_MOTOR_PWM_RATE   MOTOR34_39KHZ
  79.     // Note: for PIC32, both of these must be set to the same value
  80.     // since there's only one timebase for all 4 PWM outputs
  81.     #define STEPPER1_PWM_RATE   MOTOR12_39KHZ
  82.     #define STEPPER2_PWM_RATE   MOTOR34_39KHZ
  83.    
  84. #endif

  85. // Bit positions in the 74HCT595 shift register output
  86. #define MOTOR1_A 2
  87. #define MOTOR1_B 3
  88. #define MOTOR2_A 1
  89. #define MOTOR2_B 4
  90. #define MOTOR4_A 0
  91. #define MOTOR4_B 6
  92. #define MOTOR3_A 5
  93. #define MOTOR3_B 7

  94. // Constants that the user passes in to the motor calls
  95. #define FORWARD 1
  96. #define BACKWARD 2
  97. #define BRAKE 3
  98. #define RELEASE 4

  99. // Constants that the user passes in to the stepper calls
  100. #define SINGLE 1
  101. #define DOUBLE 2
  102. #define INTERLEAVE 3
  103. #define MICROSTEP 4

  104. /*
  105. #define LATCH 4
  106. #define LATCH_DDR DDRB
  107. #define LATCH_PORT PORTB
  108. #define CLK_PORT PORTD
  109. #define CLK_DDR DDRD
  110. #define CLK 4
  111. #define ENABLE_PORT PORTD
  112. #define ENABLE_DDR DDRD
  113. #define ENABLE 7
  114. #define SER 0
  115. #define SER_DDR DDRB
  116. #define SER_PORT PORTB
  117. */

  118. // Arduino pin names for interface to 74HCT595 latch
  119. #define MOTORLATCH 12
  120. #define MOTORCLK 4
  121. #define MOTORENABLE 7
  122. #define MOTORDATA 8

  123. class AFMotorController
  124. {
  125.   public:
  126.     AFMotorController(void);
  127.     void enable(void);
  128.     friend class AF_DCMotor;
  129.     void latch_tx(void);
  130.     uint8_t TimerInitalized;
  131. };

  132. class AF_DCMotor
  133. {
  134. public:
  135.   AF_DCMotor(uint8_t motornum, uint8_t freq = DC_MOTOR_PWM_RATE);
  136.   void run(uint8_t);
  137.   void setSpeed(uint8_t);

  138. private:
  139.   uint8_t motornum, pwmfreq;
  140. };

  141. class AF_Stepper {
  142. public:
  143.   AF_Stepper(uint16_t, uint8_t);
  144.   void step(uint16_t steps, uint8_t dir,  uint8_t style = SINGLE);
  145.   void setSpeed(uint16_t);
  146.   uint8_t onestep(uint8_t dir, uint8_t style);
  147.   void release(void);
  148.   uint16_t revsteps; // # steps per revolution
  149.   uint8_t steppernum;
  150.   uint32_t usperstep, steppingcounter;
  151. private:
  152.   uint8_t currentstep;

  153. };

  154. uint8_t getlatchstate(void);

  155. #endif
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 09:04:33 | 显示全部楼层
附录:AFMotor.cpp库文件
目录—adafruit/Adafruit-Motor-Shield-library
链接—https://github.com/adafruit/Adaf ... /master/AFMotor.cpp

  1. // Adafruit Motor shield library
  2. // copyright Adafruit Industries LLC, 2009
  3. // this code is public domain, enjoy!


  4. #if (ARDUINO >= 100)
  5.   #include "Arduino.h"
  6. #else
  7.   #if defined(__AVR__)
  8.     #include <avr/io.h>
  9.   #endif
  10.   #include "WProgram.h"
  11. #endif

  12. #include "AFMotor.h"



  13. static uint8_t latch_state;

  14. #if (MICROSTEPS == 8)
  15. uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
  16. #elif (MICROSTEPS == 16)
  17. uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255};
  18. #endif

  19. AFMotorController::AFMotorController(void) {
  20.     TimerInitalized = false;
  21. }

  22. void AFMotorController::enable(void) {
  23.   // setup the latch
  24.   /*
  25.   LATCH_DDR |= _BV(LATCH);
  26.   ENABLE_DDR |= _BV(ENABLE);
  27.   CLK_DDR |= _BV(CLK);
  28.   SER_DDR |= _BV(SER);
  29.   */
  30.   pinMode(MOTORLATCH, OUTPUT);
  31.   pinMode(MOTORENABLE, OUTPUT);
  32.   pinMode(MOTORDATA, OUTPUT);
  33.   pinMode(MOTORCLK, OUTPUT);

  34.   latch_state = 0;

  35.   latch_tx();  // "reset"

  36.   //ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs!
  37.   digitalWrite(MOTORENABLE, LOW);
  38. }


  39. void AFMotorController::latch_tx(void) {
  40.   uint8_t i;

  41.   //LATCH_PORT &= ~_BV(LATCH);
  42.   digitalWrite(MOTORLATCH, LOW);

  43.   //SER_PORT &= ~_BV(SER);
  44.   digitalWrite(MOTORDATA, LOW);

  45.   for (i=0; i<8; i++) {
  46.     //CLK_PORT &= ~_BV(CLK);
  47.     digitalWrite(MOTORCLK, LOW);

  48.     if (latch_state & _BV(7-i)) {
  49.       //SER_PORT |= _BV(SER);
  50.       digitalWrite(MOTORDATA, HIGH);
  51.     } else {
  52.       //SER_PORT &= ~_BV(SER);
  53.       digitalWrite(MOTORDATA, LOW);
  54.     }
  55.     //CLK_PORT |= _BV(CLK);
  56.     digitalWrite(MOTORCLK, HIGH);
  57.   }
  58.   //LATCH_PORT |= _BV(LATCH);
  59.   digitalWrite(MOTORLATCH, HIGH);
  60. }

  61. static AFMotorController MC;

  62. /******************************************
  63.                MOTORS
  64. ******************************************/
  65. inline void initPWM1(uint8_t freq) {
  66. #if defined(__AVR_ATmega8__) || \
  67.     defined(__AVR_ATmega48__) || \
  68.     defined(__AVR_ATmega88__) || \
  69.     defined(__AVR_ATmega168__) || \
  70.     defined(__AVR_ATmega328P__)
  71.     // use PWM from timer2A on PB3 (Arduino pin #11)
  72.     TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
  73.     TCCR2B = freq & 0x7;
  74.     OCR2A = 0;
  75. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  76.     // on arduino mega, pin 11 is now PB5 (OC1A)
  77.     TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a
  78.     TCCR1B = (freq & 0x7) | _BV(WGM12);
  79.     OCR1A = 0;
  80. #elif defined(__PIC32MX__)
  81.     #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
  82.         // Make sure that pin 11 is an input, since we have tied together 9 and 11
  83.         pinMode(9, OUTPUT);
  84.         pinMode(11, INPUT);
  85.         if (!MC.TimerInitalized)
  86.         {   // Set up Timer2 for 80MHz counting fro 0 to 256
  87.             T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  88.             TMR2 = 0x0000;
  89.             PR2 = 0x0100;
  90.             MC.TimerInitalized = true;
  91.         }
  92.          // Setup OC4 (pin 9) in PWM mode, with Timer2 as timebase
  93.         OC4CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  94.         OC4RS = 0x0000;
  95.         OC4R = 0x0000;
  96.     #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
  97.         // Make sure that pin 11 is an input, since we have tied together 9 and 11
  98.         pinMode(10, OUTPUT);
  99.         pinMode(11, INPUT);
  100.         if (!MC.TimerInitalized)
  101.         {   // Set up Timer2 for 80MHz counting fro 0 to 256
  102.             T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  103.             TMR2 = 0x0000;
  104.             PR2 = 0x0100;
  105.             MC.TimerInitalized = true;
  106.         }
  107.          // Setup OC5 (pin 10) in PWM mode, with Timer2 as timebase
  108.         OC5CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  109.         OC5RS = 0x0000;
  110.         OC5R = 0x0000;
  111.     #else
  112.         // If we are not using PWM for pin 11, then just do digital
  113.         digitalWrite(11, LOW);
  114.     #endif
  115. #else
  116.    #error "This chip is not supported!"
  117. #endif
  118.     #if !defined(PIC32_USE_PIN9_FOR_M1_PWM) && !defined(PIC32_USE_PIN10_FOR_M1_PWM)
  119.         pinMode(11, OUTPUT);
  120.     #endif
  121. }

  122. inline void setPWM1(uint8_t s) {
  123. #if defined(__AVR_ATmega8__) || \
  124.     defined(__AVR_ATmega48__) || \
  125.     defined(__AVR_ATmega88__) || \
  126.     defined(__AVR_ATmega168__) || \
  127.     defined(__AVR_ATmega328P__)
  128.     // use PWM from timer2A on PB3 (Arduino pin #11)
  129.     OCR2A = s;
  130. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  131.     // on arduino mega, pin 11 is now PB5 (OC1A)
  132.     OCR1A = s;
  133. #elif defined(__PIC32MX__)
  134.     #if defined(PIC32_USE_PIN9_FOR_M1_PWM)
  135.         // Set the OC4 (pin 9) PMW duty cycle from 0 to 255
  136.         OC4RS = s;
  137.     #elif defined(PIC32_USE_PIN10_FOR_M1_PWM)
  138.         // Set the OC5 (pin 10) PMW duty cycle from 0 to 255
  139.         OC5RS = s;
  140.     #else
  141.         // If we are not doing PWM output for M1, then just use on/off
  142.         if (s > 127)
  143.         {
  144.             digitalWrite(11, HIGH);
  145.         }
  146.         else
  147.         {
  148.             digitalWrite(11, LOW);
  149.         }
  150.     #endif
  151. #else
  152.    #error "This chip is not supported!"
  153. #endif
  154. }

  155. inline void initPWM2(uint8_t freq) {
  156. #if defined(__AVR_ATmega8__) || \
  157.     defined(__AVR_ATmega48__) || \
  158.     defined(__AVR_ATmega88__) || \
  159.     defined(__AVR_ATmega168__) || \
  160.     defined(__AVR_ATmega328P__)
  161.     // use PWM from timer2B (pin 3)
  162.     TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b
  163.     TCCR2B = freq & 0x7;
  164.     OCR2B = 0;
  165. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  166.     // on arduino mega, pin 3 is now PE5 (OC3C)
  167.     TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c
  168.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  169.     OCR3C = 0;
  170. #elif defined(__PIC32MX__)
  171.     if (!MC.TimerInitalized)
  172.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  173.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  174.         TMR2 = 0x0000;
  175.         PR2 = 0x0100;
  176.         MC.TimerInitalized = true;
  177.     }
  178.     // Setup OC1 (pin3) in PWM mode, with Timer2 as timebase
  179.     OC1CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  180.     OC1RS = 0x0000;
  181.     OC1R = 0x0000;
  182. #else
  183.    #error "This chip is not supported!"
  184. #endif

  185.     pinMode(3, OUTPUT);
  186. }

  187. inline void setPWM2(uint8_t s) {
  188. #if defined(__AVR_ATmega8__) || \
  189.     defined(__AVR_ATmega48__) || \
  190.     defined(__AVR_ATmega88__) || \
  191.     defined(__AVR_ATmega168__) || \
  192.     defined(__AVR_ATmega328P__)
  193.     // use PWM from timer2A on PB3 (Arduino pin #11)
  194.     OCR2B = s;
  195. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  196.     // on arduino mega, pin 11 is now PB5 (OC1A)
  197.     OCR3C = s;
  198. #elif defined(__PIC32MX__)
  199.     // Set the OC1 (pin3) PMW duty cycle from 0 to 255
  200.     OC1RS = s;
  201. #else
  202.    #error "This chip is not supported!"
  203. #endif
  204. }

  205. inline void initPWM3(uint8_t freq) {
  206. #if defined(__AVR_ATmega8__) || \
  207.     defined(__AVR_ATmega48__) || \
  208.     defined(__AVR_ATmega88__) || \
  209.     defined(__AVR_ATmega168__) || \
  210.     defined(__AVR_ATmega328P__)
  211.     // use PWM from timer0A / PD6 (pin 6)
  212.     TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A
  213.     //TCCR0B = freq & 0x7;
  214.     OCR0A = 0;
  215. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  216.     // on arduino mega, pin 6 is now PH3 (OC4A)
  217.     TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a
  218.     TCCR4B = (freq & 0x7) | _BV(WGM12);
  219.     //TCCR4B = 1 | _BV(WGM12);
  220.     OCR4A = 0;
  221. #elif defined(__PIC32MX__)
  222.     if (!MC.TimerInitalized)
  223.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  224.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  225.         TMR2 = 0x0000;
  226.         PR2 = 0x0100;
  227.         MC.TimerInitalized = true;
  228.     }
  229.     // Setup OC3 (pin 6) in PWM mode, with Timer2 as timebase
  230.     OC3CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  231.     OC3RS = 0x0000;
  232.     OC3R = 0x0000;
  233. #else
  234.    #error "This chip is not supported!"
  235. #endif
  236.     pinMode(6, OUTPUT);
  237. }

  238. inline void setPWM3(uint8_t s) {
  239. #if defined(__AVR_ATmega8__) || \
  240.     defined(__AVR_ATmega48__) || \
  241.     defined(__AVR_ATmega88__) || \
  242.     defined(__AVR_ATmega168__) || \
  243.     defined(__AVR_ATmega328P__)
  244.     // use PWM from timer0A on PB3 (Arduino pin #6)
  245.     OCR0A = s;
  246. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  247.     // on arduino mega, pin 6 is now PH3 (OC4A)
  248.     OCR4A = s;
  249. #elif defined(__PIC32MX__)
  250.     // Set the OC3 (pin 6) PMW duty cycle from 0 to 255
  251.     OC3RS = s;
  252. #else
  253.    #error "This chip is not supported!"
  254. #endif
  255. }



  256. inline void initPWM4(uint8_t freq) {
  257. #if defined(__AVR_ATmega8__) || \
  258.     defined(__AVR_ATmega48__) || \
  259.     defined(__AVR_ATmega88__) || \
  260.     defined(__AVR_ATmega168__) || \
  261.     defined(__AVR_ATmega328P__)
  262.     // use PWM from timer0B / PD5 (pin 5)
  263.     TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a
  264.     //TCCR0B = freq & 0x7;
  265.     OCR0B = 0;
  266. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  267.     // on arduino mega, pin 5 is now PE3 (OC3A)
  268.     TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a
  269.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  270.     //TCCR4B = 1 | _BV(WGM12);
  271.     OCR3A = 0;
  272. #elif defined(__PIC32MX__)
  273.     if (!MC.TimerInitalized)
  274.     {   // Set up Timer2 for 80MHz counting fro 0 to 256
  275.         T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=<freq>, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0
  276.         TMR2 = 0x0000;
  277.         PR2 = 0x0100;
  278.         MC.TimerInitalized = true;
  279.     }
  280.     // Setup OC2 (pin 5) in PWM mode, with Timer2 as timebase
  281.     OC2CON = 0x8006;    // OC32 = 0, OCTSEL=0, OCM=6
  282.     OC2RS = 0x0000;
  283.     OC2R = 0x0000;
  284. #else
  285.    #error "This chip is not supported!"
  286. #endif
  287.     pinMode(5, OUTPUT);
  288. }

  289. inline void setPWM4(uint8_t s) {
  290. #if defined(__AVR_ATmega8__) || \
  291.     defined(__AVR_ATmega48__) || \
  292.     defined(__AVR_ATmega88__) || \
  293.     defined(__AVR_ATmega168__) || \
  294.     defined(__AVR_ATmega328P__)
  295.     // use PWM from timer0A on PB3 (Arduino pin #6)
  296.     OCR0B = s;
  297. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  298.     // on arduino mega, pin 6 is now PH3 (OC4A)
  299.     OCR3A = s;
  300. #elif defined(__PIC32MX__)
  301.     // Set the OC2 (pin 5) PMW duty cycle from 0 to 255
  302.     OC2RS = s;
  303. #else
  304.    #error "This chip is not supported!"
  305. #endif
  306. }

  307. AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) {
  308.   motornum = num;
  309.   pwmfreq = freq;

  310.   MC.enable();

  311.   switch (num) {
  312.   case 1:
  313.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0
  314.     MC.latch_tx();
  315.     initPWM1(freq);
  316.     break;
  317.   case 2:
  318.     latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0
  319.     MC.latch_tx();
  320.     initPWM2(freq);
  321.     break;
  322.   case 3:
  323.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0
  324.     MC.latch_tx();
  325.     initPWM3(freq);
  326.     break;
  327.   case 4:
  328.     latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0
  329.     MC.latch_tx();
  330.     initPWM4(freq);
  331.     break;
  332.   }
  333. }

  334. void AF_DCMotor::run(uint8_t cmd) {
  335.   uint8_t a, b;
  336.   switch (motornum) {
  337.   case 1:
  338.     a = MOTOR1_A; b = MOTOR1_B; break;
  339.   case 2:
  340.     a = MOTOR2_A; b = MOTOR2_B; break;
  341.   case 3:
  342.     a = MOTOR3_A; b = MOTOR3_B; break;
  343.   case 4:
  344.     a = MOTOR4_A; b = MOTOR4_B; break;
  345.   default:
  346.     return;
  347.   }
  348.   
  349.   switch (cmd) {
  350.   case FORWARD:
  351.     latch_state |= _BV(a);
  352.     latch_state &= ~_BV(b);
  353.     MC.latch_tx();
  354.     break;
  355.   case BACKWARD:
  356.     latch_state &= ~_BV(a);
  357.     latch_state |= _BV(b);
  358.     MC.latch_tx();
  359.     break;
  360.   case RELEASE:
  361.     latch_state &= ~_BV(a);     // A and B both low
  362.     latch_state &= ~_BV(b);
  363.     MC.latch_tx();
  364.     break;
  365.   }
  366. }

  367. void AF_DCMotor::setSpeed(uint8_t speed) {
  368.   switch (motornum) {
  369.   case 1:
  370.     setPWM1(speed); break;
  371.   case 2:
  372.     setPWM2(speed); break;
  373.   case 3:
  374.     setPWM3(speed); break;
  375.   case 4:
  376.     setPWM4(speed); break;
  377.   }
  378. }

  379. /******************************************
  380.                STEPPERS
  381. ******************************************/

  382. AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
  383.   MC.enable();

  384.   revsteps = steps;
  385.   steppernum = num;
  386.   currentstep = 0;

  387.   if (steppernum == 1) {
  388.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
  389.       ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
  390.     MC.latch_tx();
  391.    
  392.     // enable both H bridges
  393.     pinMode(11, OUTPUT);
  394.     pinMode(3, OUTPUT);
  395.     digitalWrite(11, HIGH);
  396.     digitalWrite(3, HIGH);

  397.     // use PWM for microstepping support
  398.     initPWM1(STEPPER1_PWM_RATE);
  399.     initPWM2(STEPPER1_PWM_RATE);
  400.     setPWM1(255);
  401.     setPWM2(255);

  402.   } else if (steppernum == 2) {
  403.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
  404.       ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
  405.     MC.latch_tx();

  406.     // enable both H bridges
  407.     pinMode(5, OUTPUT);
  408.     pinMode(6, OUTPUT);
  409.     digitalWrite(5, HIGH);
  410.     digitalWrite(6, HIGH);

  411.     // use PWM for microstepping support
  412.     // use PWM for microstepping support
  413.     initPWM3(STEPPER2_PWM_RATE);
  414.     initPWM4(STEPPER2_PWM_RATE);
  415.     setPWM3(255);
  416.     setPWM4(255);
  417.   }
  418. }

  419. void AF_Stepper::setSpeed(uint16_t rpm) {
  420.   usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm);
  421.   steppingcounter = 0;
  422. }

  423. void AF_Stepper::release(void) {
  424.   if (steppernum == 1) {
  425.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
  426.       ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
  427.     MC.latch_tx();
  428.   } else if (steppernum == 2) {
  429.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
  430.       ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
  431.     MC.latch_tx();
  432.   }
  433. }

  434. void AF_Stepper::step(uint16_t steps, uint8_t dir,  uint8_t style) {
  435.   uint32_t uspers = usperstep;
  436.   uint8_t ret = 0;

  437.   if (style == INTERLEAVE) {
  438.     uspers /= 2;
  439.   }
  440. else if (style == MICROSTEP) {
  441.     uspers /= MICROSTEPS;
  442.     steps *= MICROSTEPS;
  443. #ifdef MOTORDEBUG
  444.     Serial.print("steps = "); Serial.println(steps, DEC);
  445. #endif
  446.   }

  447.   while (steps--) {
  448.     ret = onestep(dir, style);
  449.     delay(uspers/1000); // in ms
  450.     steppingcounter += (uspers % 1000);
  451.     if (steppingcounter >= 1000) {
  452.       delay(1);
  453.       steppingcounter -= 1000;
  454.     }
  455.   }
  456.   if (style == MICROSTEP) {
  457.     while ((ret != 0) && (ret != MICROSTEPS)) {
  458.       ret = onestep(dir, style);
  459.       delay(uspers/1000); // in ms
  460.       steppingcounter += (uspers % 1000);
  461.       if (steppingcounter >= 1000) {
  462.         delay(1);
  463.         steppingcounter -= 1000;
  464.       }
  465.     }
  466.   }
  467. }

  468. uint8_t AF_Stepper::onestep(uint8_t dir, uint8_t style) {
  469.   uint8_t a, b, c, d;
  470.   uint8_t ocrb, ocra;

  471.   ocra = ocrb = 255;

  472.   if (steppernum == 1) {
  473.     a = _BV(MOTOR1_A);
  474.     b = _BV(MOTOR2_A);
  475.     c = _BV(MOTOR1_B);
  476.     d = _BV(MOTOR2_B);
  477.   } else if (steppernum == 2) {
  478.     a = _BV(MOTOR3_A);
  479.     b = _BV(MOTOR4_A);
  480.     c = _BV(MOTOR3_B);
  481.     d = _BV(MOTOR4_B);
  482.   } else {
  483.     return 0;
  484.   }

  485.   // next determine what sort of stepping procedure we're up to
  486.   if (style == SINGLE) {
  487.     if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird
  488.       if (dir == FORWARD) {
  489.         currentstep += MICROSTEPS/2;
  490.       }
  491.       else {
  492.         currentstep -= MICROSTEPS/2;
  493.       }
  494.     } else {           // go to the next even step
  495.       if (dir == FORWARD) {
  496.         currentstep += MICROSTEPS;
  497.       }
  498.       else {
  499.         currentstep -= MICROSTEPS;
  500.       }
  501.     }
  502.   } else if (style == DOUBLE) {
  503.     if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird
  504.       if (dir == FORWARD) {
  505.         currentstep += MICROSTEPS/2;
  506.       } else {
  507.         currentstep -= MICROSTEPS/2;
  508.       }
  509.     } else {           // go to the next odd step
  510.       if (dir == FORWARD) {
  511.         currentstep += MICROSTEPS;
  512.       } else {
  513.         currentstep -= MICROSTEPS;
  514.       }
  515.     }
  516.   } else if (style == INTERLEAVE) {
  517.     if (dir == FORWARD) {
  518.        currentstep += MICROSTEPS/2;
  519.     } else {
  520.        currentstep -= MICROSTEPS/2;
  521.     }
  522.   }

  523.   if (style == MICROSTEP) {
  524.     if (dir == FORWARD) {
  525.       currentstep++;
  526.     } else {
  527.       // BACKWARDS
  528.       currentstep--;
  529.     }

  530.     currentstep += MICROSTEPS*4;
  531.     currentstep %= MICROSTEPS*4;

  532.     ocra = ocrb = 0;
  533.     if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) {
  534.       ocra = microstepcurve[MICROSTEPS - currentstep];
  535.       ocrb = microstepcurve[currentstep];
  536.     } else if  ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) {
  537.       ocra = microstepcurve[currentstep - MICROSTEPS];
  538.       ocrb = microstepcurve[MICROSTEPS*2 - currentstep];
  539.     } else if  ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) {
  540.       ocra = microstepcurve[MICROSTEPS*3 - currentstep];
  541.       ocrb = microstepcurve[currentstep - MICROSTEPS*2];
  542.     } else if  ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) {
  543.       ocra = microstepcurve[currentstep - MICROSTEPS*3];
  544.       ocrb = microstepcurve[MICROSTEPS*4 - currentstep];
  545.     }
  546.   }

  547.   currentstep += MICROSTEPS*4;
  548.   currentstep %= MICROSTEPS*4;

  549. #ifdef MOTORDEBUG
  550.   Serial.print("current step: "); Serial.println(currentstep, DEC);
  551.   Serial.print(" pwmA = "); Serial.print(ocra, DEC);
  552.   Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
  553. #endif

  554.   if (steppernum == 1) {
  555.     setPWM1(ocra);
  556.     setPWM2(ocrb);
  557.   } else if (steppernum == 2) {
  558.     setPWM3(ocra);
  559.     setPWM4(ocrb);
  560.   }


  561.   // release all
  562.   latch_state &= ~a & ~b & ~c & ~d; // all motor pins to 0

  563.   //Serial.println(step, DEC);
  564.   if (style == MICROSTEP) {
  565.     if ((currentstep >= 0) && (currentstep < MICROSTEPS))
  566.       latch_state |= a | b;
  567.     if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2))
  568.       latch_state |= b | c;
  569.     if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3))
  570.       latch_state |= c | d;
  571.     if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4))
  572.       latch_state |= d | a;
  573.   } else {
  574.     switch (currentstep/(MICROSTEPS/2)) {
  575.     case 0:
  576.       latch_state |= a; // energize coil 1 only
  577.       break;
  578.     case 1:
  579.       latch_state |= a | b; // energize coil 1+2
  580.       break;
  581.     case 2:
  582.       latch_state |= b; // energize coil 2 only
  583.       break;
  584.     case 3:
  585.       latch_state |= b | c; // energize coil 2+3
  586.       break;
  587.     case 4:
  588.       latch_state |= c; // energize coil 3 only
  589.       break;
  590.     case 5:
  591.       latch_state |= c | d; // energize coil 3+4
  592.       break;
  593.     case 6:
  594.       latch_state |= d; // energize coil 4 only
  595.       break;
  596.     case 7:
  597.       latch_state |= d | a; // energize coil 1+4
  598.       break;
  599.     }
  600.   }


  601.   MC.latch_tx();
  602.   return currentstep;
  603. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 09:51:20 | 显示全部楼层
补充实验

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  3.   实验一百七十:L293D四路电机驱动板 motor control shield 马达板
  4.   Adafruit Motor Shield模块 Arduino AFMotor 电机扩展板

  5.   1、安装库:IDE—工具—管理库—搜索“Servo”—安装
  6.   2、实验之八:测试M1M2电机
  7. */

  8. #include <AFMotor.h>

  9. AF_DCMotor motor1(1);
  10. AF_DCMotor motor2(2);

  11. void setup() {
  12.   Serial.begin(9600);
  13.   Serial.println("测试M1M2电机!");

  14.   // turn on motor
  15.   motor1.setSpeed(200);
  16.   motor2.setSpeed(200);

  17.   motor1.run(RELEASE);
  18.   motor2.run(RELEASE);
  19. }

  20. void loop() {
  21.   uint8_t i;

  22.   Serial.println("正转");

  23.   motor1.run(FORWARD);
  24.   motor2.run(FORWARD);
  25.   for (i = 0; i < 255; i++) {
  26.     motor1.setSpeed(i);
  27.     motor2.setSpeed(i);
  28.     delay(10);
  29.   }

  30.   for (i = 255; i != 0; i--) {
  31.     motor1.setSpeed(i);
  32.     motor2.setSpeed(i);
  33.     delay(10);
  34.   }

  35.   Serial.println("反转");

  36.   motor1.run(BACKWARD);
  37.   motor2.run(BACKWARD);

  38.   for (i = 0; i < 255; i++) {
  39.     motor1.setSpeed(i);
  40.     motor2.setSpeed(i);
  41.     delay(10);
  42.   }

  43.   for (i = 255; i != 0; i--) {
  44.     motor1.setSpeed(i);
  45.     motor2.setSpeed(i);
  46.     delay(10);
  47.   }

  48.   Serial.println("断电一秒");
  49.   motor1.run(RELEASE);
  50.   motor2.run(RELEASE);
  51.   delay(1000);
  52. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 10:39:42 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 11:00:55 | 显示全部楼层
太极创客团队制作的B站视频,相当不错的视频教程

B站太极创客官方站:https://space.bilibili.com/10358 ... _765f7570696e666f.2



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 11:04:33 | 显示全部楼层
本帖最后由 eagler8 于 2020-11-13 11:05 编辑

Arduino AFMotor电机扩展板(上)
https://www.bilibili.com/video/BV1vb411q7xz?p=1

Arduino AFMotor电机扩展板(下)
https://www.bilibili.com/video/BV1vb411q7xz?p=2


回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 13:22:16 | 显示全部楼层
AFMotor电机驱动扩展板使用图形编程
【mind+用户库】第三方库方案

先下载安装Mind+(目前版本V1.6.5 RC3.0)
链接:http://mindplus.cc/download.html


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 13:38:35 | 显示全部楼层
打开Mind+,进入“扩展”

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 13:41:51 | 显示全部楼层
进入“用户库”

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 13:44:59 | 显示全部楼层
在用户库中搜索“hockel”即可

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 13:47:41 | 显示全部楼层
添加的 AFMotor模块

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 14:03:51 | 显示全部楼层
AFMotor电机驱动扩展板积木列表

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 16:53:27 | 显示全部楼层
用图形编程驱动四只直流电机

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-13 16:55:20 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 15:52 , Processed in 0.041838 second(s), 15 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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