Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
27b32bd462 | |||
d755d1382e | |||
f35be86a71 | |||
e473216eba | |||
e4f6fd2d36 | |||
d05f1de3b1 | |||
efd7ebbe36 | |||
77fa66a6d9 | |||
639c0e9bb9 |
4
Makefile
4
Makefile
@ -1,6 +1,6 @@
|
|||||||
PRG = blmc
|
PRG = blmc
|
||||||
OBJ = blmc.o eeprom.o i2c-slave.o main.o
|
OBJ = blmc.o eeprom.o i2c-slave.o main.o
|
||||||
MCU_TARGET = atmega8
|
MCU_TARGET = atmega88
|
||||||
OPTIMIZE = -Os
|
OPTIMIZE = -Os
|
||||||
|
|
||||||
DEFS =
|
DEFS =
|
||||||
@ -61,4 +61,4 @@ ebin: $(PRG)_eeprom.bin
|
|||||||
|
|
||||||
install: text
|
install: text
|
||||||
# uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex
|
# uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex
|
||||||
avrdude -p m8 -c butterfly -b 115200 -P /dev/ttyUSB1 -u -e -V -U flash:w:$(PRG).hex
|
avrdude -p m88 -c butterfly -b 115200 -u -e -V -U flash:w:$(PRG).hex
|
||||||
|
9
README
9
README
@ -1,8 +1,11 @@
|
|||||||
blmc v1
|
blmc v2
|
||||||
=======
|
=======
|
||||||
|
|
||||||
An AVR mega8 based brushless motor controller.
|
An AVR mega88/168 based brushless motor controller.
|
||||||
- SW/HW and i2c protocol are *NOT* compatible with H+I blctrl!
|
|
||||||
- must run with TWIBOOT as bootloader to get own i2c address
|
- must run with TWIBOOT as bootloader to get own i2c address
|
||||||
- spinup parameters in EEPROM
|
- spinup parameters in EEPROM
|
||||||
- extended i2c protocol
|
- extended i2c protocol
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- remove C1/C3/C6 and do "timed" commutation
|
||||||
|
- replace C11 with smaller value / remove it
|
||||||
|
120
blmc.c
120
blmc.c
@ -31,67 +31,86 @@ static uint8_t next_sense;
|
|||||||
|
|
||||||
void trigger_adc(uint8_t channel)
|
void trigger_adc(uint8_t channel)
|
||||||
{
|
{
|
||||||
/* Disable Analog Comperator */
|
/* Disable Analog Comperator Interrupt */
|
||||||
ACSR &= ~(1<<ACIE);
|
TIMSK1 &= ~(1<<ICIE1);
|
||||||
|
|
||||||
/* set channel (Internal reference, 2.56V) */
|
/* set channel (external reference, 5V) */
|
||||||
ADMUX = (1<<REFS1) | (1<<REFS0) | channel;
|
ADMUX = (0<<REFS1) | (0<<REFS0) | channel;
|
||||||
|
|
||||||
/* turn on ADC with interrupts, start conversion with 1/32 of F_CPU */
|
/*
|
||||||
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADIF)| (1<<ADPS2) | (1<<ADPS0);
|
* turn on ADC with interrupts
|
||||||
|
* start conversion with 1/32 of F_CPU
|
||||||
|
* 1/250kHz * 25 => 100us conversion time
|
||||||
|
*/
|
||||||
|
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADIF)| (1<<ADPS2) | (0<<ADPS0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void next_phase(void)
|
static void next_phase(void)
|
||||||
{
|
{
|
||||||
static uint8_t phase;
|
static uint8_t phase;
|
||||||
static uint8_t phase_adc;
|
static uint8_t phase_adc;
|
||||||
|
|
||||||
/* Disable Analog Comperator */
|
/* Disable Analog Comperator Interrupt */
|
||||||
ACSR &= ~(1<<ACIE);
|
TIMSK1 &= ~(1<<ICIE1);
|
||||||
|
|
||||||
TCNT1 = 0x00;
|
|
||||||
TCNT2 = 0x00;
|
|
||||||
|
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case 0: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_B_L;
|
case 0: /* A: PWM, B: LOW, C: SENSE => disable EN_C, disable PWM_B, enable EN_B */
|
||||||
TCCR1A = (TCCR1A & ~(1<<COM1B1)) | (1<<COM1A1);
|
PORTD &= ~PHASE_C_EN;
|
||||||
TCCR2 &= ~(1<<COM21);
|
TCCR0A &= ~PHASE_B_OC;
|
||||||
ACSR = (1<<ACIS1);
|
PORTD |= PHASE_B_EN;
|
||||||
|
|
||||||
|
/* C: falling edge */
|
||||||
|
TCCR1B &= ~(1<<ICES1);
|
||||||
next_sense = SENSE_C;
|
next_sense = SENSE_C;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_B_L;
|
case 1: /* A: SENSE, B: LOW, C: PWM => disable EN_A, enable PWM_C, enable EN_C */
|
||||||
TCCR1A &= ~((1<<COM1A1) | (1<<COM1B1));
|
PORTB &= ~PHASE_A_EN;
|
||||||
TCCR2 |= (1<<COM21);
|
TCCR2A |= PHASE_C_OC;
|
||||||
ACSR = (1<<ACIS1) | (1<<ACIS0);
|
PORTD |= PHASE_C_EN;
|
||||||
|
|
||||||
|
/* A: rising edge */
|
||||||
|
TCCR1B |= (1<<ICES1);
|
||||||
next_sense = SENSE_A;
|
next_sense = SENSE_A;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_A_L;
|
case 2: /* A: LOW, B: SENSE, C: PWM => disable EN_B, disable PWM_A, enable EN_A */
|
||||||
TCCR1A &= ~((1<<COM1A1) | (1<<COM1B1));
|
PORTD &= ~PHASE_B_EN;
|
||||||
TCCR2 |= (1<<COM21);
|
TCCR2A &= ~PHASE_A_OC;
|
||||||
ACSR = (1<<ACIS1);
|
PORTB |= PHASE_A_EN;
|
||||||
|
|
||||||
|
/* B: falling edge */
|
||||||
|
TCCR1B &= ~(1<<ICES1);
|
||||||
next_sense = SENSE_B;
|
next_sense = SENSE_B;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_A_L;
|
case 3: /* A: LOW, B: PWM, C: SENSE => disable EN_C, enable PWM_B, enable EN_B */
|
||||||
TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1B1);
|
PORTD &= ~PHASE_C_EN;
|
||||||
TCCR2 &= ~(1<<COM21);
|
TCCR0A |= PHASE_B_OC;
|
||||||
ACSR = (1<<ACIS1) | (1<<ACIS0);
|
PORTD |= PHASE_B_EN;
|
||||||
|
|
||||||
|
/* C: rising edge */
|
||||||
|
TCCR1B |= (1<<ICES1);
|
||||||
next_sense = SENSE_C;
|
next_sense = SENSE_C;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_C_L;
|
case 4: /* A: SENSE, B: PWM, C: LOW => disable EN_A, disable PWM_C, enable EN_C */
|
||||||
TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1B1);
|
PORTB &= ~PHASE_A_EN;
|
||||||
TCCR2 &= ~(1<<COM21);
|
TCCR2A &= ~PHASE_C_OC;
|
||||||
ACSR = (1<<ACIS1);
|
PORTD |= PHASE_C_EN;
|
||||||
|
|
||||||
|
/* A: falling edge */
|
||||||
|
TCCR1B &= ~(1<<ICES1);
|
||||||
next_sense = SENSE_A;
|
next_sense = SENSE_A;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_C_L;
|
case 5: /* A: PWM, B: SENSE, C: LOW => disable EN_B, enable PWM_A, enable EN_A */
|
||||||
TCCR1A = (TCCR1A & ~(1<<COM1B1)) | (1<<COM1A1);
|
PORTD &= ~PHASE_B_EN;
|
||||||
TCCR2 &= ~(1<<COM21);
|
TCCR2A |= PHASE_A_OC;
|
||||||
ACSR = (1<<ACIS1) | (1<<ACIS0);
|
PORTB |= PHASE_A_EN;
|
||||||
|
|
||||||
|
/* B: rising edge */
|
||||||
|
TCCR1B |= (1<<ICES1);
|
||||||
next_sense = SENSE_B;
|
next_sense = SENSE_B;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -114,8 +133,10 @@ void next_phase(void)
|
|||||||
ADMUX = next_sense;
|
ADMUX = next_sense;
|
||||||
|
|
||||||
/* enable Analog Comparator with Interrupts */
|
/* enable Analog Comparator with Interrupts */
|
||||||
if (blmc.flags & FLAG_COM_NORMAL)
|
if (blmc.flags & FLAG_COM_NORMAL) {
|
||||||
ACSR |= (1<<ACIE) | (1<<ACI);
|
TIFR1 |= (1<<ICF1);
|
||||||
|
TIMSK1 |= (1<<ICIE1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
phase++;
|
phase++;
|
||||||
@ -207,12 +228,21 @@ void setpwm(uint8_t pwm)
|
|||||||
if (pwm > params.pwm_max)
|
if (pwm > params.pwm_max)
|
||||||
pwm = params.pwm_max;
|
pwm = params.pwm_max;
|
||||||
|
|
||||||
OCR1A = pwm;
|
OCR0B = pwm;
|
||||||
OCR1B = pwm;
|
OCR2A = pwm;
|
||||||
OCR2 = pwm;
|
OCR2B = pwm;
|
||||||
|
|
||||||
|
/* disable PWM signales, enable all drivers -> brake */
|
||||||
|
if (pwm == 0) {
|
||||||
|
TCCR0A &= ~PHASE_B_OC;
|
||||||
|
TCCR2A &= ~(PHASE_A_OC | PHASE_C_OC);
|
||||||
|
|
||||||
|
PORTB |= PHASE_A_EN;
|
||||||
|
PORTD |= (PHASE_B_EN | PHASE_C_EN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(ANA_COMP_vect)
|
ISR(TIMER1_CAPT_vect)
|
||||||
{
|
{
|
||||||
next_phase();
|
next_phase();
|
||||||
}
|
}
|
||||||
@ -232,8 +262,10 @@ ISR(ADC_vect)
|
|||||||
ADCSRA = 0x00;
|
ADCSRA = 0x00;
|
||||||
|
|
||||||
/* enable Analog Comparator with Interrupts */
|
/* enable Analog Comparator with Interrupts */
|
||||||
if (blmc.flags & FLAG_COM_NORMAL)
|
if (blmc.flags & FLAG_COM_NORMAL) {
|
||||||
ACSR |= (1<<ACIE) | (1<<ACI);
|
TIFR1 |= (1<<ICF1);
|
||||||
|
TIMSK1 |= (1<<ICIE1);
|
||||||
|
}
|
||||||
|
|
||||||
if (channel == SENSE_CURRENT) {
|
if (channel == SENSE_CURRENT) {
|
||||||
current_tmp += value;
|
current_tmp += value;
|
||||||
|
2
blmc.h
2
blmc.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef _BLMC_H_
|
#ifndef _BLMC_H_
|
||||||
#define _BLMC_H_
|
#define _BLMC_H_
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
#define FLAG_RUN_MASK 0x00F
|
#define FLAG_RUN_MASK 0x00F
|
||||||
#define FLAG_PWM_SPINUP 0x001
|
#define FLAG_PWM_SPINUP 0x001
|
||||||
#define FLAG_PWM_NORMAL 0x002
|
#define FLAG_PWM_NORMAL 0x002
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
BIN
eagle/blmc-v2-bot.png
Normal file
BIN
eagle/blmc-v2-bot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
eagle/blmc-v2-sch.png
Normal file
BIN
eagle/blmc-v2-sch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
eagle/blmc-v2-top.png
Normal file
BIN
eagle/blmc-v2-top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
eagle/blmc.brd
Normal file
BIN
eagle/blmc.brd
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
10
eeprom.c
10
eeprom.c
@ -16,11 +16,12 @@
|
|||||||
* Free Software Foundation, Inc., *
|
* Free Software Foundation, Inc., *
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
#include <util/crc16.h>
|
#include <util/crc16.h>
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
|
|
||||||
static const struct ee_param defaults = DEFAULT_PARAMETERS;
|
static struct ee_param defaults PROGMEM = DEFAULT_PARAMETERS;
|
||||||
|
|
||||||
struct ee_param params;
|
struct ee_param params;
|
||||||
struct ee_param params_in_eeprom EEMEM = DEFAULT_PARAMETERS;
|
struct ee_param params_in_eeprom EEMEM = DEFAULT_PARAMETERS;
|
||||||
@ -48,12 +49,7 @@ uint8_t read_parameters(void)
|
|||||||
crc = _crc_ccitt_update(crc, *tmp++);
|
crc = _crc_ccitt_update(crc, *tmp++);
|
||||||
|
|
||||||
if (crc != 0x0000) {
|
if (crc != 0x0000) {
|
||||||
i = sizeof(struct ee_param);
|
memcpy_P(¶ms, &defaults, sizeof(struct ee_param));
|
||||||
uint8_t *src = (uint8_t *)&defaults;
|
|
||||||
uint8_t *dst = (uint8_t *)¶ms;
|
|
||||||
while (i--)
|
|
||||||
*dst++ = *src++;
|
|
||||||
|
|
||||||
write_parameters();
|
write_parameters();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
9
eeprom.h
9
eeprom.h
@ -22,16 +22,17 @@ struct ee_param {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_PARAMETERS { \
|
#define DEFAULT_PARAMETERS { \
|
||||||
.spinup_ticks = 1000, \
|
.spinup_ticks = 2000, \
|
||||||
.spinup_tick = 25, \
|
.spinup_tick = 24, \
|
||||||
.spinup_step = 24, \
|
.spinup_step = 4, \
|
||||||
.spinup_wait = 10, \
|
.spinup_wait = 10, \
|
||||||
.spinup_pwm = 0x0f, \
|
.spinup_pwm = 25, \
|
||||||
.pwm_min = 0x08, \
|
.pwm_min = 0x08, \
|
||||||
.pwm_max = 0xff, \
|
.pwm_max = 0xff, \
|
||||||
.current_limit = 120, \
|
.current_limit = 120, \
|
||||||
.current_max = 0x3ff, \
|
.current_max = 0x3ff, \
|
||||||
.voltage_min = 0x000, \
|
.voltage_min = 0x000, \
|
||||||
|
.crc16 = 0xDB76, \
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t read_parameters(void);
|
uint8_t read_parameters(void);
|
||||||
|
51
i2c-slave.c
51
i2c-slave.c
@ -61,20 +61,19 @@ extern struct ee_param params;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const static uint8_t info[16] = "blmc m8-v1.2 ";
|
const static uint8_t info[16] = "blctrl m88-v2.0";
|
||||||
|
|
||||||
ISR(TWI_vect)
|
ISR(TWI_vect)
|
||||||
{
|
{
|
||||||
static uint8_t cmd;
|
static uint8_t cmd;
|
||||||
static uint8_t bcnt;
|
static uint8_t bcnt;
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
uint8_t ack = (1<<TWEA);
|
|
||||||
|
|
||||||
switch (TWSR & 0xF8) {
|
switch (TWSR & 0xF8) {
|
||||||
/* SLA + W received, ACK returned -> receive Data and ACK */
|
/* SLA + W received, ACK returned -> receive Data and ACK */
|
||||||
case 0x60:
|
case 0x60:
|
||||||
bcnt = 0;
|
bcnt = 0;
|
||||||
TWCR |= (1<<TWINT) | (1<<TWEA);
|
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* prev. SLA + W, data received, ACK returned -> receive Data and ACK */
|
/* prev. SLA + W, data received, ACK returned -> receive Data and ACK */
|
||||||
@ -103,9 +102,6 @@ ISR(TWI_vect)
|
|||||||
case CMD_SWITCH_APPLICATION:
|
case CMD_SWITCH_APPLICATION:
|
||||||
if (data == BOOTTYPE_BOOTLOADER) {
|
if (data == BOOTTYPE_BOOTLOADER) {
|
||||||
wdt_enable(WDTO_15MS);
|
wdt_enable(WDTO_15MS);
|
||||||
|
|
||||||
} else {
|
|
||||||
ack = (0<<TWEA);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -113,14 +109,10 @@ ISR(TWI_vect)
|
|||||||
bcnt++;
|
bcnt++;
|
||||||
if (data == MEMTYPE_PARAMETERS) {
|
if (data == MEMTYPE_PARAMETERS) {
|
||||||
cmd = CMD_WRITE_PARAMETERS;
|
cmd = CMD_WRITE_PARAMETERS;
|
||||||
|
|
||||||
} else {
|
|
||||||
ack = (0<<TWEA);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ack = (0<<TWEA);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -136,21 +128,16 @@ ISR(TWI_vect)
|
|||||||
((uint8_t *)¶ms)[bcnt++ -4] = data;
|
((uint8_t *)¶ms)[bcnt++ -4] = data;
|
||||||
if (bcnt == sizeof(params)) {
|
if (bcnt == sizeof(params)) {
|
||||||
write_parameters();
|
write_parameters();
|
||||||
ack = (0<<TWEA);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ack = (0<<TWEA);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ack == 0x00)
|
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
|
||||||
bcnt = 0;
|
|
||||||
|
|
||||||
TWCR |= (1<<TWINT) | ack;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* SLA+R received, ACK returned -> send data */
|
/* SLA+R received, ACK returned -> send data */
|
||||||
@ -161,16 +148,32 @@ ISR(TWI_vect)
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CMD_WAIT:
|
case CMD_WAIT:
|
||||||
switch (bcnt++) {
|
switch (bcnt++) {
|
||||||
case 0:
|
case 0: data = blmc.pwm - blmc.pwm_limit;
|
||||||
data = blmc.current & 0xFF;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1: data = blmc.pwm;
|
||||||
data = 0xFF - blmc.pwm_limit;
|
break;
|
||||||
|
|
||||||
|
case 2: data = (blmc.rpm & 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: data = (blmc.rpm >> 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: data = (blmc.current & 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: data = (blmc.current >> 8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: data = (blmc.voltage & 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: data = (blmc.voltage >> 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
data = 0xFF;
|
data = 0x00;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -192,19 +195,19 @@ ISR(TWI_vect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TWDR = data;
|
TWDR = data;
|
||||||
TWCR |= (1<<TWINT) | (1<<TWEA);
|
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* STOP or repeated START */
|
/* STOP or repeated START */
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
/* Data transmitted, NACK returned */
|
/* Data transmitted, NACK returned */
|
||||||
case 0xC0:
|
case 0xC0:
|
||||||
TWCR |= (1<<TWINT) | (1<<TWEA);
|
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* failsave -> reset Hardware */
|
/* failsave -> reset Hardware */
|
||||||
default:
|
default:
|
||||||
TWCR |= (1<<TWINT) | (1<<TWSTO) | (1<<TWEA);
|
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWSTO) | (1<<TWEA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
main.c
60
main.c
@ -46,13 +46,13 @@ extern struct blmc_ blmc;
|
|||||||
|
|
||||||
static uint8_t led[2];
|
static uint8_t led[2];
|
||||||
|
|
||||||
ISR(TIMER0_OVF_vect)
|
ISR(TIMER1_COMPB_vect)
|
||||||
{
|
{
|
||||||
static uint8_t timer0_cnt = 0;
|
static uint8_t rpm_cnt = 0;
|
||||||
static uint8_t adc_chan = SENSE_CURRENT;
|
static uint8_t adc_chan = SENSE_CURRENT;
|
||||||
|
|
||||||
/* Come back in 20ms */
|
/* Come back in 20ms */
|
||||||
TCNT0 = 0xFF - 156;
|
OCR1B = TCNT1 + 20000;
|
||||||
|
|
||||||
/* commutations during last 20ms */
|
/* commutations during last 20ms */
|
||||||
uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old;
|
uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old;
|
||||||
@ -64,7 +64,7 @@ ISR(TIMER0_OVF_vect)
|
|||||||
blmc.flags &= ~(FLAG_RUN_MASK);
|
blmc.flags &= ~(FLAG_RUN_MASK);
|
||||||
blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
|
blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
/* no i2c cmd in the last 20ms */
|
/* no i2c cmd in the last 20ms */
|
||||||
if (!(blmc.flags & FLAG_I2C_ACTIVE)) {
|
if (!(blmc.flags & FLAG_I2C_ACTIVE)) {
|
||||||
/* already in i2c timeout, turn off motor */
|
/* already in i2c timeout, turn off motor */
|
||||||
@ -76,7 +76,7 @@ ISR(TIMER0_OVF_vect)
|
|||||||
} else {
|
} else {
|
||||||
blmc.flags &= ~FLAG_I2C_TIMEOUT;
|
blmc.flags &= ~FLAG_I2C_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
blmc.flags &= ~FLAG_I2C_ACTIVE;
|
blmc.flags &= ~FLAG_I2C_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,9 @@ ISR(TIMER0_OVF_vect)
|
|||||||
setpwm(blmc.pwm);
|
setpwm(blmc.pwm);
|
||||||
|
|
||||||
/* calc rpm every second */
|
/* calc rpm every second */
|
||||||
timer0_cnt++;
|
rpm_cnt++;
|
||||||
if (timer0_cnt == 50) {
|
if (rpm_cnt == 50) {
|
||||||
timer0_cnt = 0;
|
rpm_cnt = 0;
|
||||||
|
|
||||||
blmc.rpm = blmc.rpm_tmp;
|
blmc.rpm = blmc.rpm_tmp;
|
||||||
blmc.rpm_tmp = 0;
|
blmc.rpm_tmp = 0;
|
||||||
@ -100,7 +100,6 @@ ISR(TIMER0_OVF_vect)
|
|||||||
else
|
else
|
||||||
adc_chan = SENSE_CURRENT;
|
adc_chan = SENSE_CURRENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* led blink timer */
|
/* led blink timer */
|
||||||
static uint8_t led_timer = 0;
|
static uint8_t led_timer = 0;
|
||||||
led_timer = (led_timer +1) & 0x1F;
|
led_timer = (led_timer +1) & 0x1F;
|
||||||
@ -126,29 +125,49 @@ ISR(TIMER0_OVF_vect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For newer devices (mega88) the watchdog timer remains active even after a
|
||||||
|
* system reset. So disable it as soon as possible.
|
||||||
|
* automagically called on startup
|
||||||
|
*/
|
||||||
|
void get_mcusr(void) __attribute__((naked, section(".init3")));
|
||||||
|
void get_mcusr(void)
|
||||||
|
{
|
||||||
|
MCUSR = 0;
|
||||||
|
WDTCSR = (1<<WDCE) | (0<<WDE);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
DDRB = PHASE_H_MASK | LED_RT | LED_GN;
|
DDRB = PHASE_A_EN | PHASE_A_PWM | LED_RT | LED_GN;
|
||||||
DDRD = PHASE_L_MASK;
|
DDRD = PHASE_B_EN | PHASE_B_PWM | PHASE_C_EN | PHASE_C_PWM;
|
||||||
|
|
||||||
PORTB = 0x00;
|
PORTB = 0x00;
|
||||||
PORTD = 0x00;
|
PORTD = 0x00;
|
||||||
|
|
||||||
/* timer0: running with F_CPU/1024 */
|
/* timer0: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
|
||||||
TCCR0 = (1<<CS02) | (1<<CS00);
|
TCCR0A = (1<<WGM00);
|
||||||
|
TCCR0B = (1<<CS00);
|
||||||
|
|
||||||
/* timer1: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
|
/* timer1: running with F_CPU/8 */
|
||||||
TCCR1B = (1<<CS10);
|
TCCR1B = (1<<CS11) | (1<<ICNC1);
|
||||||
TCCR1A = (1<<WGM10);
|
|
||||||
|
|
||||||
/* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
|
/* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
|
||||||
TCCR2 = (1<<WGM20) | (1<<CS20);
|
TCCR2A = (1<<WGM20);
|
||||||
|
TCCR2B = (1<<CS20);
|
||||||
|
|
||||||
/* enable Timer0 OVF Interrupt */
|
/* sync PWM timers */
|
||||||
TIMSK = (1<<TOIE0);
|
GTCCR = (1<<TSM) | (1<<PSRASY) | (1<<PSRSYNC);
|
||||||
|
TCNT0 = 0x00;
|
||||||
|
TCNT2 = 0x00;
|
||||||
|
GTCCR = (0<<TSM);
|
||||||
|
|
||||||
|
/* enable Timer1 OVF Interrupt */
|
||||||
|
TIMSK1 = (1<<OCIE1B);
|
||||||
|
|
||||||
/* Enable Analog Comparator Multiplexer */
|
/* Enable Analog Comparator Multiplexer */
|
||||||
SFIOR |= (1<<ACME);
|
ADCSRB |= (1<<ACME);
|
||||||
|
ACSR |= (1<<ACIC);
|
||||||
|
|
||||||
/* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */
|
/* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */
|
||||||
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
|
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
|
||||||
@ -210,5 +229,6 @@ int main(void)
|
|||||||
|
|
||||||
sleep_mode();
|
sleep_mode();
|
||||||
};
|
};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
26
main.h
26
main.h
@ -9,21 +9,23 @@
|
|||||||
#define LED_RT (1<<PORTB4)
|
#define LED_RT (1<<PORTB4)
|
||||||
#define LED_GN (1<<PORTB5)
|
#define LED_GN (1<<PORTB5)
|
||||||
|
|
||||||
#define PHASE_A_H (1<<PORTB1)
|
#define PHASE_A_EN (1<<PORTB2)
|
||||||
#define PHASE_B_H (1<<PORTB2)
|
#define PHASE_A_PWM (1<<PORTB3)
|
||||||
#define PHASE_C_H (1<<PORTB3)
|
#define PHASE_A_OC (1<<COM2A1)
|
||||||
#define PHASE_H_MASK (PHASE_A_H | PHASE_B_H | PHASE_C_H)
|
|
||||||
|
|
||||||
#define PHASE_A_L (1<<PORTD4)
|
#define PHASE_B_EN (1<<PORTD7)
|
||||||
#define PHASE_B_L (1<<PORTD3)
|
#define PHASE_B_PWM (1<<PORTD5)
|
||||||
#define PHASE_C_L (1<<PORTD2)
|
#define PHASE_B_OC (1<<COM0B1)
|
||||||
#define PHASE_L_MASK (PHASE_A_L | PHASE_B_L | PHASE_C_L)
|
|
||||||
|
#define PHASE_C_EN (1<<PORTD4)
|
||||||
|
#define PHASE_C_PWM (1<<PORTD3)
|
||||||
|
#define PHASE_C_OC (1<<COM2B1)
|
||||||
|
|
||||||
#define SENSE_A 0
|
#define SENSE_A 0
|
||||||
#define SENSE_B 1
|
#define SENSE_B 2
|
||||||
#define SENSE_C 2
|
#define SENSE_C 1
|
||||||
|
|
||||||
#define SENSE_VOLTAGE 3
|
#define SENSE_VOLTAGE 7
|
||||||
#define SENSE_CURRENT 6
|
#define SENSE_CURRENT 3
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user