16f628 - Problem counting clock frequency

080603010600070303030706 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit

I have added some code to my IR sampler so the chip/board can double as unknown/salvaged crystal identifier. For internal and external clocking of 4Mhz I am getting counts of about 55%. I used single comparator mode to catch pulses from a full rectifier through

1M/270K divider (with the current 9.2 Vac US Robatics wall adapter.) I have been wrestling with this program for a few days , ironing out some other problems, and my brain is a mush. I would appreciate some help with this.

;********************************************************************** ; This file is a basic code template for object module code * ; generation on the PICmicro PIC16F628A. This file contains the * ; basic code building blocks to build upon. As a project minimum * ; the 16F628A.lkr file will also be required for this file to * ; correctly build. The .lkr files are located in the MPLAB * ; directory. * ; * ; If interrupts are not used all code presented between the * ; code section "INT_VECTOR and code section "MAIN" can be removed. * ; In addition the variable assignments for 'w_temp' and * ; 'status_temp' can be removed. * ; * ; If interrupts are used, as in this template file, the 16F628A.lkr * ; file will need to be modified as follows: Remove the lines * ; CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED * ; and * ; SECTION NAME=STARTUP ROM=vectors * ; and change the start address of the page0 section from 0x5 to 0x0 * ; * ; Refer to the MPASM User's Guide for additional information on * ; features of the assembler and linker (Document DS33014). * ; * ; Refer to the respective PICmicro data sheet for additional * ; information on the instruction set. * ; * ;********************************************************************** ; * ; Filename: irs_osc_cntr.asm * ; Date: * ; File Version: * ; * ; Author: * ; Company: * ; * ; * ;********************************************************************** ; * ; Files required: * ; 16F628A.lkr * ; * ; * ;********************************************************************** ; * ; Notes: modified IR_sampler (unfinished, unresolved TX_max_char_count * ; outs all possible values ) * ; besides sampling ir signals, use of the comparators and * ; AC supply to count/measure the oscilator frequency * ; * ;**********************************************************************

list p=16F628A ; list directive to define processor #include ; processor specific variable definitions

errorlevel -302 ; suppress message 302 from list file

; __CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT __CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See data sheet for additional information on configuration word settings.

;***** VARIABLE DEFINITIONS (examples)

; example of using Shared Uninitialized Data Section INT_VAR UDATA 0x20

DD_PA equ 0xa6 DD_PB equ 0xf2

timer1_prescaler res 1 ; /start PB5_old_val res 1 PB5_new_val res 1 timer_lo res 1 timer_hi res 1 timer1_timeouts res 1 ; number of timeouts at 20, decrement the ; TX_max_char_count so that we can periodicaly ; check the degree of activity in the output buffer ; ( when external commands are implemented ) ; for now transfer the TX_max_char_count at first timeout. ResultsA res 1 ; port A outputs ; 0 - output ; 1 - comp- ; 2 - comp+ / ref out 120/60 Hz input ; 3 - ; 4 - ; 5 - VPP/!MCLR always input ; 6 - ; 7 - baud rate input HI/LO (BRGH bit) ResultsB res 1 ; port B outputs ; 0 - timer read hickup indicator ; 1 - Async RX ; 2 - Async Tx ; 3 - ?IR output? not yet implemented ; 4 - measure AC low / PGM ; 5 - IR input ; 6 - PGC ; 7 - PGD comp_flags res 1 AC_present equ 0 ; 0 - ac detected start_measurement equ 1 ; 1 - start measurement ( next zero cross) measuring equ 2 ; 2 - measurement in progress long equ 3 ; 3 - short(.1sec)/ long (1sec) comparator_old_state equ 4 ; 4 - comp old state ; 5 - ; 6 - comp new state ; 7 - reference_adjust res 1 ; incremented by Timer1 ; timeouts ( when marker is ; transmited ) when 4 or 8 and no AC ; reduce the reference reference_adjust_done equ 6 ; AC_found equ 7 ; flag indicating ac ; was just detected and reference ; should be reduced one more notch

zero_cross_count res 1 tmr0_temp res 1 t0_ovf1 res 1 t0_ovf2 res 1 t0_ovf3 res 1

;################################################################################### ; Commands from the serial port precceded by 00 AA sync chars ; Read or write registers ; 101 00001 read register specified in following byte ; 101 00010 write register specified in following byte with data in next additional byte

; sync_OK res 1 ; set to 0 when 0 received incremented when AA received Last_command res 1 ; if sync is 1 store bytes Command_data1 res 1 ; usualy address Command_data2 res 1 ; usualy data value

Free_ram:

INT_VAR_SHR UDATA_SHR 0x71 w_temp res 1 ; variable used for context saving status_temp res 1 ; variable used for context saving

temp1 res 1 ; used by place_byte_in_output_buffer temp2 res 1 ; used by place_byte_in_output_buffer temp3 res 1 buff_head res 1 ; points to where new data is stored buff_tail res 1 ; points to which byte is next to be transmited ( read advance ) buff_start res 1 ; buff_end res 1 new_buff_head res 1 TX_char_count res 1 TX_max_char_count res 1 ;********************************************************************** RESET_VECTOR CODE 0x000 ; processor reset vector goto main ; go to beginning of program

INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents swapf STATUS, w ; move status register into W register movwf status_temp ; save off contents of STATUS register bcf STATUS, RP0 bcf STATUS, RP1

; check for comparator state change movfw TMR0 movwf tmr0_temp

btfss PIR1, CMIF goto comparator_done bsf PORTA, 3 btfsc CMCON, C2OUT goto wrap_up_comp_int bsf comp_flags, AC_present bsf ResultsA, 0 bsf PORTA, 0 btfss comp_flags, start_measurement goto wrap_up_comp_int btfss comp_flags, measuring goto setup_measurement incf zero_cross_count, f ; movfw zero_cross_count ; call place_byte_in_output_buffer

btfsc comp_flags, long goto check_long movlw .12 subwf zero_cross_count, w btfss STATUS, Z goto measurement_incomplete goto transnit_count check_long: movlw .120 subwf zero_cross_count, w btfss STATUS, Z goto measurement_incomplete transnit_count: movfw t0_ovf3 call place_byte_in_output_buffer movfw t0_ovf2 call place_byte_in_output_buffer movfw t0_ovf1 call place_byte_in_output_buffer movfw tmr0_temp call place_byte_in_output_buffer ; movlw A'/' ; call place_byte_in_output_buffer ; movlw A'.' ; call place_byte_in_output_buffer ; movlw A'1' ; call place_byte_in_output_buffer btfsc comp_flags, long goto wrap_up_measurements bsf comp_flags, long bcf comp_flags, measuring goto wrap_up_comp_int

wrap_up_measurements: bcf PORTA, 0 bcf comp_flags, measuring bcf comp_flags, start_measurement bcf comp_flags, long bsf T1CON, TMR1ON goto wrap_up_comp_int

setup_measurement: ; 17 instruction cycles to get here movlw 0x13 ; start with 19 (19 instructions since ; ZERO crossing movwf TMR0 clrf zero_cross_count ; clrf TMR0 clrf t0_ovf1 clrf t0_ovf2 clrf t0_ovf3 bcf T1CON, TMR1ON bsf comp_flags, measuring

measurement_incomplete: wrap_up_comp_int: bcf PIR1, CMIF comparator_done: ; check timer0 overflow do_timer0: btfss INTCON, T0IF goto timer0_done incf t0_ovf1, f btfss STATUS, Z goto timer0_wrap_up incf t0_ovf2, f btfss STATUS, Z goto timer0_wrap_up incf t0_ovf3, f btfss STATUS, Z ; goto timer0_wrap_up

timer0_wrap_up: bcf INTCON, T0IF timer0_done:

; isr code can go here or be located as a call subroutine elsewhere test_PB_change: bcf STATUS, RP0 ; RAM PAGE 0 btfss INTCON, RBIF goto timer_overflow movfw PORTB andlw 0x20 movwf PB5_new_val subwf PB5_old_val, w btfsc STATUS, Z goto PB_change_wrap_up1 movfw TMR1H movwf timer_hi movfw TMR1L movwf timer_lo movf TMR1H, w ; Read high byte SUBWF timer_hi, W ; Sub 1st read with ; 2nd read BTFSC STATUS, Z ; Is result = 0 GOTO done_reading_timer ; Good 16-bit read bsf ResultsB, 0 decf timer_hi, f done_reading_timer: clrf TMR1H clrf TMR1L clrf timer1_timeouts ; output the data to the Async output buffer ; test if change is L/H or H/L

btfsc PB5_new_val, 5 goto bit_end ; on account of IR receiver being normaly high ; invert logic bsf timer_hi, 7 ; slap the bit start indicator into the highest bit movfw timer_hi call place_byte_in_output_buffer movfw timer_lo call place_byte_in_output_buffer goto PB_change_wrap_up bit_end: bcf timer_hi, 7 ; slap the bit end indicator into the highest bit movfw timer_hi call place_byte_in_output_buffer movfw timer_lo call place_byte_in_output_buffer PB_change_wrap_up: movwf PB5_new_val movfw PB5_old_val PB_change_wrap_up1: bcf INTCON, RBIF portB_no_change: timer_overflow; btfss PIR1, TMR1IF ; did timer 1 overflow? goto timer1_service_done bcf PIR1, TMR1IF ; clear a byte somewhere?

; handle first time out: send '#' followed by the maximun number of bytes ; in transmit buffer incf timer1_timeouts, f movlw 1 subwf timer1_timeouts, w btfss STATUS, Z goto handle_buff_treshold_counter movlw 23 call place_byte_in_output_buffer movfw TX_max_char_count call place_byte_in_output_buffer

;every 20 timeouts ( aprox 1 sec, 0.5 with 8MHz clock ) send '*' handle_buff_treshold_counter: movlw 14 subwf timer1_timeouts, w btfss STATUS, C goto timer1_service_done clrf timer1_timeouts incf timer1_timeouts, f movlw 2a call place_byte_in_output_buffer bcf STATUS, RP0 ; RAM PAGE 0

movlw 1 subwf TX_max_char_count, w btfss STATUS, Z decf TX_max_char_count, f

; btfsc reference_adjust, AC_found ; goto timer1_service_done ; clrf comp_flags btfss reference_adjust, 1 incf reference_adjust, f

; bsf comp_flags, start_measurement

timer1_service_done:

int_done: swapf status_temp, w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp, f swapf w_temp, w ; restore pre-isr W register contents retfie ; return from interrupt

place_byte_in_output_buffer: ; pointers - test write/read advance movwf temp1 ; test if head + 1 is equal tail , if so buffer is full!!! ; first test if it hits end of buffer movfw buff_head addlw 1 movwf new_buff_head ; movwf temp2 subwf buff_end, w btfsc STATUS, Z goto head_hit_end ; now test it against the tail pointer movfw new_buff_head subwf buff_tail, w btfsc STATUS, Z goto buffer_full goto place_character head_hit_end: ; head will be pointing to beginning - is tail currently pointing to the beginning? movfw buff_tail subwf buff_start, w btfsc STATUS, Z goto buffer_full movfw buff_start movwf new_buff_head place_character: movfw buff_head movwf FSR movfw temp1 movwf INDF movfw new_buff_head movwf buff_head

character_qued_for_output: bcf STATUS, C return

buffer_full: bsf STATUS, C return

main ; remaining code goes here bcf STATUS, RP0 ; RAM PAGE 0 bcf STATUS, RP1 ; RAM PAGE 0

clrf PORTA movlw 0x04 movwf PORTB

banksel OPTION_REG bcf OPTION_REG, NOT_RBPU bsf STATUS, RP0 ; RAM PAGE 1 movlw 0x0f ; high speed int osc, POR and BOR movwf PCON movlw DD_PA movwf TRISA ; PA5, PA7 inputs

movlw DD_PB ; RB7-RB4 and RB1(RX)=input, others output movwf TRISB banksel PORTB movlw 0x04 movwf PORTB movwf ResultsB movlw 0x00 movwf PORTA movwf ResultsA ; setup voltage reference banksel VRCON ; bsf TRISA, 2 movlw 0xff ; low range max (3.593V) the length below this treshold could be measured ; and the reference adjusted depending on the voltage applied movwf VRCON

bcf STATUS, RP0 ; PAGE 0 movlw 5 ; comparator 2 only movwf CMCON

BCF PIR1,CMIF ; Clear pending interrupts comp_old_state ; setup timer 0 bsf STATUS, RP0 ; PAGE 0 bcf OPTION_REG, T0CS

clrf temp1 settle decfsz temp1,F goto settle

banksel T1CON movlw 0x20 ; prescale /8, enable timer movwf T1CON ; clrf T1CON movwf timer1_prescaler movlw 0x30 andwf timer1_prescaler, f movlw 0xc8 ; enable global interrupts, peripheral interrupts, interrupt on change of port B movwf INTCON bsf STATUS, RP0 ; RAM PAGE 1 ; bsf PIE1, TMR1IE ; enable timer 1 interrupts, timeout clears any in-progrees IR character reception?? ; postpone enabling the timer ints untill after the test messages have been sent ; to avoid the possibility that we are in place_byte_in_output_buffer() which is otherwise ; used by the interrupt routine movlw 1 ; set time outs to 1 to indicate we are not movwf timer1_timeouts ; in the middle of receiving IR code/char ;

Reply to
Sambo
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.