512 lines
24 KiB
C
Executable File
512 lines
24 KiB
C
Executable File
/*
|
||
* USB rotor card
|
||
*
|
||
* Created: 30.05.2022
|
||
* Update: 11.06.2022 00:34:00
|
||
* Author : R5CA
|
||
* Support only GS232B 450deg
|
||
*/
|
||
#include <avr/io.h>
|
||
#include <util/delay.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <avr/eeprom.h>
|
||
#include <avr/pgmspace.h>
|
||
#include <avr/wdt.h>
|
||
#include <avr/interrupt.h>
|
||
|
||
#define BAUD 9600
|
||
#define MYUBRR F_CPU/16/BAUD-1
|
||
|
||
volatile uint8_t uartRXBuf[16]; // Буфер для данных принятых по UART
|
||
volatile uint8_t uartRXBufNum = 0; // Кол-во принятых байт по UART
|
||
volatile uint8_t uartRXC = 0; // Флаг окончания приема данных по UART
|
||
|
||
#define ROTOR_DDR DDRD
|
||
#define ROTOR_PORT PORTD
|
||
#define ROTOR_CW PD5
|
||
#define ROTOR_CCW PD6
|
||
#define ROTOR_AZ_IN 0 // Канал АЦП измерения азимута
|
||
#define ROTOR_SPEED_DDR DDRB // DDR регулировки скорости
|
||
#define ROTOR_SPEED_PORT PORTB // Порт регулировки скорости
|
||
#define ROTOR_SPEED_PINNUM PB3 // Номер пина регулировки скорости(обязательно OC2A)
|
||
|
||
#define STOP 0
|
||
#define SLOW_START 1
|
||
#define ROTARY 2
|
||
#define SLOW_DOWN 3
|
||
|
||
#define SLOW_DOWN_AZ 20 // Расстояние начала плавной остановки
|
||
|
||
uint16_t EEMEM EEPcal0 = 0; // EEProm значение калибровки 0 градусов
|
||
uint16_t EEMEM EEPcal90 = 0; // EEProm значение калибровки 90 градусов
|
||
uint16_t EEMEM EEPcal180 = 0; // EEProm значение калибровки 180 градусов
|
||
uint16_t EEMEM EEPcal270 = 0; // EEProm значение калибровки 270 градусов
|
||
uint16_t EEMEM EEPcal360 = 0; // EEProm значение калибровки 360 градусов
|
||
uint16_t EEMEM EEPcal450 = 0; // EEProm значение калибровки 450 градусов
|
||
uint8_t EEMEM EEPspeed = 128; // EEProm скорость вращения
|
||
|
||
uint16_t cal0 = 0; // Значение калибровки 0 градусов
|
||
uint16_t cal90 = 0; // Значение калибровки 90 градусов
|
||
uint16_t cal180 = 0; // Значение калибровки 180 градусов
|
||
uint16_t cal270 = 0; // Значение калибровки 270 градусов
|
||
uint16_t cal360 = 0; // Значение калибровки 360 градусов
|
||
uint16_t cal450 = 0; // Значение калибровки 450 градусов
|
||
|
||
uint8_t rot_cw = 0; // Вращение по часовой
|
||
uint8_t rot_ccw = 0; // Вращение против часовой
|
||
|
||
volatile uint8_t timer = 0; // Переменная таймера задержки плавного старта/остановки
|
||
volatile uint16_t timer2 = 0; // Переменная таймера
|
||
|
||
void uartbuf_zero(void) // Обнуление буфера UART
|
||
{
|
||
for(uint8_t i=0; i<16; i++) // Обнуление буфера UART
|
||
{
|
||
uartRXBuf[i] = 0x00; // Обнуление буфера UART
|
||
}
|
||
}
|
||
|
||
void usart_init(unsigned int ubrr) // Инициализация USART
|
||
{
|
||
UBRR0H = (unsigned char) (ubrr >> 8); // Установка скорости
|
||
UBRR0L = (unsigned char) ubrr; // Установка скорости
|
||
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // Включаем приемник, передатчик и прерывание по приходу байта
|
||
UCSR0C = (1<<UCSZ00)|(1<<UCSZ01); //
|
||
}
|
||
|
||
void usart_tx(uint8_t data) // Передача байта по USART
|
||
{
|
||
while (!(UCSR0A & (1<<UDRE0))){}; // Проверяем ушел-ли предыдущий байт
|
||
UDR0 = data; // отправляем байт
|
||
}
|
||
|
||
static int uart_putchar(char c, FILE *stream);
|
||
|
||
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
||
|
||
static int uart_putchar(char c, FILE *stream)
|
||
{
|
||
if (c == '\n')
|
||
uart_putchar('\r', stream);
|
||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||
UDR0 = c;
|
||
return 0;
|
||
}
|
||
|
||
ISR(USART_RX_vect) // Прерывание по приходу байта в USART
|
||
{
|
||
uartRXBuf[uartRXBufNum] = UDR0; // Чтение байта
|
||
if(uartRXBuf[uartRXBufNum] == 0x0D) // Если пришел символ конца строки
|
||
{
|
||
uartRXBuf[uartRXBufNum] = 0x00; // То заменяем его на 0х00
|
||
uartRXC = 1; // Ставим флаг замершения приема строки
|
||
}
|
||
else if(uartRXBuf[uartRXBufNum] == 0x18) // Если надо в бут
|
||
{
|
||
wdt_disable(); // Ребутимся
|
||
wdt_enable(WDTO_15MS); // Ребутимся
|
||
while(1) {}; // Ребутимся
|
||
}
|
||
uartRXBufNum++; // Счетчик принятых символов
|
||
}
|
||
|
||
void adc_init(void) // Инициализация АЦП
|
||
{
|
||
ADMUX |= (1<<REFS0); // Опора - AVCC + конденсатор на AREF
|
||
ADCSRA |= (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1); // Включаем АЦП и устанавливаем делитель тактовой частоты
|
||
}
|
||
|
||
|
||
uint16_t adc_read(uint8_t ch) // Чтение значения АЦП
|
||
{
|
||
ch &= 0b00000111; // Выбор канала АЦП
|
||
ADMUX = (ADMUX & 0xF8)|ch; // Выбор канала АЦП
|
||
ADCSRA |= (1<<ADSC); // Старт измерения
|
||
while(ADCSRA & (1<<ADSC)){}; // Ожидание завершения измерения
|
||
return (ADC); // Возврат измеренного значения
|
||
}
|
||
|
||
uint16_t az_raw(void) // Определение текущего азимута
|
||
{
|
||
uint16_t adc_val; // Переменная для хранения значения АЦП
|
||
adc_val = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
int16_t az_raw_data; // Переменная для хранения азимута
|
||
az_raw_data = lround((adc_val - cal0)*450.0/(cal450-cal0)); // Приблизительный расчет по полной шкале 0-450
|
||
if(adc_val <= cal0) // Если считанное значение АЦП меньше 0-ой калибровки
|
||
{
|
||
return 0; // То возвращаем 0
|
||
}
|
||
else if(adc_val >= cal450) // Если считанное значение АЦП больше 450-ой калибровки
|
||
{
|
||
return 450; // То возвращаем 450
|
||
}
|
||
else if(az_raw_data > 0 && az_raw_data < 90) // Если приблизительный азимут от 0 до 90 градусов
|
||
{
|
||
az_raw_data = lround((adc_val - cal0)*90.0/(cal90-cal0)); // То делаем уточненный расчет по части шкалы в 90 градусов(0-90) с использованием дополнительных калибровок
|
||
return az_raw_data; // Возвращаем значчение азимута
|
||
}
|
||
else if(az_raw_data >= 90 && az_raw_data < 180) // Если приблизительный азимут от 90 до 180 градусов
|
||
{
|
||
az_raw_data = lround(90.0+((adc_val - cal90)*90.0/(cal180-cal90))); // То делаем уточненный расчет по части шкалы в 90 градусов(90-180) с использованием дополнительных калибровок
|
||
return az_raw_data; // Возвращаем значчение азимута
|
||
}
|
||
else if(az_raw_data >= 180 && az_raw_data < 270) // Если приблизительный азимут от 180 до 270 градусов
|
||
{
|
||
az_raw_data = lround(180.0+((adc_val - cal180)*90.0/(cal270-cal180))); // То делаем уточненный расчет по части шкалы в 90 градусов(180-270) с использованием дополнительных калибровок
|
||
return az_raw_data; // Возвращаем значчение азимута
|
||
}
|
||
else if(az_raw_data >= 270 && az_raw_data < 360) // Если приблизительный азимут от 270 до 360 градусов
|
||
{
|
||
az_raw_data = lround(270.0+((adc_val - cal270)*90.0/(cal360-cal270))); // То делаем уточненный расчет по части шкалы в 90 градусов(270-360) с использованием дополнительных калибровок
|
||
return az_raw_data; // Возвращаем значчение азимута
|
||
}
|
||
else if(az_raw_data >= 360 && az_raw_data <= 450) // Если приблизительный азимут от 360 до 450 градусов
|
||
{
|
||
az_raw_data = lround(360.0+((adc_val - cal360)*90.0/(cal450-cal360))); // То делаем уточненный расчет по части шкалы в 90 градусов(360-450) с использованием дополнительных калибровок
|
||
return az_raw_data; // Возвращаем значчение азимута
|
||
}
|
||
else
|
||
{
|
||
return az_raw_data;
|
||
}
|
||
}
|
||
|
||
void set_az(uint16_t az_r, uint16_t az_n) // Расчет кратчайшего пути для поворота антенны
|
||
{
|
||
int16_t cw; // Переменная для длины пути по часовой стрелке
|
||
int16_t ccw; // Переменная для длины пути против часовой стрелки
|
||
ccw = az_r - az_n; // Расчет пути против часовой стрелки
|
||
if(ccw < 0) // Расчет пути против часовой стрелки
|
||
{
|
||
ccw += 360; // Расчет пути против часовой стрелки
|
||
}
|
||
cw = az_n - az_r; // Расчет пути по часовой стрелке
|
||
if(cw < 0) // Расчет пути по часовой стрелке
|
||
{
|
||
cw += 360; // Расчет пути по часовой стрелке
|
||
}
|
||
if(cw < ccw) // Если по часовой короче, чем против
|
||
{
|
||
if(cw + az_r <= 450) // и получившийся азимут не выходит за возможности редуктора
|
||
{
|
||
rot_cw = 1; // То вращаем по часовой стрелке
|
||
}
|
||
else // Иначе
|
||
{
|
||
rot_ccw = 1; // против часовой стрелки
|
||
}
|
||
}
|
||
else // Если против часовой короче, чем по
|
||
{
|
||
if((int16_t)az_r - (int16_t)ccw > 0) // и получившийся азимут не выходит за возможности редуктора
|
||
{
|
||
rot_ccw = 1; // То вращаем против часовой
|
||
}
|
||
else // Иначе
|
||
{
|
||
rot_cw = 1; // По часовой
|
||
}
|
||
}
|
||
}
|
||
|
||
void pwm_init(void) // Инициализация ШИМ
|
||
{
|
||
TCCR2A |= (1<<COM2A1)|(1<<WGM21)|(1<<WGM20); // OC2A, Fast PWM
|
||
TCCR2B |= (1<<CS20); // Установка делителя тактовой частоты
|
||
}
|
||
|
||
ISR(TIMER0_OVF_vect) // Прерывание по переполнению таймера 0
|
||
{
|
||
if(timer < 255)
|
||
{
|
||
timer++;
|
||
}
|
||
if(timer2 > 0)
|
||
{
|
||
timer2--;
|
||
}
|
||
}
|
||
|
||
void timer0_stop(void) // Остановка таймера 0
|
||
{
|
||
TCCR0B &= ~(1<<CS02); // Отключаем тактирование
|
||
TIMSK0 &= ~(1<<TOIE0); // Запрещаем прерывание
|
||
timer = 0; // Обнуляем переменную
|
||
}
|
||
|
||
void timer0_start(void) // Запуск таймера 0
|
||
{
|
||
TCCR0B |= (1<<CS02); // Включаем тактирование и устанавливаем делитель тактовой частоты
|
||
TIMSK0 |= (1<<TOIE0); // Разрешаем прерывание по переполнению таймера
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
wdt_enable(WDTO_2S);
|
||
wdt_reset();
|
||
uint8_t step_val = 31; // Значение ШИМ для регулировки скорости
|
||
uint8_t manual = 0; // Ручное вращение - 0, установка по азимуту - 1
|
||
uint8_t rot_stat = 0; // Текущее состояние, 0 - остановле, 1 - плавный пуск, 2 - вращение на установленной скорости, 3 - плавная остановка
|
||
uint8_t speed = 0; // Скорость вращения, значения для ШИМ
|
||
uint16_t raw_az = 0; // Текущий азимут 0-450
|
||
uint16_t new_az = 0; // Азимут установки
|
||
uint8_t need_stop = 0;
|
||
ROTOR_DDR |= (1<<ROTOR_CW)|(1<<ROTOR_CCW); // Настройка портов
|
||
ROTOR_PORT &= ~((1<<ROTOR_CW)|(1<<ROTOR_CCW)); // Настройка портов
|
||
ROTOR_SPEED_DDR |= (1<<ROTOR_SPEED_PINNUM); // Настройка портов
|
||
ROTOR_SPEED_PORT &= ~(1<<ROTOR_SPEED_PINNUM); // Настройка портов
|
||
adc_init(); // Инициализация АЦП
|
||
usart_init(MYUBRR); // Инициализация UART
|
||
stdout = &mystdout;
|
||
cal0 = eeprom_read_word(&EEPcal0); // Чтение калибровок
|
||
cal90 = eeprom_read_word(&EEPcal90); // Чтение калибровок
|
||
cal180 = eeprom_read_word(&EEPcal180); // Чтение калибровок
|
||
cal270 = eeprom_read_word(&EEPcal270); // Чтение калибровок
|
||
cal360 = eeprom_read_word(&EEPcal360); // Чтение калибровок
|
||
cal450 = eeprom_read_word(&EEPcal450); // Чтение калибровок
|
||
speed = eeprom_read_byte(&EEPspeed); // Чтение максимальной скорости
|
||
pwm_init(); // Инициализация ШИМ
|
||
OCR2A = 0; // Скважность ШИМ - 0
|
||
printf_P(PSTR("YAESU DXA ROTOR CARD by R5CA\n")); // Печатаем в порт
|
||
sei(); // Глобально разрешаем прерывания
|
||
timer0_start(); // Запускаем таймер
|
||
wdt_reset();
|
||
while(1)
|
||
{
|
||
wdt_reset();
|
||
raw_az = az_raw(); // Считывание и расчет азимута
|
||
if(rot_cw == 1 && (new_az - raw_az) < 1 && manual == 0) // Если разница между текущим азимутом и заданным меньше 1 градуса
|
||
{
|
||
rot_cw = 0; // Останавливаем вращение
|
||
}
|
||
if(rot_ccw == 1 && (raw_az - new_az) < 1 && manual == 0) // Если разница между текущим азимутом и заданным меньше 1 градуса
|
||
{
|
||
rot_ccw = 0; // Останавливаем вращение
|
||
}
|
||
if(rot_stat != STOP && rot_cw == 0 && rot_ccw == 0) // Ротор не остановлен и задание на вращение закончилось
|
||
{
|
||
ROTOR_PORT &= ~((1<<ROTOR_CW)|(1<<ROTOR_CCW)); // Останавливаем вращение
|
||
rot_stat = STOP; // Меняем статус
|
||
OCR2A = 0; // Скважность ШИМ - 0
|
||
//timer0_stop(); // Останавливаем таймер
|
||
|
||
}
|
||
if(timer2 == 0)
|
||
{
|
||
if(rot_stat == STOP && rot_cw == 1) // Ротор остановлен и получено задание на вращение по часовой стрелке
|
||
{
|
||
ROTOR_PORT |= (1<<ROTOR_CW); // Начинаем вращение
|
||
rot_stat = SLOW_START; // Меняем статус
|
||
step_val = 31; // Устанавливаем начальную скорость
|
||
OCR2A = step_val; // Устанавливаем начальную скорость
|
||
//timer0_start(); // Запускаем таймер
|
||
}
|
||
else if(rot_stat == STOP && rot_ccw == 1) // Ротор остановлен и получено задание на вращение против часовой стрелки
|
||
{
|
||
ROTOR_PORT |= (1<<ROTOR_CCW); // Начинаем вращение
|
||
rot_stat = SLOW_START; // Меняем статус
|
||
step_val = 31; // Устанавливаем начальную скорость
|
||
OCR2A = step_val; // Устанавливаем начальную скорость
|
||
//timer0_start(); // Запускаем таймер
|
||
}
|
||
}
|
||
if(rot_stat == SLOW_START) // Плавный пуск
|
||
{
|
||
if(step_val < speed && timer > 20) // Текущая скорость меньше максимальной и таймер дотикал до переключения
|
||
{
|
||
step_val += 16; // чуть добавляем скорость
|
||
OCR2A = step_val; // чуть добавляем скорость
|
||
timer = 0; // обнуляем таймер
|
||
}
|
||
if(step_val == speed) // Если достигли максимальной скорости
|
||
{
|
||
rot_stat = ROTARY; // Меняем статус
|
||
}
|
||
}
|
||
if((rot_stat == SLOW_START || rot_stat == ROTARY) && ((rot_ccw == 1 && ((raw_az - new_az) < SLOW_DOWN_AZ)) || (rot_cw == 1 && ((new_az - raw_az) < SLOW_DOWN_AZ))) && manual == 0) // Разница между текущим и заданным азимутом меньше, чем задана для плавной остановки
|
||
{
|
||
rot_stat = SLOW_DOWN; // Меняем статус
|
||
}
|
||
if(rot_stat == SLOW_DOWN) // Плавная остановка
|
||
{
|
||
if(step_val > 31 && timer > 15) // Если значение скорости больше минимальной и таймер дотикал до переключения
|
||
{
|
||
OCR2A = step_val; // Чуть уменьшаем скорость
|
||
step_val -= 16; // Чуть уменьшаем скорость
|
||
timer = 0; // обнуляем таймер
|
||
}
|
||
if(step_val <= 31 && need_stop == 1)
|
||
{
|
||
ROTOR_PORT &= ~((1<<ROTOR_CW)|(1<<ROTOR_CCW)); // Останавливаем вращение
|
||
rot_stat = STOP; // Меняем статус
|
||
OCR2A = 0; // Скважность ШИМ - 0
|
||
need_stop = 0;
|
||
}
|
||
}
|
||
if(uartRXC == 1) // Принята строка по UART
|
||
{
|
||
char uart_tmp[10];
|
||
if(strcmp_P((char*)uartRXBuf, PSTR("BOOT")) == 0) // Получено слово для перехода в boot
|
||
{
|
||
wdt_disable(); // Ребутимся
|
||
wdt_enable(WDTO_15MS); // Ребутимся
|
||
while(1) {}; // Ребутимся
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL0")) == 0) // Калибровка 0 градусов
|
||
{
|
||
cal0 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal0, cal0); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL90")) == 0) // Калибровка 90 градусов
|
||
{
|
||
cal90 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal90, cal90); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL180")) == 0) // Калибровка 180 градусов
|
||
{
|
||
cal180 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal180, cal180); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL270")) == 0) // Калибровка 270 градусов
|
||
{
|
||
cal270 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal270, cal270); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL360")) == 0) // Калибровка 360 градусов
|
||
{
|
||
cal360 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal360, cal360); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("CAL450")) == 0) // Калибровка 450 градусов
|
||
{
|
||
cal450 = adc_read(ROTOR_AZ_IN); // Чтение АЦП
|
||
eeprom_write_word(&EEPcal450, cal450); // Запись в EEPROM
|
||
printf_P(PSTR("OK\n")); // Печатаем в порт
|
||
}
|
||
else if(strlen((char*)uartRXBuf) == 1)
|
||
{
|
||
if(((char*) uartRXBuf)[0] == 'C') // Получен запрос азимута
|
||
{
|
||
usart_tx('A'); // Печатаем в порт
|
||
usart_tx('Z'); // Печатаем в порт
|
||
usart_tx('='); // Печатаем в порт
|
||
memset(uart_tmp, 0x00, 10); // Очищаем строку
|
||
sprintf(uart_tmp, "%03d", raw_az); // печатаем азимут в строку
|
||
for(uint8_t i=0; i < strlen(uart_tmp); i++) // Отправляем в порт строку
|
||
{
|
||
usart_tx(uart_tmp[i]); // Печатаем в порт
|
||
}
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
}
|
||
else if(((char*) uartRXBuf)[0] == 'S') // остановка
|
||
{
|
||
rot_cw = 0; // Отменяем задание на вращение
|
||
rot_ccw = 0; // Отменяем задание на вращение
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
}
|
||
else if(((char*) uartRXBuf)[0] == 'L' && rot_stat == STOP) // вращение против часовой
|
||
{
|
||
rot_ccw = 1; // Задание на вращение против часовой
|
||
manual = 1; // Ручной режим
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
}
|
||
else if(((char*) uartRXBuf)[0] == 'R' && rot_stat == STOP) // вращение по часовой
|
||
{
|
||
rot_cw = 1; // Задание на вращение по часовой
|
||
manual = 1; // Ручной режим
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
}
|
||
}
|
||
else if(strlen((char*)uartRXBuf) == 4 && ((char*) uartRXBuf)[0] == 'M') // установка азимута
|
||
{
|
||
uartRXBuf[0] = uartRXBuf[1]; // Сдвиг в массиве
|
||
uartRXBuf[1] = uartRXBuf[2]; // Сдвиг в массиве
|
||
uartRXBuf[2] = uartRXBuf[3]; // Сдвиг в массиве
|
||
uartRXBuf[3] = 0x00; // Конец строки
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
new_az = atoi((char*)uartRXBuf); // Преобразуем ASCII число в значение
|
||
uint8_t tmp1 = 0;
|
||
uint8_t tmp2 = 0;
|
||
if(rot_cw == 1)
|
||
{
|
||
tmp1 = 1;
|
||
}
|
||
else if(rot_ccw == 1)
|
||
{
|
||
tmp1 = 2;
|
||
}
|
||
rot_cw = 0;
|
||
rot_ccw = 0;
|
||
set_az(raw_az, new_az); // Устанавливаем азимут назначения
|
||
if(rot_cw == 1)
|
||
{
|
||
tmp2 = 1;
|
||
}
|
||
else if(rot_ccw == 1)
|
||
{
|
||
tmp2 = 2;
|
||
}
|
||
if(tmp1 != 0)
|
||
{
|
||
if(tmp1 != tmp2)
|
||
{
|
||
if(rot_stat != STOP)
|
||
{
|
||
rot_stat = SLOW_DOWN; // Меняем статус
|
||
need_stop = 1;
|
||
timer2 = 375;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(rot_stat == SLOW_DOWN)
|
||
{
|
||
rot_stat = SLOW_START; // Меняем статус
|
||
}
|
||
}
|
||
}
|
||
manual = 0; // Автоматический режим
|
||
}
|
||
else if(strlen((char*)uartRXBuf) == 2)
|
||
{
|
||
if(strcmp_P((char*)uartRXBuf, PSTR("X1")) == 0) // Команда изменения максимальной скорости
|
||
{
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
speed = 63; // Устанавливаем значение скорости(скважность ШИМ 0-255)
|
||
eeprom_write_byte(&EEPspeed, speed); // Запись в EEPROM
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("X2")) == 0) // Команда изменения максимальной скорости
|
||
{
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
speed = 127; // Устанавливаем значение скорости(скважность ШИМ 0-255)
|
||
eeprom_write_byte(&EEPspeed, speed); // Запись в EEPROM
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("X3")) == 0) // Команда изменения максимальной скорости
|
||
{
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
speed = 191; // Устанавливаем значение скорости(скважность ШИМ 0-255)
|
||
eeprom_write_byte(&EEPspeed, speed); // Запись в EEPROM
|
||
}
|
||
else if(strcmp_P((char*)uartRXBuf, PSTR("X4")) == 0) // Команда изменения максимальной скорости
|
||
{
|
||
usart_tx(0x0D); // Печатаем в порт
|
||
speed = 255; // Устанавливаем значение скорости(скважность ШИМ 0-255)
|
||
eeprom_write_byte(&EEPspeed, speed); // Запись в EEPROM
|
||
}
|
||
}
|
||
cli(); // Глобально запрещаем прерывания
|
||
uartbuf_zero(); // Обнуляем буфер UART
|
||
uartRXBufNum = 0; // Обнуляем кол-во принятых байт
|
||
uartRXC = 0; // Обнуляем флаг окончания приема строки
|
||
sei(); // Глобально разрешаем прерывания
|
||
}
|
||
}//
|
||
}
|