PDA

View Full Version : 32.768kHz external crystal for TMR1 time base and internal 4MHz oscillator



flotulopex
- 17th March 2017, 13:15
Hi there,

I'd like to have my external 32.768kHz crystal as time base onTMR1 and, in the same time, run the internal oscillator at 4MHz.

Thoretically, this simple code hereunder should blink my LED only when the TMR1IF overflow flag is set.

But...

This code works erratically:
- sometimes the program starts, sometimes not
- commenting the fuses will mostly make the program start almost always
- physically removing the 32.768kHz crystal from my breadboard will change nothing => when the program works, the LED still blinks?!


' ====== FUSES ================================================== ==================================
' PIC 16F690
@ __Config _FCMEN_ON &_IESO_OFF &_CPD_OFF &_WDT_OFF &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF &_LP_OSC

' ====== INTERRUPT SERVICE ROUTINE ================================================== ==============
GOTO INIT: ' Just to place ISR at top of program
DISABLE
ISR: 'if TMR1IF is set (TMR1 has overflown)
toggle PORTB.6 'LED
PIR1.0 = 0 ' clear TMR1IF overflow flag
resume
ENABLE

' ====== INITIALIZE ================================================== =============================
INIT:
PAUSE 1000 'circuit settle time

' ====== DEFINES ================================================== ================================
DEFINE OSC 4

' ====== REGISTERS ================================================== ==============================
' 76543210
OPTION_REG = %10000000 ' Pull-Ups disabled
OSCCON = %01100000 ' Internal RC set to 4Mhz
ANSEL = %00000000 ' Analog inputs Channels 0 to 7
ANSELH = %00000000 ' Analog inputs Channels 8 to 11
INTCON = %11000000 ' INTerrupts CONtrol: GIE is ON, PEIE is ON
T1CON = %00111001 ' Timer1 OSC enabled, Timer1 enabled, presc.1:8
PIE1 = %00000001 ' Enable TMR1IF overflow flag

' ====== PROGRAM ================================================== ================================
ON INTERRUPT GOTO ISR

MAIN:
goto MAIN:
END

Setting the FCMEN to OFF will never let the program run which lets me think the 32.768Khz crystal doesn't actually run at all. But le LED blinks?!

What am I missing?

richard
- 17th March 2017, 20:56
TMR1CS:
Timer1 Clock Source Select bit



T1CON = %00111011 ' Timer1 OSC enabled, Timer1 enabled, presc.1:8

richard
- 17th March 2017, 22:51
plus config needs to enable internal osc

__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_ON & _FCMEN_ON

flotulopex
- 17th March 2017, 23:20
I've modified the code according to the answers.

But with or without the 32,768kHz crystal, the LED will always blink.

As per datasheet, I have enabled LP oscillator. Why should I set the internal oscillator instead please?

Same question for T1CON.TMR1CS; why should I set this one?


' ====== FUSES ================================================== ==================================
' PIC 16F690
__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_ON & _FCMEN_ON

' ====== INTERRUPT SERVICE ROUTINE ================================================== ==============
GOTO INIT: ' Just to place ISR at top of program
DISABLE
ISR: 'if TMR1IF is set (TMR1 has overflown)
toggle PORTB.6 'LED
PIR1.0 = 0 ' clear TMR1IF overflow flag
resume
ENABLE

' ====== INITIALIZE ================================================== =============================
INIT:
PAUSE 1000 'circuit settle time

' ====== DEFINES ================================================== ================================
DEFINE OSC 4

' ====== REGISTERS ================================================== ==============================
' 76543210
OPTION_REG = %10000000 ' Pull-Ups disabled
OSCCON = %01100000 ' Internal RC set to 4Mhz
ANSEL = %00000000 ' Analog inputs Channels 0 to 7
ANSELH = %00000000 ' Analog inputs Channels 8 to 11
INTCON = %11000000 ' INTerrupts CONtrol: GIE is ON, PEIE is ON
T1CON = %00111011 ' Timer1 OSC enabled, Timer1 enabled, presc.1:8
PIE1 = %00000001 ' Enable TMR1IF overflow flag

' ====== PROGRAM ================================================== ================================
ON INTERRUPT GOTO ISR

MAIN:
goto MAIN:
END

richard
- 17th March 2017, 23:37
As per datasheet, I have enabled LP oscillator. Why should I set the internal oscillator instead please?

if I understand correctly your intent is to use the intosc @4mhz for cpu clock and the ext osc @32khz for timer1 clk source

so to use the HFINTOSC @4mhz config= _INTRC_OSC_NOCLKOUT [no clk out assumed]
osccon= $60


Same question for T1CON.TMR1CS; why should I set this one?

to use the ext osc for timer1

you must enable the ext osc
bit 3 T1OSCEN: LP Oscillator Enable Control bit
and
select ext osc as timer clock source
bit 1 TMR1CS: Timer1 Clock Source Select bit

so t1con= %00111011 with 8:1 prescale and timer on

richard
- 17th March 2017, 23:45
the data sheet says that T1OSCEN should be enable and the user should delay for a suitable time before timer is enabled

I don't have a 16f690 handy to test with

flotulopex
- 18th March 2017, 00:03
Thanks a lot Richard,

The code hereunder works :)

BTW, I had to change the config settings (fuses) since you might have copied them for another PIC and generated errors while compiling. Please let me know if I should take care to change some of them.

For the test, I removed the 32,768kHz crystal while running (:eek:) and the LED stops blinking which is correct.


' ====== FUSES ================================================== ==================================
' PIC 16F690
@ __config _INTRC_OSC_NOCLKOUT &_WDT_OFF &_PWRTE_OFF &_MCLRE_OFF &_CP_OFF &_CPD_OFF &_BOR_OFF &_IESO_OFF &_FCMEN_OFF

' ====== INTERRUPT SERVICE ROUTINE ================================================== ==============
GOTO INIT: ' Just to place ISR at top of program
DISABLE
ISR: 'if TMR1IF is set (TMR1 has overflown)
toggle PORTB.6 'LED
PIR1.0 = 0 ' clear TMR1IF overflow flag
TMR1H = 0
TMR1L = 0
resume
ENABLE

' ====== INITIALIZE ================================================== =============================
INIT:
PIR1.0 = 0 ' clear TMR1IF overflow flag
TMR1H = 0
TMR1L = 0

' ====== DEFINES ================================================== ================================
DEFINE OSC 4

' ====== REGISTERS ================================================== ==============================
' 76543210
OPTION_REG = %10000000 ' Pull-Ups disabled
OSCCON = %01100000 ' Internal RC set to 4Mhz
ANSEL = %00000000 ' Analog inputs Channels 0 to 7
ANSELH = %00000000 ' Analog inputs Channels 8 to 11
INTCON = %11000000 ' INTerrupts CONtrol: GIE is ON, PEIE is ON
T1CON = %00111011 ' Timer1 OSC enabled, Timer1 enabled, presc.1:8
PIE1 = %00000001 ' Enable TMR1IF overflow flag

' ====== PROGRAM ================================================== ================================
PAUSE 1000 'circuit settle time

ON INTERRUPT GOTO ISR

MAIN:
goto MAIN:
END

richard
- 18th March 2017, 00:22
BTW, I had to change the config settings (fuses) since you might have copied them for another PIC and generated errors while compiling. Please let me know if I should take care to change some of them.
config was generated by meCONFIG for pbp3

flotulopex
- 20th March 2017, 09:34
config was generated by meCONFIG for pbp3I have 2.6 so this may be why there is a change ;)