;avpulse.asm ;Dhananjay V. Gadre, VU2NOX ;11th September 1999 ;Clock Crystal Frequency: 3.58 MHz ;Synpopsis: ;A pulse frequency counting interface for an astronomical ;photometer. Connects to the PC serial port, draws power from ;the serial port pin. ; PB0 <---Data from PC ; PB1 --->Data to PC2 ; PB2 <--- Pulses from Photometer. ;Pulse frequency (TTL Compatible) is between 0 and 10000 Hz ;Sampling rates offered are .1, 1 and 10 s ;After each sampling interval, the data is sent back to ;the PC in BCD .include "2323def.inc" .def save_state=r1 .def start_t=r2 .def stop_t=r3 .def timer_reload=r4 .def exor=r5 .def max_count_low=r6 .def max_count_hi=r7 .def clk_div = r8 .def temp=r16 .def temp2=r18 .def temp1=r19 .def low_del=r17 .def high_del=r22 .def count=r20 .def data=r21 .def mode=r23 ; These are software counter registers .def count_low=r24 .def count_med=r25 .def count_hi=r26 .def int_low=r27 .def int_hi=r28 .equ half_step= -23 .equ full_step= -46 .equ stop_timer= 0 .equ start_timer= 2 .equ ex_mark = '!' .equ and_mark = '&' .equ samp0_low= $77 ;constants for comparing timeout .equ samp0_hi= 5 .equ samp0_clk= 1 ;use CK as the clock source for the Timer0 .equ samp1_low= $a6 .equ samp1_hi= $36 .equ samp1_clk= 1 ;use CK as the clock source for the Timer0 .equ samp2_low= $49 .equ samp2_hi= $44 .equ samp2_clk= 2 ;use CK/8 as the clock source for the Timer0 .cseg .org 0 rjmp RESET ;Reset Handle .org 2 rjmp Timer0_int RESET: ldi temp, low(RAMEND) out SPL, temp ;Init the Stack Pointer ldi temp, 0b00000010 ;configure PORT B for all inputs out DDRB, temp ;except PB1 ldi temp, 0b00000101 ;PB0 and PB2 is input with pullup ;PB1 is o/p at '0' out PORTB, temp ldi temp, $04 mov exor, temp ldi temp, stop_timer ;stop the timer out TCCR0, temp out TCNT0, temp mov stop_t, temp ldi temp, start_timer mov start_t, temp ;register to start the timer ;with CK/8 as the clock source ;******************************************************* ;Main Program Loop ;******************************************************* main_loop: rcall tx_msg rcall get_samp_num go_on: rcall collect_data rcall print_data rjmp go_on ;******************************************************* ;Function: GET_SAMP_NUM ******************************************************** get_samp_num: rcall get_byte com data subi data, $30 cpi data, 0 brne samp1 ldi temp, samp0_low mov max_count_low, temp ldi temp, samp0_hi mov max_count_hi, temp ldi temp, samp0_clk mov clk_div, temp ldi temp, $30 add data, temp com data rcall send_byte ret samp1: cpi data, 1 brne samp2 ldi temp, samp1_low mov max_count_low, temp ldi temp, samp1_hi mov max_count_hi, temp ldi temp, samp1_clk mov clk_div, temp ldi temp, $30 add data, temp com data rcall send_byte ret samp2: ldi temp, samp2_low mov max_count_low, temp ldi temp, samp2_hi mov max_count_hi, temp ldi temp, samp2_clk mov clk_div, temp ldi temp, $30 add data, temp com data rcall send_byte ret ;******************************************************* ;Function: Collect_data ;******************************************************* collect_data: ldi count_low, 0 ldi count_med, 0 ldi count_hi, 0 ldi int_low, 0 ldi int_hi, 0 ldi data, 0 out TCCR0, clk_div ldi temp, 0 out TCNT0, temp ldi temp, 2 ;enable timer0 interrupt out TIMSK, temp sei ;enable global interrupts check_data1: cpi data, 0 brne collect_done in temp, PINB andi temp, 4 cpi temp, 4 brne check_data1 check_data0: cpi data, 0 brne collect_done in temp, PINB andi temp, 4 cpi temp, 4 breq check_data0 inc count_low cpi count_low, 0 breq inc_med rjmp check_data1 inc_med: inc count_med cpi count_med, 0 breq inc_hi rjmp check_data1 inc_hi: inc count_hi rjmp check_data1 collect_done: cli ret ;******************************************************* ;Function: Print_data ;******************************************************* print_data: mov temp, count_med andi temp, $f0 lsr temp lsr temp lsr temp lsr temp ldi data, $30 add temp, data cpi temp, $3a brge gt1 subi temp, 7 gt1: ldi data, 7 add temp, data mov data, temp com data rcall send_byte mov temp, count_med andi temp, $0f ldi data, $30 add temp, data cpi temp, $3a brge gt2 subi temp, 7 gt2: ldi data, 7 add temp, data mov data, temp com data rcall send_byte mov temp, count_low andi temp, $f0 lsr temp lsr temp lsr temp lsr temp ldi data, $30 add temp, data cpi temp, $3a brge gt3 subi temp, 7 gt3: ldi data, 7 add temp, data mov data, temp com data rcall send_byte mov temp, count_low andi temp, $0f ldi data, $30 add temp, data cpi temp, $3a brge gt4 subi temp, 7 gt4: ldi data, 7 add temp, data mov data, temp com data rcall send_byte ldi data, $0d com data rcall send_byte ldi data, $0a com data rcall send_byte ret ;******************************************************* ;Function: GET_BYTE ;Receives a byte on the serial port at 9600, 8, N, 1 ;complements the byte to account for the inversion ;at transmitter end and puts the byte in variable 'data' ;******************************************************* get_byte: ldi count, 9 ldi data, 0 wait_for0: sbic PINB, 0 rjmp wait_for0 wait_for1: sbis PINB, 0 rjmp wait_for1 ldi temp, half_step out TCNT0, temp out TCCR0, start_t still_time: in temp, TIFR cpi temp, 2 brne still_time out TIFR, temp out TCCR0, stop_t in temp, PORTB eor temp, exor out PORTB, temp sec ;set carry sbis PINB, 0 clc ror data ldi temp, full_step out TCNT0, temp out TCCR0, start_t dec count cpi count, 0 brne still_time ldi temp, half_step out TCNT0, temp s_time: in temp, TIFR cpi temp, 2 brne s_time out TIFR, temp out TCCR0, stop_t mov temp, data ret ;******************************************************* ;Function: SEND_BYTE ;Transmits a byte in variable 'data' on the PB1 at ;9600, 8, N, 1 complements the byte to account for the ;inversion at receiver end. ;******************************************************* send_byte: ldi count, 10 in temp, PORTB eor temp, exor out PORTB, temp sbi PORTB, 1 ldi temp, full_step out TCNT0, temp out TCCR0, start_t till_time: in temp, TIFR cpi temp, 2 brne till_time out TIFR, temp out TCCR0, stop_t in temp, PORTB eor temp, exor out PORTB, temp clc ror data brcs its_1 cbi PORTB, 1 rjmp loop_over its_1: sbi PORTB, 1 loop_over: ldi temp, full_step out TCNT0, temp out TCCR0, start_t dec count cpi count, 0 brne till_time out TCCR0, stop_t ldi temp, 2 out TIFR, temp ret ;******************************************************* ;Function: TX_MSG ;Transmits the opening message to the PC terminal ;******************************************************* tx_msg: ldi ZL, low(msg1*2) ldi ZH, high(msg1*2) more_msg: lpm adiw ZL, 1 mov temp, r0 cpi temp, ex_mark brne chk_and ldi data, $0d com data rcall send_byte ldi data, $0a com data rcall send_byte rjmp more_msg chk_and: cpi temp, and_mark breq go_back mov data, temp com data rcall send_byte rjmp more_msg go_back: ret ;******************************************************* ;ISR: Timer0_Int ;******************************************************** Timer0_int: in save_state, SREG inc int_low cpi int_low, 0 breq inc_hi_now rjmp dont_inc inc_hi_now: inc int_hi dont_inc: cp int_low, max_count_low brne noteq1 cp int_hi, max_count_hi brne noteq1 ldi data, 255 noteq1: out SREG, save_state reti ;******************************************************* ;Message String ;A '!' is used to indicate end of line ;when the program encounters a '!', it transmits a ;CR-LF sequence on the serial port ;Similarly, a '&' character is used to indicate ;end of the message string. ;******************************************************* msg1: .db "!!!!!!Welcome to PhotInt!" .db "------------------!" .db "PhotInt: Pulse Counting Photometer Interface to the PC!" .db "Copyright: Dhananjay V. Gadre, 1999!" .db "!" .db "Menu:!" .db "0 -> 0.1 s integration!" .db "1 -> 1.0 s integration!" .db "2 -> 10 s integration!" .db "Press 0, 1 or 2 on your keyboard!&"