16f877A and tmr1 external crystal question


Closed Thread
Results 1 to 4 of 4
  1. #1

    Default 16f877A and tmr1 external crystal question

    This might be a stupid question... but i'll ask anyways...

    Does the external crystal for TMR1 have to be a crystal or is their other options?
    For example, could i run it from one of the PWM lines... or perhaps an RC method... or some sort of TTL gates....

    Also what about those ceramic resonators... they have 3 pins, how do you connect them? and can i use one on TMR1 (datasheet only briefly says to consult the manufacturers datasheet for caps with resonators, doesn't say you can use them)

    Thanks

  2. #2
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    There are no stupid questions... just stupid answers... and I'll attempt one now... (oops if you read my reply prior to 09:35 just ignore it... Melanie must remember to read the damn Datasheet before giving advice!!!!!!!!)...

    TMR1 DOES have a crystal input capability.

    You can have a CRYSTAL which requires loading Capacitors (connected as per the Datasheet schematic), or you can use a RESONATOR - the three pin types are neat because the middle pin is connected to Ov (Vss) and the outer pins connect to your OSC pins (polarity irrelevant). On those Resonators, the Capacitors are built-in and you don't need any further components.

    You can have any (hopefully) square-wave input as a Counter for TMR1. Any external circuit that is giving pulses... (you want for eample TMR1 to tick at exactly 1Hz, then you can feed it from the output of a DS1307). Yes, you can feed-back a PWM signal as an external counting source for TMR1, but it's too early in the morning and I've had insufficient coffee to attempt to guess why you would want to do this.

  3. #3


    Did you find this post helpful? Yes | No

    Default

    lol, your post time was 9am... my post time was 3am... can you tell i was up late scouring the datasheet... lol

    right... using the onboard PWM means i can set the frequency to what i want and not to the nearest xtal i can find, plus if for any reason i need to change it it's simple to do rarther than look for another xtal... and it makes floating point maths a little easyer!
    To be completely honest, i skipped the section on using the tmr1 as a counter, and now realise i can link the PWM output into TMR1's COUNTER (not clock) input... so efectively, it was a stupid question...

    resonators... cool, thanks for the info... i have one sat in a salvage draw I think it's 4MHz... and yes, i strip componants of dead boards, test then and re-use when needed...
    anyone know what frequency the xtal is for the CMOS on PC motherboards?
    I have a couple of these too but their no markings on them...

    I suppose i could use one of my PICs to do a TMR0(20MHz) - TMR1(unknown xtal) compair, provided the xtals run TMR1...

    Thanks Mell

  4. #4


    Did you find this post helpful? Yes | No

    Default

    hi everyone, i'm back again...
    I'm still having trouble with my RPM counter... it's still giving me stupid readouts...

    i've got PWM1 linked straight into RC0/T1CKI and runing at 50% duty and 1KHz.
    TMR1 is therefor set to counter mode and 1:1 prescaler...

    However, it hapily runs my pulse motor so the control side is fine... but the RPM counter seems to stay at 5727 or 6136 which i don't understand... even when i slow the rotor down by hand it stays at those readings...

    I just don't get why it's doing that... Can someone take a look at my program?

    Thanks

    Code:
    include "bs1defs.bas"
    Define  CONF_WORD = 	0x3F3A
    Define  OSC				24				' Set clock speed
    SEROUT2 PORTB.5,16390,[10,13,10,13]
    DEFINE  SER2_BITS		8				' Ser2 number of data bits
    Define  ADC_BITS        10     			' Set number of bits in result
    Define  ADC_SAMPLEUS    50    			' Set sampling time in uS
    ADCON0.7 = 0							' ADC clock set to Fosc/2
    ADCON0.6 = 0							' ADC clock set to Fosc/2
    ADCON1.6 = 0							' ADC clock set to Fosc/2
    INTCON = 0								' Disable all interupts
    'RCSTA = %10010000						' Enable serial port and continuous receive
    'TXSTA = %00100100						' Enable transmit and asynchronous mode with BRGH 1
    'SPBRG = 20								' Set baud rate to 57600 with 20mhz clock (BRGH = 1)
    ADT1 var word							' Create ADT1 to store curent ad conversion for AD channel 0
    ADT1MAX var word						' Create ADT1MAX to store curent ADC0 max val
    ADT1MAX = 0
    ADT1VAL var word
    ADT1VAL = 0
    ADV1 var word
    VOLT1H var word
    VOLT1L var word
    C1N	var bit
    C1N = 0
    C1S	var bit
    C1S = 0
    PCOUNTER var byte
    PCOUNTER = 0
    PTICK var bit
    PTICK = 0
    RPM var word
    RPM = 0
    TMR1_VAL var word
    TMR1_VAL = 0
    cycle var word
    'aveadc1 var word
    'averpm var word
    TMR1EXT var byte
    rpm0 var bit
    rpm0 = 0
    'datalog var word
    'datalog = 0
    
    'TRISE = 255							' Set PortE to all inputs
    TRISD = 0							' Set PortD to all outputs
    TRISC = 0							' Set PortC to all outputs
    TRISB = 0							' Set PortB to all outputs
    TRISA = 255 						' Set PORTA to all input
    ADCON1 = 0 							' PORTA is analog
    
    PORTB = 0
    PORTC = 0
    PORTD = 0
    
    HPWM 1,127,1000 
    SEROUT2 PORTB.5,16390,["INITIALISED",10,13]
    gosub TMR1setup
    
    goto main
    
    TMR1setup:
    PIE1.0 = 0							' Disable TMR1 interupt (double check)
    T1CON.5 = 0 						' Setup TMR1 timings
    T1CON.4 = 0							' Setup TMR1 timings
    T1CON.3 = 1
    T1CON.1 = 1
    T1CON.0 = 1
    return
    
    main:
    FOR cycle = 1 to 3000
    gosub getadc
    gosub control
    gosub backemfreuse
    gosub rpmcounter
    'gosub avecounter
    NEXT cycle
    gosub adcvonvert
    gosub telemetry
    goto main
    
    getadc:
    ADCIN 0, ADT1
    ADT1 = ADT1 / 64
    'write datalog, adt1.highbyte
    'write datalog+1, adt1.lowbyte
    'datalog=datalog+2
    'if datalog > 255 then
    'datalog = 0
    'endif
    return
    
    adcvonvert:
    VOLT1H = ((48 * ADT1) / 10000)										' calculate voltage above decimal place using FP
    VOLT1L = ((48 * ADT1) - (((48 * ADT1) / 10000) * 10000)) / 100		' calculate voltage below decimal place using FP
    return
    
    'avecounter:
    'aveadc1 = (aveadc1/2) + (ADT1/2)
    'return
    
    rpmcounter:
    if PCOUNTER = 4 then				' wait for 4 pulses befor doing RPM calc
    	T1CON.0 = 0 					' Pause TMR1
    	if PIR1.0 = 1 then				' if TMR1 has overflowed we set the RPM to 0
    		TMR1L = 0
    		TMR1H = 0
    		rpm0 = 1					' Set RPM overide
    		PIR1.0 = 0
    		ENDIF
    	TMR1_VAL.lowbyte = TMR1L		' Load TMR1 Low end byte
    	TMR1_VAL.Highbyte = TMR1H		' Load TMR1 High end byte
    	if rpm0 = 1 then				' RPM overide 
    		RPM = 0						' if RPM overide set RPM to 0
    		'averpm = 0					' if RPM overide set aveerage RPM to 0
    		rpm0 = 0					' if RPM overide RESET rpm OVERIDE
    		ELSE									' If their is no RPM overide...
    		RPM = ((100 / TMR1_VAL) * 60) / 10		' RPM calculation using simple floating point calculations
    		'averpm = (averpm/2) + (RPM/2)			' calculate average RPM
    		ENDIF
    	PCOUNTER = 0					' reset pulse counter to 0
    	TMR1L = 0						' reset TMR1 low to 0
    	TMR1H = 0						' reset TMR1 high to 0
    	gosub TMR1setup
    	T1CON.0 = 1						' restart TMR1
    endif
    return
    
    telemetry:
    'HSEROUT ["V1:",DEC5 VOLT1H,".",DEC5 VOLT1L," RPM:", DEC5 RPM,10,13]
    
    SEROUT2 PORTB.5,16390,["V1:",DEC VOLT1H,".",DEC VOLT1L," RPM:",DEC RPM,10,13]
    rpm = 0								' reset average RPM
    RETURN
    
    control:
    IF ADT1 > 128 then					' wait for positive voltage from trigger coil
    	LOW PORTD.7						' make sure backemf re-use is off
    	high PORTB.0					' commence pulse
    	C1N = 1
    	IF PTICK = 0 then				' if this is the first run to power the dirve coil
    		PCOUNTER = PCOUNTER + 1		' increment the pulse counter
    		PTICK = 1					' makes the tick 1 to stop pcounter being incremented untill drive turns off
    		endif
    	endif
    IF ADT1 < 128 then					' if trigger voltage is low
    	LOW PORTB.0						' turn off drive puls
    	C1N = 0
    	IF PTICK = 1 then				' if pulse tick is high
    		PTICK = 0					' set pulse tick to low
    		endif
    	endif
    return
    
    backemfreuse:
    if C1N = 0 then
    	High PORTD.7
    Else
    	LOW PORTD.7
    endif
    return
    
    end

Similar Threads

  1. TMR1 external LP xtal setup check
    By comwarrior in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 13th October 2009, 19:11

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts