Enabling 12bit A/D on 16 series board

Discuss the Firewing language

Enabling 12bit A/D on 16 series board

Postby Timbo » Mon Apr 13, 2015 8:49 pm

I'm trying to turn on the 12 bit A/D ability of the 16 series pic's

When I say I'm trying, to be honest not very hard at this moment. I need to read the data sheet to see the regs needed but I have tried to look at the lib to see if there was already a switch and where to add the code.

I presume its in the adc module in the Main routine used to do the initialization.


The thing is that you chaps always come through with a little snippet of code when asked so its always worth asking. There may even be some code on the wiki I failed to see.


Thanks

Tim
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Enabling 12bit A/D on 16 series board

Postby Timbo » Mon Apr 13, 2015 9:47 pm

Actually looking at the data sheet, it looks pretty simple..

Just need to set AD12B (AD1CON1: bit 10)
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Enabling 12bit A/D on 16 series board

Postby Jerry Messina » Mon Apr 13, 2015 11:23 pm

There's a note in the datasheet that states that the ADC module must be disabled before modifying the AD12B bit.

Something like this should work...
Code: Select all
sub main()
 dim w as uinteger
 // adc is setup before main starts
 // set adc to 12-bit mode
 AD1CON1.bits(15) = 0   // turn off adc (ADON)
 AD1CON1.bits(10) = 1   // set 12-bit mode (AD12B)
 AD1CON1.bits(15) = 1   // turn module back on
 w = adc.read(A0)
end sub
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Enabling 12bit A/D on 16 series board

Postby Timbo » Tue Apr 14, 2015 6:45 am

Hi, Thanks

Yes I saw that just forgot to mention it when posting, but I really appreciate the code you posted, its not the way I was going to do it which shows I have a lot to learn still.

I may add a new routine that just starts the conversion process. Then at some point later just read the result. I have not looked up the time it takes to do the conversion but as they will mostly be in interrupt code It makes sense not be taking up too much time when it can be done in between interrupts.

Cheers

Tim
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Enabling 12bit A/D on 16 series board

Postby Jerry Messina » Tue Apr 14, 2015 11:16 am

If you're triggering the ADC manually it may not be worth the bother of using interrupts to read it.

The conversion time depends on the settings, but normally it's just a few 10's of usec, if that. Eventually your code will have to wait for the ADC to be done or you'll need to go through the complication of setting up a state machine to do the processing. I tend to use interrupts for events that just can't wait, like reading a uart rx input and such, or if triggering the ADC via some hardware method like a timer.

Of course, that's just my opinion, and every situation is different. You may have a good reason for not wanting to wait...
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Enabling 12bit A/D on 16 series board

Postby Timbo » Tue Apr 14, 2015 11:54 am

Hi Jerry

The way its going to be used is that I read the A/D converter every say 100hz. I intend to do it during an interrupt. I actually will be reading 2 or 3 Analogue inputs. So will be doing it sequentially via a 1000hz interrupt Tick

If the conversion time is only say 10us then I can do it in the interrupt but if its longer its going to be wasting my time in the interrupt. By starting the conversion in one interrupt tick and reading it in the next, no time is wasted.

My coding on another platform always revolved around doing loads in interrupt code. Really it was just Usart int and a 100hz time. But the timer interrupt had large amounts of code running with many state machines.
For example I had routines that would flash a led x times or time how long a button was down. That way your main code is not stuck timing the flashes and can get on with the real processing.

Here is an example of what I mean. The actual time in the interrupt is really very short as only a few lines of code actually gets run.

Code: Select all
TMR_INTERRUPT:

    Context Save  FSR0L, FSR0H, FSR1L, FSR1H
   
    Reset_Bank
     
    If TMR1IF = True Then
   
        Clear TMR1ON                                                ' STOP THE TIMER
        TIMER1REG = TIMER1REG + TMR1_VAL                            ' LOAD TMR1
        Set TMR1ON                                                   ' START THE TIMER AGAIN       
   
        If GPSLoadedTimer > 0 Then
            Dec GPSLoadedTimer                                       ; Every pass we need to check & dec this timer
        EndIf
       
        ; Handle the Vibration and button detection
       
        If INT0IF = 1 Then                                          ; Look for a vibration int flag
            If Vibcounter1 < 200 Then                               ; keep it in a byte range
                Inc Vibcounter1                                     ; Ok seen so up the counter
                INT0IF = 0                                          ; Clear the flag
            EndIf
        EndIf
       
        If Vibcounter1 > 0 Then
            Inc VibTimer1                                           ; manage the count down timer to clear the vibration counter
                If VibTimer1 > 4 Then
                    VibTimer1 = 0
                    Select Vibcounter1
                    Case > 100
                        Vibcounter1 = Vibcounter1 - 10
                    Case > 50
                        Vibcounter1 = Vibcounter1 - 5
                    Case > 20
                        Vibcounter1 = Vibcounter1 - 2
                    Case > 0
                        Dec Vibcounter1
                    EndSelect
                EndIf
        Else
            VibTimer1 = 0
        EndIf
       
        If Vibcounter1 > MinVibrationCnt Then                       ; If the vibration level has been high enough reload or timer
            If GPSStatus = 1 Then                               ; And there is currently a valid fix
               VibOkToLogTimer = InterLogVibTime
            EndIf
        EndIf   
       
        If Vibcounter1 > LedAliveVal Then                           ; Look after the led off timer
            LedOffTimer = LedOffTimerPeriod
        EndIf
       
       
        If WayPointLogButton = 0 Then
            If PushButtonCnt < 254 Then
                Inc PushButtonCnt
                PushButtonReleased = False
            EndIf
        Else
            PushButtonCnt = 0
            PushButtonReleased = True
        EndIf
       
        Hz100Tick = 1
   
       
        ; Handle the second timers
                           
        Dec Hz100Cnt
        If Hz100Cnt = 0 Then
            Hz100Cnt = 100
           
            Btg TwoSecFlag
            If TwoSecFlag = 1 Then
               TwoSecondTick = 1                                                ; Led Brightness Twosecond tick flag
            EndIf
           
            SecondPeriodTimerFlag = 1                                           ; Every second we set these flags
         
            If Uptime < 250 Then
                Inc Uptime                                                      ; Timer used to prevent doing an Eeprom write until the cap has had long enough to charge
            EndIf
           
            ; handle the GPS active timer
            If MilageAccumelationPeriod > 0 Then
                Dec MilageAccumelationPeriod
            EndIf
           
            If InvalidFixDelayTimer > 0 Then
                Dec InvalidFixDelayTimer
            EndIf
                   
            If GPSModuleWorkingTimer > 0 Then
                Dec GPSModuleWorkingTimer
                GPSModuleWorking = True
            Else
                GPSModuleWorking = False
                LedIndicatorStatus = NoGps
                GPSDataLoadingInfo = 0                                          ; We need to clear this so we do not have staggered data
            EndIf   
           
            If SflashFullCntr > 0 Then                                          ; Every second we see if we have to dec the memory flash counter
                Dec SflashFullCntr
            EndIf
               
            If GPSLogPeriodTimer > 0 Then                                       ; Handle our period timer
                Dec GPSLogPeriodTimer
                NewLogPeriod = False
            Else
                NewLogPeriod = True
            EndIf

            If WayPointLogTimer > 0 Then                                        ; The way point timer to control the time between way points being saved
                Dec WayPointLogTimer
            EndIf
           
            If VibOkToLogTimer > 0 Then                                         ; Decrement our Ok to log timer which is loaded when
                Dec VibOkToLogTimer                                             ; we see some vibration
            EndIf
           
            If NoFixTimer > 0 Then
                Dec NoFixTimer
            EndIf 
           
            If NoFixShortTimer > 0 Then
                Dec NoFixShortTimer
            EndIf
           
            If LedOffTimer > 0 Then
                Dec LedOffTimer
            EndIf 
           
            If GPSSpeed >= WarningSpeed Then
                If OverSpeedTimer > GPSSpeedTimeVal Then
                    Inc OverSpeedTimer
                Else
                    OverSpeed = 1
                EndIf
            Else
                OverSpeedTimer = 0
                OverSpeed = 0
            EndIf
           
            If WarningSpeedperiodTimer > 0 Then                                 ; Speed warning timer
                Dec WarningSpeedperiodTimer
            EndIf
           
            If LogExtendTimer > 0 Then
                Dec LogExtendTimer
            EndIf     
        EndIf

; Now handle the Leds
       
        If MemoryFull = False Then
       
            Select LedIndicatorStatus
    ; No Gps System Fault           
            Case NoGps
                If SounderActive = False Then
                    Ledoff
                EndIf
                IntLedOn = 0
                   
    ; Memory full flash has first hit
            Case MemoryLowFlash                                                 ; Flash mode is Memory Low
                If FlashCount > 0 Then   
                    If InterflashTimer > 0 Then
                        Dec InterflashTimer
                    Else
                        Dec FlashCount
                        If LedStatusToggle = 1 Then
                            If LedsAreOff = 0 Then
                                LedOn
                                IntLedOn = 1
                            EndIf
                            LedStatusToggle = 0
                        Else
                            If SounderActive = False Then
                                Ledoff
                                IntLedOn = 0
                            EndIf                           
                            LedStatusToggle = 1
                        EndIf
                        InterflashTimer = FLashPartFullPeriod
                     EndIf
                 Else
                     If GPSStatus = 1 Then                                      ; If the current fix is valid
                        LedIndicatorStatus = GpsWithFix                         ; return to fix mode
                     Else
                        LedIndicatorStatus =  GpsWithNoFix                      ; return to no fix mode
                     EndIf
                     FlashCount = 0                                             ; Ensure this is 0
                 EndIf
    ; Gps Active But no Fix
            Case GpsWithNoFix
                If InterflashTimer > 0 Then
                    Dec InterflashTimer
                Else
                    If LedStatusToggle = 1 Then
                        If LedsAreOff = 0 Then
                            LedOn
                            IntLedOn = 1
                        EndIf
                        LedStatusToggle = 0
                    Else
                        If SounderActive = False Then
                            Ledoff
                        EndIf
                        IntLedOn = 0
                        LedStatusToggle = 1
                    EndIf
                    InterflashTimer = GpsWithNoFixFlashPeriod
                 EndIf
    ; Gps Fixed
            Case GpsWithFix
                 If LedsAreOff = 0 Then
                    LedOn
                    IntLedOn = 1
                 EndIf
    ; Way Point log                           
            Case GPSWayPointLog
                If FlashCount > 0 Then   
                   If InterflashTimer > 0 Then
                       Dec InterflashTimer
                   Else
                    Dec FlashCount
                        If LedStatusToggle = 1 Then
                            LedOn
                            LedStatusToggle = 0
                            IntLedOn = 1
                        Else
                            Ledoff
                            LedStatusToggle = 1
                            IntLedOn = 0
                        EndIf
                        InterflashTimer = GPSWayPointLogFlashPeriod
                     EndIf
                Else
                     LedIndicatorStatus = GpsWithFix            ; Ensure we return to the right mode
                     FlashCount = 0                             ; Ensure this is 0
                     LedStatusToggle = 1
                EndIf           
            EndSelect           
         EndIf
         
; Handle the sounder as required

        Select SounderIndicatorStatus
       
        Case FirstFix   
            If SounderCount > 0 Then
                SounderOn
                Dec SounderCount
            Else
                SounderOff
                SounderIndicatorStatus = NoSound
            EndIf
           
        Case NoFixMovingWarning                                                ; When generating a sound we check if the overal time > 0
            If SounderCount > 0 Then
                Dec SounderCount
                If InterSoundPeriod > 0 Then                                   ; Check the iner toggle period is > 0
                    Dec InterSoundPeriod
                Else
                    If SounderActive = True Then                               ; else toggle it
                        SounderOff
                    Else
                        SounderOn
                    EndIf   
                    InterSoundPeriod = InterSoundPeriodVal                      ; and reload our counter
                EndIf
             Else
                SounderOff
                SounderIndicatorStatus = NoSound                               ; Over all time done so set the state to no sound and shut down the sound
             EndIf
        Case NoFixMovingShortWarning
             If SounderCount > 0 Then                                          ; Single beelp type sounds have no toggle section
                SounderOn
                Dec SounderCount
            Else
                SounderOff
                SounderIndicatorStatus = NoSound
            EndIf
        Case LowMemoryWarning
            If SounderCount > 0 Then
                Dec SounderCount
                If InterSoundPeriod > 0 Then
                    Dec InterSoundPeriod
                Else
                    If SounderActive = True Then
                        SounderOff
                    Else
                        SounderOn
                    EndIf   
                    InterSoundPeriod = InterSoundPeriodVal
                EndIf
             Else
                SounderOff
                SounderIndicatorStatus = NoSound
             EndIf
         Case RemindBusinessTypeWarning                                         ; Toggle between the 2 freqencys for this indicato
            If SounderCount2 > 0 Then
                Dec SounderCount2
                If InterSoundPeriod > 0 Then                               
                    Dec InterSoundPeriod
                Else
                    InterSoundPeriod = InterSoundPeriodVal
                    If SounderActive = True Then
                        SounderOff
                    Else
                        EnableSounderToggle = True
                        Btg SounderFreq
                        SounderOn                                             
                    EndIf                       
                EndIf
             Else
                SounderOff               
                SounderIndicatorStatus = NoSound
             EndIf
         Case WayPointSound
            Select WayPointWoundStage
            Case 0
                If SounderCount2 > 0 Then                                       ; Dit
                    Dec SounderCount2
                    SounderOn
                Else
                    SounderCount2 = WaypointGapTime
                    Inc WayPointWoundStage
                EndIf   
             Case 1
                If SounderCount2 > 0 Then                                       ; space
                    Dec SounderCount2
                    SounderOff
                Else
                    SounderCount2 = WaypointSoundTime1
                    Inc WayPointWoundStage
                EndIf
              Case 2
                If SounderCount2 > 0 Then                                       ; Dit
                    Dec SounderCount2
                    SounderOn
                Else
                    SounderCount2 = WaypointGapTime
                    Inc WayPointWoundStage
                EndIf   
             Case 3
                If SounderCount2 > 0 Then                                       ; space
                    Dec SounderCount2
                    SounderOff
                Else
                    SounderCount2 = WaypointSoundTime1
                    Inc WayPointWoundStage
                EndIf
             Case 4
                If SounderCount2 > 0 Then                                       ; Dit
                    Dec SounderCount2
                    SounderOn
                Else
                    SounderCount2 = WaypointGapTime
                    Inc WayPointWoundStage
                EndIf   
             Case 5
                If SounderCount2 > 0 Then                                       ; space
                    Dec SounderCount2
                    SounderOff
                Else
                    SounderCount2 = WaypointSoundTime2
                    Inc WayPointWoundStage
                EndIf
             Case 6
                If SounderCount2 > 0 Then                                       ; Deeeee
                    Dec SounderCount2
                    SounderOn
                Else
                    SounderOff                                                  ; And shut down
                    SounderIndicatorStatus = NoSound
                EndIf
              EndSelect               
         EndSelect                 
    EndIf
    Clear TMR1IF                                                    ; Clear TMR1 interrupt flag
   
LowIntExit:   
    Context Restore
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Enabling 12bit A/D on 16 series board

Postby Jerry Messina » Tue Apr 14, 2015 12:47 pm

See - I knew there'd be a good reason!

> By starting the conversion in one interrupt tick and reading it in the next, no time is wasted.
That sounds like a good idea. I don't like to wait at all inside an ISR since it will block other interrupts unless you set up priorities and that can just make things more complicated. It's not too bad with one or two levels like the PIC18, but much past that and I begin to get myself in trouble!
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Enabling 12bit A/D on 16 series board

Postby Timbo » Tue Apr 14, 2015 2:04 pm

Hi Jerry

Thanks thats sound advice I have little or no experience with the 24 series devices. I like not having to learn the hardway ;)
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm


Return to Language

Who is online

Users browsing this forum: Google [Bot] and 1 guest

cron

x