/********************************************* This program was produced by the CodeWizardAVR V1.0.1.3b Standard Automatic Program Generator © Copyright 1998-2000 Pavel Haiduc, HP InfoTech S.R.L. http://infotech.ir.ro e-mail:dhptechn@ir.ro , hpinfotech@mail.com Project : Ele3 Version : 0,1 Date : 1/22/2001 Author : Jim White, Collorado Satellite Company : Services, Parker, CO USA Comments: Elevation Control and Display for W6OAL EME array. Chip type : AT90LS8535 Clock frequency : 4.000000 MHz Memory model : Small Internal SRAM size : 512 External SRAM size : 0 Data Stack size : 128 *********************************************/ #include <90s8535.h> #include bit last_pulse_state = 0; //save of last pulse high or low state int up = 0; //moving up = 1 or down = 0 char outdata[16]; //buffer for output to LDC eeprom int zero_ele; //counts of pulses at zero elevation. eeprom int ninty_ele; //counts at 90 elevation eeprom int posit; //position in pulse transitions. int degrees = 0; //degrees of elevation char c; //input character from UART eeprom float mult; //counts per degree after calibration char tmpstring[5]; //diagnostic for testing // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x15 #endasm #include #pragma used+ #pragma regalloc- // UART Receiver buffer char rx_buffer[8]; unsigned char rx_wr_index,rx_rd_index,rx_counter; // This flag is set on UART Receiver buffer overflow bit rx_buffer_overflow; #pragma regalloc+ #pragma used- // UART Receiver interrupt service routine #pragma savereg- interrupt [UART_RXC] void uart_rx_isr(void) { #asm .equ __rx_buffer_size=8 push r26 in r26,sreg push r26 push r27 push r30 #endasm #ifdef _MODEL_TINY_ #asm ldi r26,_rx_buffer lds r30,_rx_wr_index add r26,r30 clr r27 #endasm #endif #ifdef _MODEL_SMALL_ #asm push r31 ldi r26,low(_rx_buffer) ldi r27,high(_rx_buffer) lds r30,_rx_wr_index clr r31 add r26,r30 adc r27,r31 #endasm #endif #asm in r30,udr st x,r30 lds r30,_rx_wr_index inc r30 cpi r30,__rx_buffer_size brlo __uart_rx_isr0 clr r30 __uart_rx_isr0: sts _rx_wr_index,r30 lds r30,_rx_counter inc r30 sts _rx_counter,r30 cpi r30,__rx_buffer_size+1 brlo __uart_rx_isr1 #endasm rx_buffer_overflow=1; #asm("__uart_rx_isr1:") #ifdef _MODEL_SMALL_ #asm("pop r31") #endif #asm pop r30 pop r27 pop r26 out sreg,r26 pop r26 #endasm } #pragma savereg+ #ifndef _DEBUG_TERMINAL_IO_ // Get a character from the UART Receiver buffer #define _ALTERNATE_GETCHAR_ #pragma warn- #pragma used+ char getchar(void) { #asm lds r30,_rx_counter tst r30 breq _getchar #endasm #ifdef _MODEL_TINY_ #asm ldi r26,_rx_buffer lds r30,_rx_rd_index add r26,r30 clr r27 #endasm #endif #ifdef _MODEL_SMALL_ #asm ldi r26,low(_rx_buffer) ldi r27,high(_rx_buffer) lds r30,_rx_rd_index clr r31 add r26,r30 adc r27,r31 #endasm #endif #asm inc r30 cpi r30,__rx_buffer_size brlo __getchar0 clr r30 __getchar0: sts _rx_rd_index,r30 ld r30,x cli lds r26,_rx_counter dec r26 sts _rx_counter,r26 sei #endasm } #pragma used- #ifdef _WARNINGS_ON_ #pragma warn+ #endif #endif // Standard Input/Output functions #include // Declare your global variables here void do_math(void) //calculate the counts, then the degrees and display { if (up) posit++; else posit--; degrees = ((float)posit-(float)zero_ele) / mult; //counts / counts per degree = degrees sprintf(outdata,"C=%4d Deg=%d ",posit,degrees); lcd_gotoxy(0,1); lcd_puts(outdata); ftoa(mult,10,tmpstring); printf("DIAG: posit = %d, mult = %s, degrees %d\n\r",posit,tmpstring,degrees); } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A DDRA=0x00; PORTA=0x00; // Port B DDRB=0x00; PORTB=0x00; // Port C DDRC=0x00; PORTC=0x00; // Port D DDRD=0x00; PORTD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Output Compare // OC0 output: Disconnected TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Output Compare // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Output Compare // OC2 output: Disconnected TCCR2=0x00; ASSR=0x00; TCNT2=0x00; OCR2=0x00; // UART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // UART Receiver: On // UART Transmitter: On UCR=0x98; // UART Baud rate: 9600 UBRR=0x19; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; // LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") printf("\n\rElevation Control starting\n\r"); while (1) { //Loop till power comes on up or down while(PINA.1 == 0 && PINA.2 == 0) { //No power lcd_gotoxy(0,0); lcd_putsf("ELEVATION OFF "); sprintf(outdata,"C=%4d Deg=%2d",posit,degrees); //last position lcd_gotoxy(0,1); lcd_puts(outdata); if (rx_counter > 0) { //if a char in the serial buffer then user wants c = getchar(); // to start calibration switch (c) { case '0' : //They have moved it to zero, so save and go to 90 posit = 100; //set 0 location to 100 counts to avoid negative math zero_ele = posit; printf("\n\rZero location saved."); printf("\n\rMove elevation to ninty degrees and hit 9 "); break; case '9' : //At 90, save, calculate and tellem we are done ninty_ele = posit; mult = ((float)ninty_ele - (float)zero_ele)/90; //counts per degree ftoa(mult,10,tmpstring); printf("\n\rmult = %s",tmpstring); printf("\n\r90 degree elevation saved."); printf("\n\rCalibration complete"); break; default : //if they hit CR or any other character, tellem we are starting printf("\n\rStarting calibration."); printf("\n\rMove elevation to zero degrees and hit 0 "); break; } //switch } //if character in buffer } //while no power applied //Power is applied lcd_gotoxy(0,0); //See if we are going up or down if(PINA.1) { lcd_putsf("ELEVATION UP "); //And show it printf("Elevation up posit = %d\n\r",posit); up = 1; } else { lcd_putsf("ELEVATION DOWN"); printf("Elevation down posit = %d\n\r", posit); up = 0; } //Now count pulses while(PINA.0 == last_pulse_state) {}; //loop till pulse state changes last_pulse_state = PINA.0; //save this as last state printf("pulse\n\r"); do_math(); //go calc the degrees and display } //while 1 } //main