// Подключение бесколлекторного двигателя к AVR(с датчиками Холла)
#include <avr/io.h>
#include <avr/interrupt.h>
// Фаза A(Верхнее плечо)
#define AH_ON TCCR0A |= (1 << COM0A1);//D6 pin
#define AH_OFF TCCR0A &= ~(1 << COM0A1);//D6 pin
// Фаза A(Нижнее плечо)
#define AL_ON TCCR0A |= (1 << COM1A1);//D9 pin
#define AL_OFF TCCR0A &= ~(1 << COM1A1);//D9 pin
// Фаза B(Верхнее плечо)
#define BH_ON TCCR0A |= (1 << COM0B1);//D5 pin
#define BH_OFF TCCR0A &= ~(1 << COM0B1);//D5 pin
// Фаза B(Нижнее плечо)
#define BL_ON TCCR1A |= (1 << COM1B1);//D10 pin
#define BL_OFF TCCR1A &= ~(1 << COM1B1);//D10 pin
// Фаза C(Верхнее плечо)
#define CH_ON TCCR2A |= (1 << COM2B1);//D3 pin
#define CH_OFF TCCR2A &= ~(1 << COM2B1);//D3 pin
// Фаза C(Нижнее плечо)
#define CL_ON TCCR1C |= (1 << COM2A1);//D11 pin
#define CL_OFF TCCR1C &= ~(1 << COM2A1);//D11 pin
unsigned char speed;
// Обработчик внешнего прерывания
ISR(PCINT0_vect)
{
unsigned char position;
// Считываем значения датчиков
position = (PINB & ((1 << PB2)|(1 << PB1)|(1 << PB0)));//D8, D9, D10
switch(position) // Переключаем обмотки
{
/*case 5: AH_ON; AL_ON; BH_OFF; BL_OFF; CH_OFF; CL_ON; break;//A+ B- 010 5
case 1: AH_ON; AL_ON; BH_OFF; BL_ON; CH_OFF; CL_OFF; break;//A+ C- 011 1
case 3: AH_OFF; AL_ON; BH_ON; BL_ON; CH_OFF; CL_OFF; break;//B+ C- 001 3
case 2: AH_OFF; AL_OFF; BH_ON; BL_ON; CH_OFF; CL_ON; break;//A- B+ 101 2
case 6: AH_OFF; AL_OFF; BH_OFF; BL_ON; CH_ON; CL_ON; break;//A- C+ 100 6
case 4: AH_OFF; AL_ON; BH_OFF; BL_OFF; CH_ON; CL_ON; break;//B- C+ 110 4*/
case 5: AH_ON; AL_OFF; BH_OFF; BL_ON; CH_OFF; CL_OFF; break;//A+ B- 010 5
case 1: AH_ON; AL_OFF; BH_OFF; BL_OFF; CH_OFF; CL_ON; break;//A+ C- 011 1
case 3: AH_OFF; AL_OFF; BH_ON; BL_OFF; CH_OFF; CL_ON; break;//B+ C- 001 3
case 2: AH_OFF; AL_ON; BH_ON; BL_OFF; CH_OFF; CL_OFF; break;//A- B+ 101 2
case 6: AH_OFF; AL_ON; BH_OFF; BL_OFF; CH_ON; CL_OFF; break;//A- C+ 100 6
case 4: AH_OFF; AL_OFF; BH_OFF; BL_ON; CH_ON; CL_OFF; break;//B- C+ 110 4
}
PORTC = position;
}
// Функция изменения скорости
static void set_speed(unsigned char speed)
{
TIFR0 = TIFR0; // Очищаем флаг прерывания TC0
while( !(TIFR0 & (1<<TOV0))); // Ждем переполнения таймера
cli();
OCR0A = speed; // Изменяем ШИМ
OCR0B = speed;
OCR2B = speed;
sei();
}
int main( void )
{
TCCR0A |= (1 << COM0A1)|(0 << COM0A0)| // Сброс вывода OC0A при совпадении
(1 << COM0B1)|(0 << COM0B0)| // Сброс вывода OC0B при совпадении
(1 << WGM01)|(1 << WGM00); // Режим Fast PWM
TCCR0B |= (1 << CS00); // Предделитель CLK/1
TCCR2A |= (1 << COM2B1)|(0 << COM2B0)| // Сброс вывода OC2B при совпадении
(1 << WGM01)|(1 << WGM00); // Режим Fast PWM
TCCR2B |= (1 << CS20); // // Предделитель CLK/1
PCMSK0 |= (1 << PCINT2)|(1 << PCINT1)|(1 << PCINT0); // Активируем входы внешних прерываний
PCICR |= (1 << PCIE0); // Разрешаем прерывание по изменению состояния порта B
ADMUX |= (1 << MUX1)|(1 << MUX0); // Вход ADC3 A3
ADCSRA |= (1 << ADEN) | (1 << ADPS1); // Разрешаем АЦП, предделитель на 4
DDRC |= (1 << PC2)|(1 << PC1)|(1 << PC0); // Порт С - выход(светодиоды)
PORTC &= ~(1 << PC2)|(1 << PC1)|(1 << PC0);
DDRB |= (1 << PB5)|(1 << PB4)|(1 << PB0); // Кратковреммено подаем лог.1 на входы датчиков
PORTB |= (1 << PB5)|(1 << PB4)|(1 << PB0); // для первоначального запуска двигателя
PORTB &= ~(1 << PB5)|(1 << PB4)|(1 << PB0);
DDRB = 0x00; // Порт B - вход
sei(); // Глобально разрешаем прерывания
DDRD = 0xFF; // Порт D - выход
while(1)
{
ADCSRA |= (1 << ADSC); // Запускаем преобразование АЦП
while ( ADCSRA & (1 << ADSC) ); // Ждем окончания преобразования
speed = ADC/4; // Считываем АЦП
set_speed(speed); // Изменяем скорость
}
}