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.
 
 

114 lines
3.3 KiB

/***************************************************************************
* Copyright (C) 09/2007 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; version 2 of the License, *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/*
* Application:
* LED_GN blinking -> motor stop
* LED_GN on -> motor running
* LED_GN on & LED_RT blinking -> pwm soft limit
* LED_GN off & LED_RT blinking -> current to high / undervoltage
*
* startup:
* - selftest
*
* cmdloop:
* - set motor (pwm)
* - get status (motor speed, voltage, current)
* - reboot (with cookie)
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "main.h"
#include "blmc.h"
extern struct blmc_ blmc;
ISR(TIMER0_OVF_vect)
{
static uint8_t timer0_cnt = 0;
static uint8_t adc_chan = SENSE_CURRENT;
/* Come back in 20ms */
TCNT0 = 0xFF - 156;
/* current-limiting */
setpwm(blmc.pwm);
uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp2;
blmc.rpm_tmp2 = blmc.rpm_tmp;
/* too low rpm while running -> do a spinup */
if (diff < 0x8 && blmc.flags == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL))
blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
timer0_cnt++;
if (timer0_cnt == 50) {
timer0_cnt = 0;
blmc.rpm = blmc.rpm_tmp;
blmc.rpm_tmp = 0;
}
/* trigger adc by hand when not running */
if (!(blmc.flags & FLAG_COM_NORMAL)) {
trigger_adc(adc_chan);
if (adc_chan == SENSE_CURRENT)
adc_chan = SENSE_VOLTAGE;
else
adc_chan = SENSE_CURRENT;
}
}
int main(void)
{
DDRB = PHASE_H_MASK | LED_RT | LED_GN;
DDRD = PHASE_L_MASK;
PORTB = LED_GN;
PORTD = 0x00;
/* timer0: running with F_CPU/1024 */
TCCR0 = (1<<CS02) | (1<<CS00);
/* timer1: running with F_CPU, 8bit Fast PWM (32kHz) */
TCCR1B = (1<<CS10);// | (1<<WGM12);
TCCR1A = (1<<WGM10);
/* timer2: running with F_CPU, 8bit Fast PWM (32kHz) */
TCCR2 = (1<<WGM20) | (1<<CS20);// | (1<<WGM21);
/* enable Timer0 OVF Interrupt */
TIMSK = (1<<TOIE0); // | (1<<OCIE2); // | (1<<TOIE2)
/* Enable Analog Comparator Multiplexer */
SFIOR |= (1<<ACME);
/* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
sei();
while (1) {
if (blmc.flags & FLAG_COM_SPINUP)
spinup();
};
return 0;
}