AVR based brushless motor controller
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
5.5 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
13 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. /***************************************************************************
  2. * Copyright (C) 09/2007 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License, *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. /*
  20. * Status LED_GN LED_RT
  21. * No Error, Motor off ON -
  22. * No Error, Motor spinup FAST -
  23. * No Error, Motor running SLOW -
  24. * Current Limit F/S ON
  25. * i2c Timeout ON ON
  26. * Undervoltage OFF SLOW
  27. * Overcurrent (Hard Limit) OFF FAST
  28. * SELFTEST failed FAST FAST (not implemented yet)
  29. * EEPROM invalid SLOW SLOW
  30. */
  31. #include <avr/io.h>
  32. #include <avr/interrupt.h>
  33. #include <avr/sleep.h>
  34. #include "main.h"
  35. #include "blmc.h"
  36. #include "eeprom.h"
  37. #define LED_OFF 0x00
  38. #define LED_SLOW 0x01
  39. #define LED_FAST 0x10
  40. #define LED_ON 0x11
  41. extern struct blmc_ blmc;
  42. static uint8_t led[2];
  43. ISR(TIMER0_OVF_vect)
  44. {
  45. static uint8_t timer0_cnt = 0;
  46. static uint8_t adc_chan = SENSE_CURRENT;
  47. /* Come back in 20ms */
  48. TCNT0 = 0xFF - 156;
  49. /* commutations during last 20ms */
  50. uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old;
  51. blmc.rpm_tmp_old = blmc.rpm_tmp;
  52. if ((blmc.flags & FLAG_RUN_MASK) == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL)) {
  53. /* too few commutations while running -> do a spinup */
  54. if (diff < 0x08) {
  55. blmc.flags &= ~(FLAG_RUN_MASK);
  56. blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
  57. }
  58. /* no i2c cmd in the last 20ms */
  59. if (!(blmc.flags & FLAG_I2C_ACTIVE)) {
  60. /* already in i2c timeout, turn off motor */
  61. if (blmc.flags & FLAG_I2C_TIMEOUT)
  62. blmc.pwm = 0;
  63. blmc.flags |= FLAG_I2C_TIMEOUT;
  64. } else {
  65. blmc.flags &= ~FLAG_I2C_TIMEOUT;
  66. }
  67. blmc.flags &= ~FLAG_I2C_ACTIVE;
  68. }
  69. /* set pwm again (adjust current limit) */
  70. setpwm(blmc.pwm);
  71. /* calc rpm every second */
  72. timer0_cnt++;
  73. if (timer0_cnt == 50) {
  74. timer0_cnt = 0;
  75. blmc.rpm = blmc.rpm_tmp;
  76. blmc.rpm_tmp = 0;
  77. }
  78. /* trigger adc by hand when not running */
  79. if (!(blmc.flags & FLAG_COM_NORMAL)) {
  80. trigger_adc(adc_chan);
  81. if (adc_chan == SENSE_CURRENT)
  82. adc_chan = SENSE_VOLTAGE;
  83. else
  84. adc_chan = SENSE_CURRENT;
  85. }
  86. /* led blink timer */
  87. static uint8_t led_timer = 0;
  88. led_timer = (led_timer +1) & 0x1F;
  89. /* green LED */
  90. if (((led[0] == LED_SLOW) && (led_timer & 0x10)) ||
  91. (led[0] == LED_FAST && (led_timer & 0x04)) ||
  92. (led[0] == LED_ON)) {
  93. PORTB |= LED_GN;
  94. } else {
  95. PORTB &= ~LED_GN;
  96. }
  97. /* red LED */
  98. if (((led[1] == LED_SLOW) && !(led_timer & 0x10)) ||
  99. (led[1] == LED_FAST && !(led_timer & 0x04)) ||
  100. (led[1] == LED_ON)) {
  101. PORTB |= LED_RT;
  102. } else {
  103. PORTB &= ~LED_RT;
  104. }
  105. }
  106. int main(void)
  107. {
  108. DDRB = PHASE_H_MASK | LED_RT | LED_GN;
  109. DDRD = PHASE_L_MASK;
  110. PORTB = 0x00;
  111. PORTD = 0x00;
  112. /* timer0: running with F_CPU/1024 */
  113. TCCR0 = (1<<CS02) | (1<<CS00);
  114. /* timer1: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
  115. TCCR1B = (1<<CS10);
  116. TCCR1A = (1<<WGM10);
  117. /* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
  118. TCCR2 = (1<<WGM20) | (1<<CS20);
  119. /* enable Timer0 OVF Interrupt */
  120. TIMSK = (1<<TOIE0);
  121. /* Enable Analog Comparator Multiplexer */
  122. SFIOR |= (1<<ACME);
  123. /* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */
  124. TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
  125. blmc.flags = 0x00;
  126. if (read_parameters())
  127. blmc.flags |= FLAG_INVALID_EEPROM;
  128. set_sleep_mode(SLEEP_MODE_IDLE);
  129. sei();
  130. while (1) {
  131. uint8_t ledX[2] = { 0x00, 0x00 };
  132. /* get motor status: spinup, running or off */
  133. if (blmc.flags & FLAG_RUN_MASK) {
  134. if (blmc.flags & (FLAG_COM_SPINUP | FLAG_PWM_SPINUP))
  135. ledX[0] = LED_FAST;
  136. else
  137. ledX[0] = LED_SLOW;
  138. } else {
  139. ledX[0] = LED_ON;
  140. }
  141. /* soft errors (current limit, i2c timeout) */
  142. if (blmc.flags & FLAG_SOFTERR_MASK)
  143. ledX[1] = LED_ON;
  144. /* hard errors */
  145. if (blmc.flags & FLAG_HARDERR_MASK) {
  146. if (blmc.flags & FLAG_CURRENT_LIMIT) {
  147. ledX[0] = LED_OFF;
  148. ledX[1] = LED_FAST;
  149. } else if (blmc.flags & FLAG_UNDERVOLTAGE) {
  150. ledX[0] = LED_OFF;
  151. ledX[1] = LED_SLOW;
  152. } else if (blmc.flags & FLAG_SELFTEST_FAILED) {
  153. ledX[0] = LED_FAST;
  154. ledX[1] = LED_FAST;
  155. } else if (blmc.flags & FLAG_INVALID_EEPROM) {
  156. ledX[0] = LED_SLOW;
  157. ledX[1] = LED_SLOW;
  158. }
  159. }
  160. if (!(blmc.flags & (FLAG_SOFTERR_MASK | FLAG_HARDERR_MASK)))
  161. ledX[1] = LED_OFF;
  162. led[0] = ledX[0];
  163. led[1] = ledX[1];
  164. /* do a spinup from main loop (blocking for > 200ms) */
  165. if (blmc.flags & FLAG_COM_SPINUP)
  166. spinup();
  167. sleep_mode();
  168. };
  169. return 0;
  170. }