I'm trying to find out what are the necessary registers to configure the comparator that will gate the timer 1 and then counting the period for a complex sine wave.
Device 12F1840
Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF,_
BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_ON, STVREN_OFF,LVP_OFF
Declare Xtal 32
On_Hardware_Interrupt GoTo ISRhandler
Symbol C1IE PIE2.5 ' Comparator 1 interrupt Enable
Symbol C1IF PIR2.5 ' Comparator 1 interrupt Flag
Symbol C1POL CM1CON0.4 ' Comparator 1 Polarity
Symbol C1INTP CM1CON1.7 ' Comparator 1 interrupt positive edge
Symbol C1INTN CM1CON1.6 ' Comparator 1 interrupt negative edge
Symbol PEIE INTCON.6 ' Peripheral interrupt Enable
Symbol GIE INTCON.7 ' Generak interrupt Enable
Symbol TMR1ON T1CON.0 ' timer 1 start
Dim timerValue As Byte ' Start time for period measurement
C1CON0.C1ON = 1
ANSELA = 1
TRISA = 1
PORTA = 0
LATA = 0
WPUA = 0
OPTION_REG = 0
CM1CON0 = 0b10010001 ; Enable comparator 1, rising edge interrupt
CM1CON1 = 0b00000101
; Configure positive/negative inputs, use 2.048 V as reference.
; but probably i opt for an external VDD divider.
FVRCON = 0b1010010
C1IE = 1 ' Enable comparator interrupt
GIE = 1 ' Enable global interrupt
PEIE = 1 ' Enable peripheral interrupt
C1IF = 0 ' Clear comparator interrupt flag
' Enable Timer1 Gate, select Comparator1 output as gate source
T1GCON = 0b11000000
' Enable Timer1, set prescaler, choose clock source
T1CON = 0b00110001
Clear TMR1L ' starting from zero
Clear TMR1H ' starting from zero
End
ISRhandler:
Context Save
If C1IF = 1 Then ' Comparator interrupt detected
Clear C1IF ' Clear interrupt flag
Clear TMR1ON ' Turn off Timer1
timerValue = TMR1L ' Collect Timer1 value
TMR1L= 0 ' Reset Timer1
If C1INTP = 0 Then
Set C1INTP ' Switch to rising edge detection
Clear C1INTN ' clear falling edge detection
Else
Clear C1INTP ' Switch to falling edge detection
Set C1INTN ' clear rising edge detection
End If
Set TMR1ON ' Turn it back on
End If
Context Restore
test this
Device = 12F1840
Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF,_
BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_ON, STVREN_OFF,LVP_OFF
Declare Xtal 32
Declare Create_Coff On
Declare Optimiser_Level = 3
Declare Watchdog Off
Declare HRSOut_Pin = PORTA.0
Declare Hserial_Baud = 9600
On_Hardware_Interrupt GoTo ISRhandler
Symbol C1IE PIE2.5 ' Comparator 1 interrupt Enable
Symbol C1IF PIR2.5 ' Comparator 1 interrupt Flag
Symbol C1POL CM1CON0.4 ' Comparator 1 Polarity
Symbol C1INTP CM1CON1.7 ' Comparator 1 interrupt positive edge
Symbol C1INTN CM1CON1.6 ' Comparator 1 interrupt negative edge
Symbol PEIE INTCON.6 ' Peripheral interrupt Enable
Symbol GIE INTCON.7 ' Generak interrupt Enable
Symbol TMR1ON T1CON.0 ' timer 1 start
Dim timerValue As Byte ' Start time for period measurement
Dim timerVal As Byte ' Start time for period measurement
OSCCON= $73
ANSELA = 0
TRISA = 0b10000
PORTA = 0
LATA = 0
WPUA = 0
OPTION_REG = 0
CM1CON0 = 0b10010001 ; Enable comparator 1, rising edge interrupt
CM1CON1 = 0b10100001
; Configure positive/negative inputs, use 2.048 V as reference.
; but probably i opt for an external VDD divider.
FVRCON = 0b10011010
PEIE = 1 ' Enable peripheral interrupt
C1IF = 0 ' Clear comparator interrupt flag
' Enable Timer1 Gate, select Comparator1 output as gate source
T1GCON = 0b11000000
' Enable Timer1, set prescaler, choose clock source
T1CON = 0b00110001
Clear TMR1L ' starting from zero
Clear TMR1H ' starting from zero
C1IE = 1 ' Enable comparator interrupt
GIE = 1 ' Enable global interrupt
Do
If timerValue<> timerVal Then
timerVal= timerValue
HRSOutLn Dec timerVal
EndIf
Loop
End
ISRhandler:
Context Save
If C1IF = 1 Then ' Comparator interrupt detected
timerValue = TMR1L ' Collect Timer1 value
TMR1L= 0 ' Reset Timer1
Clear C1IF ' Clear interrupt flag
End If
Context Restore
Thank you so much, Pepe.
It's great how you care for the community, I also appreciate it.
Coming to my simulation test I found my flaws:
1) I configured RA0 for the input. I presume there would be a change to configure it. But is not essential.
2) I Set FVRCON for a high level. Probably I look for an external voltage reference.
3) It seems that the analog filters in VSM are not well suited.
4) I should understand whether is necessary to set the edge polarity, to measure one sine width, positive or negative.
5) I am trying to decode DTMF by the sine measurement. But I prefer to use the 12F1840, because I currently have it. There could be 18F MCU capable to use trigonometry an Goertzerl algorithm, but it's my challenge and amusement.
demo proteus dtmf for 12f1840
Quote from: Pepe on Apr 01, 2025, 08:14 PMdemo proteus dtmf for 12f1840
You're a great master! Thank you sooooo much
Eres un gran maestro!! muchas gracias
The only case is when I want to change the default USART port. But this another thread.
You save my day.