ВНИМАНИЕ! На форуме началось голосование в конкурсе - астрофотография месяца ИЮНЬ!
0 Пользователей и 1 Гость просматривают эту тему.
/*****************************************************This program was produced by theCodeWizardAVR V1.25.8 ProfessionalAutomatic Program Generator© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.http://www.hpinfotech.comProject : EQ1 motorVersion : 1Date : 19.03.2011Author : MOCompany : MOComments: Chip type : ATmega88PProgram type : ApplicationClock frequency : 16,000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256*****************************************************/#include <mega88p.h>#include <stdio.h>#include <delay.h>///////// Редукторы и скорости //////#define RA_SIDERAL_H 0x1C // делитель таймера для задания звёздной скорости #define RA_SIDERAL_L 0x17#define SLEW_FADE_START 10 // начальная скорость RA_SIDERAL_H при переходе // @todo дробную скорость падения #define SLEW_FADE_SPEED 1 // скорость падения RA_SIDERAL_H при переходе #define SLEW_FADE_STOP 5 // минимум скорость падения RA_SIDERAL_H при переходе ///////// Ножки //////////// 4 ножки униполярного шаговика RA: апаратный ШИМ#define RA_0 OCR0A // D.6 #define RA_1 OCR0B // D.5 #define RA_2 OCR2A // B.3 #define RA_3 OCR2B // D.3 // 4 ножки униполярного шаговика DEC: полушаг#define DEC_3 PORTD.4 #define DEC_2 PORTD.2#define DEC_1 PORTD.1#define DEC_0 PORTD.0#define PULT_RA_LEFT PINB.0#define PULT_RA_RIGHT PINB.1#define PULT_DEC_LEFT PINB.4#define PULT_DEC_RIGHT PINB.5#define LED PORTB.2/////// таблицы шагов мотора ///flash char half_step_table[8][4] = {{1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,1,0}, {0,0,1,1}, {0,0,0,1}, {1,0,0,1}}; #define MICROSTEPS 8flash char microstep_table[MICROSTEPS + 1] = {0,39,75,100,141,180,212,235,255};////////////////////////////////#define RA_DIR_LEFT 1#define RA_DIR_RIGHT 2//////////////////////////long int ra = 0;long int dec = 0;long int slew_ra;long int slew_dec;char sideral = 1;char slewing = 0;unsigned char uart_byte = 0;long int uart_ra, uart_dec;char uart_mode;///////////////////////////////////// UART ////////////#ifndef RXB8#define RXB8 1#endif#ifndef TXB8#define TXB8 0#endif#ifndef UPE#define UPE 2#endif#ifndef DOR#define DOR 3#endif#ifndef FE#define FE 4#endif#ifndef UDRE#define UDRE 5#endif#ifndef RXC#define RXC 7#endif#define FRAMING_ERROR (1<<FE)#define PARITY_ERROR (1<<UPE)#define DATA_OVERRUN (1<<DOR)#define DATA_REGISTER_EMPTY (1<<UDRE)#define RX_COMPLETE (1<<RXC)#define RX_BUFFER_SIZE0 8char rx_buffer0[RX_BUFFER_SIZE0];unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;bit rx_buffer_overflow0;// USART Receiver interrupt service routineinterrupt [USART_RXC] void usart_rx_isr(void){ char status,data; long int long_tmp; status=UCSR0A; data=UDR0; long_tmp = data; // Номер байта в посылке switch (uart_byte) { // первый LONG параметр = RA, HhLl case 1: uart_ra |= (long_tmp<<24); uart_byte++; break; case 2: uart_ra |= (long_tmp<<16); uart_byte++; break; case 3: uart_ra |= (long_tmp<<8); uart_byte++; break; case 4: uart_ra |= long_tmp; uart_byte++; break; // второй LONG параметр = DEC case 5: uart_dec |= (long_tmp<<24); uart_byte++; break; case 6: uart_dec |= (long_tmp<<16); uart_byte++; break; case 7: uart_dec |= (long_tmp<<8); uart_byte++; break; case 8: uart_dec |= long_tmp; uart_byte = 0; switch (uart_mode) { // S: slew ra/dec case 'S': slewing = 1; slew_ra = uart_ra; slew_dec = uart_dec; OCR1AH = SLEW_FADE_START; break; // P: sync ra/dec (put) case 'P': ra = uart_ra; dec = uart_dec; break; } uart_ra = 0; uart_dec = 0; break; // первый байт case 0: switch (data) { // A: abort slew // input: void // output: void case 'A': // @todo: плавный останов slew_ra = ra; slew_dec = dec; slewing = 0; break; // S: slew ra/dec // input: long ra, long dec // output: void case 'S': uart_byte++; uart_ra = 0; uart_dec = 0; break; // s: is slewing // input: void // output: bool case 's': putchar(slewing); break; // P: sync ra/dec (put) // input: long ra, long dec // output: void case 'P': uart_byte++; uart_ra = 0; uart_dec = 0; break; // G: get ra/dec // input void // output: long ra, long dec case 'G': putchar((ra & 0xFF000000) >> 24); putchar((ra & 0xFF0000) >> 16); putchar((ra & 0xFF00) >> 8); putchar(ra & 0xFF); putchar((dec & 0xFF000000) >> 24); putchar((dec & 0xFF0000) >> 16); putchar((dec & 0xFF00) >> 8); putchar(dec & 0xFF); break; // R: start sideral rate // input: void // output: void case 'R': sideral = 1; break; // r: stop sideral rate // input: void // output: void case 'r': sideral = 0; break; // L: pulseguide @todo узнать параметры в аскоме case 'L': // @todo break; } uart_mode = data; break; } if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer0[rx_wr_index0++]=data; if (rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0; if (++rx_counter0 == RX_BUFFER_SIZE0) { rx_counter0=0; rx_buffer_overflow0=1; } }}#ifndef _DEBUG_TERMINAL_IO_// Get a character from the USART Receiver buffer#define _ALTERNATE_GETCHAR_#pragma used+char getchar(void){ char data; while (rx_counter0==0); data=rx_buffer0[rx_rd_index0++]; if (rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0; #asm("cli") --rx_counter0; #asm("sei") return data;}#pragma used-#endif/////////// UART ////////////// Звёздная шагалка, 16бит таймер 1// она же slew с fade, таймер модифицируетсяinterrupt [TIM1_COMPA] void timer1_compa_isr(void){ unsigned char phase; unsigned char microstep; if (slewing) { // start ускорения // нагоняем скорость, понижая край счётчика таймера на FADE_STEP, если не FADE_STOP if (OCR1AH > SLEW_FADE_STOP) { OCR1AH -= SLEW_FADE_SPEED; } // @todo: учесть зацикливание по переполнению LONG if (ra < slew_ra) { ra++; } else { if (ra > slew_ra) { ra--; } } if (dec < slew_dec) { dec++; } else { if (dec > slew_dec) { dec--; } } if ( (ra == slew_ra) && (dec == slew_dec) ) { // переход завершён slewing = 0; } // @todo: stop ускорения (щас просто отрубает моторы) /* if (ticks to stop < (SLEW_FADE_START - SLEW_FADE_SPEED) ) { OCR1AH += SLEW_FADE_SPEED; } */ } else { if (sideral) { // Запуск звёздной скорости OCR1AH=RA_SIDERAL_H; OCR1AL=RA_SIDERAL_L; // шаг вперёд ra++; } } // частный случай на 1/8 микрошага // @todo: переделать бы в #define phase = ra & 0b11000; microstep = ra &0b111; RA_0 = ((phase == 1)?microstep_table[microstep]:(phase == 2)?microstep_table[8-microstep]:0); RA_1 = ((phase == 2)?microstep_table[microstep]:(phase == 3)?microstep_table[8-microstep]:0); RA_2 = ((phase == 3)?microstep_table[microstep]:(phase == 4)?microstep_table[8-microstep]:0); RA_3 = ((phase == 4)?microstep_table[microstep]:(phase == 1)?microstep_table[8-microstep]:0); DEC_0 = (half_step_table[dec & 7][0] == 1)?1:0; DEC_1 = (half_step_table[dec & 7][1] == 1)?1:0; DEC_2 = (half_step_table[dec & 7][2] == 1)?1:0; DEC_3 = (half_step_table[dec & 7][3] == 1)?1:0; // и моргаем лампочкой LED = (ra+dec) & 1;}void main(void){// Crystal Oscillator division factor: 1#pragma optsize-CLKPR=0x80;CLKPR=0x00;#ifdef _OPTIMIZE_SIZE_#pragma optsize+#endif// Input/Output Ports initialization// Port B initialization// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00;DDRB=0xFF;// Port C initialization// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00;DDRC=0x7F;// Port D initialization// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTD=0x00;DDRD=0xFF;// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: Timer 0 Stopped// Mode: Normal top=FFh// OC0A output: Disconnected// OC0B output: DisconnectedTCCR0A=0x00;TCCR0B=0x00;TCNT0=0x00;OCR0A=0x00;OCR0B=0x00;// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: 250,000 kHz// Mode: CTC top=OCR1A// OC1A output: Discon.// OC1B output: Discon.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: On// Compare B Match Interrupt: OffTCCR1A=0x00;TCCR1B=0x0B;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x70;OCR1AL=0x5F;OCR1BH=0x00;OCR1BL=0x00;// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: Timer 2 Stopped// Mode: Normal top=FFh// OC2A output: Disconnected// OC2B output: DisconnectedASSR=0x00;TCCR2A=0x00;TCCR2B=0x00;TCNT2=0x00;OCR2A=0x00;OCR2B=0x00;// External Interrupt(s) initialization// INT0: Off// INT1: Off// Interrupt on any change on pins PCINT0-7: Off// Interrupt on any change on pins PCINT8-14: Off// Interrupt on any change on pins PCINT16-23: OffEICRA=0x00;EIMSK=0x00;PCICR=0x00;// Timer/Counter 0 Interrupt(s) initializationTIMSK0=0x00;// Timer/Counter 1 Interrupt(s) initializationTIMSK1=0x02;// Timer/Counter 2 Interrupt(s) initializationTIMSK2=0x00;// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: OffACSR=0x80;ADCSRB=0x00;// USART initialization// Communication Parameters: 8 Data, 1 Stop, No Parity// USART Receiver: On// USART Transmitter: On// USART0 Mode: Asynchronous// USART Baud Rate: 9600UCSR0A=0x00;UCSR0B=0x98;UCSR0C=0x06;UBRR0H=0x00;UBRR0L=0x67;#asm("sei") while (1) { };}
Хорошее дело. Полезно прогнать Ascom Conformance Checkerhttp://ascom-standards.org/Downloads/DevTools.htm, он напишет кучу замечаний (что именно в плагине не соответствует стандарту).Пересчет в Alt Az координаты делать по моему не обязательно, достаточно внятно прописать в интерфейсе, что телескоп их не поддерживает.
В перспективе переход на stm32 платку (350+ руб) и железные драйвера биполярников от Аллегро (400+ руб за канал) с контролем тока.Платка придёт через пару недель из кЕтая. Аллегровский напаяный модуль уже дома.
Цитата: moscow от 02 Ноя 2011 [12:48:10]В перспективе переход на stm32 платку (350+ руб) и железные драйвера биполярников от Аллегро (400+ руб за канал) с контролем тока.Платка придёт через пару недель из кЕтая. Аллегровский напаяный модуль уже дома.тоже балывался с AVRками, и уже перешел на STM32+Allegro, проект ксате чемто похож на вашhttp://www.astroclub.kiev.ua/forum/index.php?topic=20674.msg241446#msg241446на ASCOM драйвер не созрел "времярасход" большой, подвязался к EQMOD.на текущий момент на столе в связке с EQMOD все работает, готовлю свежую прошивку ну и тестирование на монти.так что ресурса кортекса с головой.
На яхе лежит и рыба на Си(каком-то) того самого драйвера eqcontrl.dll для eqmod (ой! я зря про eqmod? )
...Да, я не сторонник eqmod, но не могу не признать, что это классная программа.Сам же я ей не пользуюсь и свой контроллер строю на аском драйвере.
Обнаруживаются мелкие неприятности, связанные с написанием своего аском-драйвера. К примеру, я думал, что монти/драйверу не обязательно знать свои координаты. И, в принципе, всё работает и без них (в рамках протестированного). Но при перекладке монти идёт кругом по RA, не анализируя, уводит ли она трубу "под землю". Для избежания подобного достаточно чтобы монти знала широту места наблюдения с точностью в пяток градусов.
Цитата: moscow от 02 Ноя 2011 [20:50:10]...Да, я не сторонник eqmod, но не могу не признать, что это классная программа.Сам же я ей не пользуюсь и свой контроллер строю на аском драйвере.имелось ввиду наверное свой аском, ведь eqmod можно сказать тоже аском драйвер.
Цитата: moscow от 03 Ноя 2011 [01:21:51]Обнаруживаются мелкие неприятности, связанные с написанием своего аском-драйвера. К примеру, я думал, что монти/драйверу не обязательно знать свои координаты. И, в принципе, всё работает и без них (в рамках протестированного). Но при перекладке монти идёт кругом по RA, не анализируя, уводит ли она трубу "под землю". Для избежания подобного достаточно чтобы монти знала широту места наблюдения с точностью в пяток градусов.я не вникал глубоко в аском, думал что надо больше знать информации как минимум координаты места наблюдения, и время, ну и вычисления для перехода от небесных координат в энкодеры движков.
я не вникал глубоко в аском, думал что надо больше знать информации как минимум координаты места наблюдения, и время, ну и вычисления для перехода от небесных координат в энкодеры движков.
The above diagram shows a standard bipolar stepper motor. To control this with the A4983 or A4988, connect stepper lead A to board output 1A, stepper lead C to board output 1B, stepper lead B to board output 2A, and stepper lead D to board output 2B. See the A4983/A4988 datasheet for more information.If you have a six-lead unipolar stepper motor as shown in the diagram below:Two-phase unipolar stepper motor with six leads.(картинка 1)