News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Configuring Comparator for 12F1840

Started by keytapper, Mar 30, 2025, 11:55 AM

Previous topic - Next topic

keytapper

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
Ignorance comes with a cost

Pepe

#1
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

keytapper

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.
Ignorance comes with a cost