狗趴(GodPub),开源硬件学习与实践

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 5672|回复: 3
打印 上一主题 下一主题

【二叔科技】学习驱动电机

[复制链接]

13

主题

33

帖子

155

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
155
跳转到指定楼层
楼主
发表于 2014-12-29 21:15:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
发现了一篇讲得比较好的帖子
http://forum.godpub.com/article-2-1.html
  1. class AF_DCMotor
  2. {
  3. public:
  4.   AF_DCMotor(uint8_t motornum, uint8_t freq =  MOTOR34_8KHZ);
  5.   void run(uint8_t);
  6.   void setSpeed(uint8_t);

  7. private:
  8.   uint8_t motornum, pwmfreq;
  9. };
复制代码

  1. AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) {
  2.   motornum = num;
  3.   pwmfreq = freq;

  4.   MC.enable();

  5.   switch (num) {
  6.   case 1:
  7.     latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0
  8.     MC.latch_tx();
  9.     initPWM1(freq);
  10.     break;
  11.   case 2:
  12.     latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0
  13.     MC.latch_tx();
  14.     initPWM2(freq);
  15.     break;
  16.   case 3:
  17.     latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0
  18.     MC.latch_tx();
  19.     initPWM3(freq);
  20.     break;
  21.   case 4:
  22.     latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0
  23.     MC.latch_tx();
  24.     initPWM4(freq);
  25.     break;
  26.   }
  27. }
复制代码

  1. void AF_DCMotor::setSpeed(uint8_t speed) {
  2.   switch (motornum) {
  3.   case 1:
  4.     setPWM1(speed); break;
  5.   case 2:
  6.     setPWM2(speed); break;
  7.   case 3:
  8.     setPWM3(speed); break;
  9.   case 4:
  10.     setPWM4(speed); break;
  11.   }
  12. }
复制代码

  1. void AF_DCMotor::run(uint8_t cmd) {
  2.   uint8_t a, b;
  3.   switch (motornum) {
  4.   case 1:
  5.     a = MOTOR1_A; b = MOTOR1_B; break;
  6.   case 2:
  7.     a = MOTOR2_A; b = MOTOR2_B; break;
  8.   case 3:
  9.     a = MOTOR3_A; b = MOTOR3_B; break;
  10.   case 4:
  11.     a = MOTOR4_A; b = MOTOR4_B; break;
  12.   default:
  13.     return;
  14.   }
  15.   
  16.   switch (cmd) {
  17.   case FORWARD:
  18.     latch_state |= _BV(a);
  19.     latch_state &= ~_BV(b);
  20.     MC.latch_tx();
  21.     break;
  22.   case BACKWARD:
  23.     latch_state &= ~_BV(a);
  24.     latch_state |= _BV(b);
  25.     MC.latch_tx();
  26.     break;
  27.   case RELEASE:
  28.     latch_state &= ~_BV(a);
  29.     latch_state &= ~_BV(b);
  30.     MC.latch_tx();
  31.     break;
  32.   }
  33. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏

13

主题

33

帖子

155

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
155
沙发
 楼主| 发表于 2014-12-29 21:20:36 | 只看该作者
  1. class AFMotorController
  2. {
  3.   public:
  4.     AFMotorController(void);
  5.     void enable(void);
  6.     friend class AF_DCMotor;
  7.     void latch_tx(void);
  8. };
复制代码

  1. AFMotorController::AFMotorController(void) {
  2. }
复制代码

  1. void AFMotorController::enable(void) {
  2.   // setup the latch
  3.   /*
  4.   LATCH_DDR |= _BV(LATCH);
  5.   ENABLE_DDR |= _BV(ENABLE);
  6.   CLK_DDR |= _BV(CLK);
  7.   SER_DDR |= _BV(SER);
  8.   */
  9.   pinMode(MOTORLATCH, OUTPUT);
  10.   pinMode(MOTORENABLE, OUTPUT);
  11.   pinMode(MOTORDATA, OUTPUT);
  12.   pinMode(MOTORCLK, OUTPUT);

  13.   latch_state = 0;

  14.   latch_tx();  // "reset"

  15.   //ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs!
  16.   digitalWrite(MOTORENABLE, LOW);
  17. }
复制代码

  1. void AFMotorController::latch_tx(void) {
  2.   uint8_t i;

  3.   //LATCH_PORT &= ~_BV(LATCH);
  4.   digitalWrite(MOTORLATCH, LOW);

  5.   //SER_PORT &= ~_BV(SER);
  6.   digitalWrite(MOTORDATA, LOW);

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

  10.     if (latch_state & _BV(7-i)) {
  11.       //SER_PORT |= _BV(SER);
  12.       digitalWrite(MOTORDATA, HIGH);
  13.     } else {
  14.       //SER_PORT &= ~_BV(SER);
  15.       digitalWrite(MOTORDATA, LOW);
  16.     }
  17.     //CLK_PORT |= _BV(CLK);
  18.     digitalWrite(MOTORCLK, HIGH);
  19.   }
  20.   //LATCH_PORT |= _BV(LATCH);
  21.   digitalWrite(MOTORLATCH, HIGH);
  22. }
复制代码

13

主题

33

帖子

155

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
155
板凳
 楼主| 发表于 2014-12-29 21:24:20 | 只看该作者
  1. inline void initPWM1(uint8_t freq) {
  2. #if defined(__AVR_ATmega8__) || \
  3.     defined(__AVR_ATmega48__) || \
  4.     defined(__AVR_ATmega88__) || \
  5.     defined(__AVR_ATmega168__) || \
  6.     defined(__AVR_ATmega328P__)
  7.     // use PWM from timer2A on PB3 (Arduino pin #11)
  8.     TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
  9.     TCCR2B = freq & 0x7;
  10.     OCR2A = 0;
  11. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  12.     // on arduino mega, pin 11 is now PB5 (OC1A)
  13.     TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a
  14.     TCCR1B = (freq & 0x7) | _BV(WGM12);
  15.     OCR1A = 0;
  16. #else
  17.    #error "This chip is not supported!"
  18. #endif
  19.     pinMode(11, OUTPUT);
  20. }

  21. inline void setPWM1(uint8_t s) {
  22. #if defined(__AVR_ATmega8__) || \
  23.     defined(__AVR_ATmega48__) || \
  24.     defined(__AVR_ATmega88__) || \
  25.     defined(__AVR_ATmega168__) || \
  26.     defined(__AVR_ATmega328P__)
  27.     // use PWM from timer2A on PB3 (Arduino pin #11)
  28.     OCR2A = s;
  29. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  30.     // on arduino mega, pin 11 is now PB5 (OC1A)
  31.     OCR1A = s;
  32. #else
  33.    #error "This chip is not supported!"
  34. #endif
  35. }

  36. inline void initPWM2(uint8_t freq) {
  37. #if defined(__AVR_ATmega8__) || \
  38.     defined(__AVR_ATmega48__) || \
  39.     defined(__AVR_ATmega88__) || \
  40.     defined(__AVR_ATmega168__) || \
  41.     defined(__AVR_ATmega328P__)
  42.     // use PWM from timer2B (pin 3)
  43.     TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b
  44.     TCCR2B = freq & 0x7;
  45.     OCR2B = 0;
  46. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  47.     // on arduino mega, pin 3 is now PE5 (OC3C)
  48.     TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c
  49.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  50.     OCR3C = 0;
  51. #else
  52.    #error "This chip is not supported!"
  53. #endif

  54.     pinMode(3, OUTPUT);
  55. }

  56. inline void setPWM2(uint8_t s) {
  57. #if defined(__AVR_ATmega8__) || \
  58.     defined(__AVR_ATmega48__) || \
  59.     defined(__AVR_ATmega88__) || \
  60.     defined(__AVR_ATmega168__) || \
  61.     defined(__AVR_ATmega328P__)
  62.     // use PWM from timer2A on PB3 (Arduino pin #11)
  63.     OCR2B = s;
  64. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  65.     // on arduino mega, pin 11 is now PB5 (OC1A)
  66.     OCR3C = s;
  67. #else
  68.    #error "This chip is not supported!"
  69. #endif
  70. }

  71. inline void initPWM3(uint8_t freq) {
  72. #if defined(__AVR_ATmega8__) || \
  73.     defined(__AVR_ATmega48__) || \
  74.     defined(__AVR_ATmega88__) || \
  75.     defined(__AVR_ATmega168__) || \
  76.     defined(__AVR_ATmega328P__)
  77.     // use PWM from timer0A / PD6 (pin 6)
  78.     TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A
  79.     //TCCR0B = freq & 0x7;
  80.     OCR0A = 0;
  81. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  82.     // on arduino mega, pin 6 is now PH3 (OC4A)
  83.     TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a
  84.     TCCR4B = (freq & 0x7) | _BV(WGM12);
  85.     //TCCR4B = 1 | _BV(WGM12);
  86.     OCR4A = 0;
  87. #else
  88.    #error "This chip is not supported!"
  89. #endif
  90.     pinMode(6, OUTPUT);
  91. }

  92. inline void setPWM3(uint8_t s) {
  93. #if defined(__AVR_ATmega8__) || \
  94.     defined(__AVR_ATmega48__) || \
  95.     defined(__AVR_ATmega88__) || \
  96.     defined(__AVR_ATmega168__) || \
  97.     defined(__AVR_ATmega328P__)
  98.     // use PWM from timer0A on PB3 (Arduino pin #6)
  99.     OCR0A = s;
  100. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  101.     // on arduino mega, pin 6 is now PH3 (OC4A)
  102.     OCR4A = s;
  103. #else
  104.    #error "This chip is not supported!"
  105. #endif
  106. }



  107. inline void initPWM4(uint8_t freq) {
  108. #if defined(__AVR_ATmega8__) || \
  109.     defined(__AVR_ATmega48__) || \
  110.     defined(__AVR_ATmega88__) || \
  111.     defined(__AVR_ATmega168__) || \
  112.     defined(__AVR_ATmega328P__)
  113.     // use PWM from timer0B / PD5 (pin 5)
  114.     TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a
  115.     //TCCR0B = freq & 0x7;
  116.     OCR0B = 0;
  117. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  118.     // on arduino mega, pin 5 is now PE3 (OC3A)
  119.     TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a
  120.     TCCR3B = (freq & 0x7) | _BV(WGM12);
  121.     //TCCR4B = 1 | _BV(WGM12);
  122.     OCR3A = 0;
  123. #else
  124.    #error "This chip is not supported!"
  125. #endif
  126.     pinMode(5, OUTPUT);
  127. }

  128. inline void setPWM4(uint8_t s) {
  129. #if defined(__AVR_ATmega8__) || \
  130.     defined(__AVR_ATmega48__) || \
  131.     defined(__AVR_ATmega88__) || \
  132.     defined(__AVR_ATmega168__) || \
  133.     defined(__AVR_ATmega328P__)
  134.     // use PWM from timer0A on PB3 (Arduino pin #6)
  135.     OCR0B = s;
  136. #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  137.     // on arduino mega, pin 6 is now PH3 (OC4A)
  138.     OCR3A = s;
  139. #else
  140.    #error "This chip is not supported!"
  141. #endif
  142. }
复制代码

84

主题

143

帖子

725

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
725
QQ
地板
发表于 2015-1-5 18:11:27 | 只看该作者
二叔威武
天理路上甚宽,稍游心,胸中便觉广大宏朗;
人欲路上甚窄,才寄迹,眼前俱是荆棘泥涂。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|狗趴(GodPub) Arduino&Raspberry Pi开源硬件学习与实践[QQ群:20085629]  

GMT+8, 2024-5-2 11:41 , Processed in 0.037952 second(s), 30 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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