News:

Let's find out together what makes a PIC Tick!

Main Menu

Fraction Calculations

Started by Fanie, Aug 12, 2025, 11:12 AM

Previous topic - Next topic

Fanie

What is the difference between the calculation speed of the 16F pics vs the 18F pics when dealing with fractions at the same clock speed ?

What is the difference between the calculation speed of the 18F pics vs the 24F pics when dealing with fractions at the same clock speed ?

trastikata

#1
Hello Fanie, can clarify what do you mean by fractional calculations?

Did you mean for example multiplication of two floating point variables?

Or you meant the fixed point arithmetic acceleration available in PIC24F devices compared to emulated fixed point arithmetic in 18F and 16F devices?

Fanie

#2
Yes, multiplication / division of values by 0,1 to 0,01

I think I may have to use a 24F pic in any case.

There is a glitch in the software (or somewhere else.  Will post the code in the next post and what it does.

Frizie

I hardly ever use fractions (float), even though I use the MCP3422 ADC to display the distance between two rollers with a resolution of 0.01 mm.
For example:

DIM Distance AS WORD
Distance = 12345
PRINT DEC Distance / 100, ".", DEC2 Distance // 100, "mm"


Wil display 123.45mm
Ohm sweet Ohm | www.picbasic.nl

trastikata

Les' Positron 24 has really well optimized floating point routines and they are quite faster than the 8-bit routines - I have an extremely computational intensive program for IR imaging sensors which is ruining quite fast on a dsPIC33.

If you are looking for faster calculations, take a dsPIC33 instead of the PIC24, you can run the former at 160 MHz.

Fanie

I have a simple application that has to change an input frequency to less or more.
There is an input and an output for this.
There are two LED's as simple indicators.
There are two switches, one decrease the output frequency, the next increase the frequency.

The code is working, I do however find that a sporadic glitch happens and not sure if it is hardware or software.

I'm using a 18F14K50 currently, it just seems a huge micro to perform such an app.  I was hoping to get a 16 bit 12 pin TQFP but no.  And then I have to consider what is available here, seems the 24FJ16MC102 but in a SOIC and cost roughly the same as the 18F but with potentially better performance.

There may be a better way to do the software. If there is I am keen to learn.

Device = 18F14K50    ' 24FJ16MC102     '32CM5164JH00032T

Xtal = 32

Config_Start
   FOSC = IRC        ; Internal RC oscillator
   PLLEN = On       ; PLL is under software control
   PCLKEN = OFF      ; Primary clock is under software control     
   FCMEN = OFF       ; Fail-Safe Clock Monitor disabled         
   IESO = On        ; Oscillator Switchover mode enabled
   PWRTEN = On      ; PWRT enabled
   BOREN = Off      ; Brown-out Reset enabled and controlled by software (SBOREN is enabled)
   BORV = 30        ; VBOR set to 2.2 V nominal
   WDTEN = OFF      ; WDT is controlled by SWDTEN bit of the WDTCON register
   WDTPS = 64
   MCLRE = OFF      ; RA3 input pin enabled; MCLR disabled
   HFOFST = On      ; The system clock is held off until the HF-INTOSC is stable.
   STVREN = On      ; Stack full/underflow will cause Reset
   LVP = Off        ; (Single-Supply icsp ?) Low Voltage programming disabled
   BBSIZ = OFF        ; 1kW boot block size
   XINST = On        ; Instruction set extension and Indexed Addressing mode enabled
   Cp0 = On            ; Block 0 code-protected
   CP1 = On         ; Block 1 (002000-003FFFh) code-protected
   CPB = On         ; Boot block (000000-0007FFh) code-protected
   CPD = On         ; Data EEPROM code-protected
   WRT0 = OFF       ; Block 0 (000800-001FFFh) not write-protected
   WRT1 = OFF       ; Block 1 (002000-003FFFh) not write-protected
   WRTB = OFF       ; Boot block (000000-0007FFh) not write-protected
   WRTC = OFF       ; Configuration registers (300000-3000FFh) not write-protected
   WRTD = OFF       ; Data EEPROM not write-protected
   EBTR0 = OFF      ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
   EBTR1 = OFF      ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
   EBTRB = OFF      ; Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
      
TRISA = %00001000               ' Configure I/O
TRISB = %11000000
TRISC = %00001000
Bcf ANSEL.7                     ' disable A/D cha 7 to make portC3 a digital input

ADCON0 = %00101100              ' Set analogue inputs on AN11       01 enable ADC 00 disable ADC
ADCON1 = %00000000              ' AD control reg
ADCON2 = %1001011
OSCCON = %01101100             '
                                ' %01011100 select internal 4 MHz clock defined by FOSC<2:0> of the CONFIG1
                                ' -111---- = 16MHz   1MHz
                                ' -110---- = 8MHz    500kHz
                                ' -101---- = 4MHz    250kHz
                                ' -100---- = 2MHz
OSCCON2 = %00000111
OSCTUNE = %11000000             'b7 = INTSRC, b6 = PLLEN, b0-5 = max freq
'Config1H.3 = 1
'WDTCON =  %00000000
'ewrite 300001, [%10111000]     'Config1H = %00001000     Int RC Osc    ***** clock *****
                               'PLL enabled CLK x 4

Dim Cnti As Dword               ' Count cycles in
Dim Cntitot As Float
Dim Cnto As Dword               ' Count cycles out
Dim FacTor As Float
Dim Vin As Dword                ' Voltage input
Dim Tin As Float                '
Dim FNew As Dword
Dim A As Bit
Dim B As Bit
Dim Dis3 As Byte       
Dim Tel As Byte
Dim Braam As Byte

Symbol NCA0 = PORTA.0            ' NC output                         o
Symbol NCA1 = PORTA.1            ' NC Output                         o
Symbol NCA2 = PORTA.2            ' NC Output                         o

Symbol NCA4 = PORTA.4            ' NC Output                         o
Symbol LedR = PORTA.5            ' LedR                              o

Symbol NCB4 = PORTB.4            ' NC Output                        0
Symbol Fn1 = PORTB.5            ' Analog 11 Pot                     i   An
Symbol Sw2 = PORTB.6            ' Sw2 Input                         i
Symbol Sw1 = PORTB.7            ' Sw1 Input                         i
                           
Symbol FOut = PORTC.0            ' Freq Output                       o
Symbol NCC1 = PORTC.1              ' NC Output                         0
Symbol NCC2 = PORTC.2            ' NC Output                         0
Symbol Fin = PORTC.3            ' Freq Input                        i

Symbol LedY = PORTC.4           ' LedY Output                       0
Symbol LedG = PORTC.5           ' LedG Output                       o
Symbol FinA = PORTC.6            ' Freq Input Analog                 i
Symbol NCC7 = PORTC.7            ' NC Output                         0

PORTA = 0 : PORTB = 0 : PORTC = 0

'********************************************************
'*              Main Program Starts Here
'********************************************************

Start: 
           Tin = 0
           Cnti = 0
           FOut = 1
           FacTor = ERead 10
           DelayMS 20
                If FacTor < 0.20 Or FacTor > 100 Then
                FacTor = 1.07                    ' was 1
                EWrite 10, [FacTor]
                DelayMS 20
                EndIf
               
           Cnti = 10000                  'was 1000

           Cnto = 20000                  ' Was 10000   8000  2000    100
           Cntitot = 10000               ' Was 10000   8000  2000    100
          
           LedR = 1 : LedG = 1 : DelayMS 50 : LedR = 0 : LedG = 0 : DelayMS 50
           LedR = 1 : LedG = 1 : DelayMS 50 : LedR = 0 : LedG = 0 : DelayMS 50
           LedR = 1 : LedG = 1 : DelayMS 50 : LedR = 0 : LedG = 0 : DelayMS 50
          
           GoTo InloOutHi
  
' cnto & cnto1 value
' 1700 ~ 6000rpm  2000 ~ 5000rpm  4000 ~ 2500rpm  10000 = 1000rpm  20000 = 500rpm  30000 = 250rpm  40000 = 100rpm   50000 ~ 50 rpm
           
       
InHiOutHi:     ' Input High and Output High

            FOut = 1
            LedR = 1
            PORTC.0 = 1
            PORTA.5 = 1
            If Fin = 1 Then Cnti = Cnti + 1
           
            If Fin = 0 Then
                Cntitot = Cntitot * 5
                Cntitot = Cntitot + Cnti
                Cntitot = Cntitot / 6
                GoTo InloOutHi
                EndIf
               
            Cnto = Cnto - 1
          
            If Cnto = 0 Then
                GoSub Calcul
                LedG = 0
                GoTo InhiOutLo
                EndIf
           
            GoTo InHiOutHi
           
InhiOutLo:     ' Input High and Output Low

            FOut = 0
            LedR = 1
            PORTC.0 = 0
            PORTA.5 = 1
            If Fin = 1 Then Cnti = Cnti + 1
           
           
            If Fin = 0 Then
                Cntitot = Cntitot * 5
                Cntitot = Cntitot + Cnti
                Cntitot = Cntitot / 6
                GoTo InLoOutLo
                EndIf
           
            Cnto = Cnto - 1
           
            If Cnto = 0 Then
                GoSub Calcul
                LedG = 1
                GoTo InHiOutHi
                EndIf
           
            GoTo InhiOutLo
 
InloOutHi:     ' Input Low and Output High
           
            FOut = 1
            LedR = 0
            PORTC.0 = 1
            PORTA.5 = 0
            If Fin = 1 Then
                Tin = 0
                Cntitot = Cntitot * 5
                Cntitot = Cntitot + Cnti 
                Cntitot = Cntitot / 6
                Cnti = 0
                GoTo InHiOutHi
                EndIf
               
            Cnto = Cnto - 1
           
            If Cnto = 0 Then
                PORTC.5 = 0
                Tin = Tin + 1
                GoSub Calcul
                LedG = 0
                GoTo InLoOutLo
                EndIf
           
            GoTo InloOutHi
     
InLoOutLo:     ' Input Low and Output Low
           
            FOut = 0
            LedR = 0
            PORTC.0 = 0
            PORTA.5 = 0
            If Fin = 1 Then
                Tin = 0
                Cntitot = Cntitot * 5
                Cntitot = Cntitot + Cnti
                Cntitot = Cntitot / 6
                Cnti = 0
                GoTo InhiOutLo
                EndIf
                           
            Cnto = Cnto - 1
           
            If Cnto = 0 Then
                PORTC.5 = 1
                Tin = Tin + 1
                GoSub Calcul
                LedG = 1
                GoTo InloOutHi
                EndIf
 
            GoTo InLoOutLo
           
 '**************************************************************************
'                       SUBROUTINES START HERE
'***************************************************************************           
 
' cnto value vs output
' 1700 ~ 6000rpm  2000 ~ 5000rpm  4000 ~ 2500rpm  10000 = 1000rpm  20000 = 500rpm  30000 = 250rpm  40000 = 100rpm   50000 ~ 50 rpm           

Calcul:
            If Tin > 7 Then
               Cntitot = 50000
               Tin = 7     ' tin was 5 , was 7
               EndIf      
           
            Cnto = Cntitot * FacTor ' 0.25
            
            If Cnto < 100 Then  
               Cntitot = 100
               EndIf   ' Max output frequency, Less is faster (300)
           
            If Cnto > 50000 Then
               Cnto = 50000
               EndIf
           
            Dis3 = Dis3 + 1
           
            If Dis3 > 50 Then
                Dis3 = 0
                If Sw2 = 1 Then FacTor = FacTor - 0.01 : A = 1 : EndIf
                If FacTor < 0.10 Then FacTor = 0.10 : EndIf             ' was 0.20
                If Sw1 = 1 Then FacTor = FacTor + 0.1 : A = 1 : EndIf
                If FacTor > 40 Then FacTor = 40
                If Sw1 = 1 And Sw2 = 1 Then
                   FacTor = FacTor - 1
                   A = 1
                   If FacTor > 60 Then FacTor = 60              ' was 40
                   If FacTor < 0.10 Then FacTor = 0.10          ' Was 0.20
                   EndIf
                  
            If Sw1 = 0 And Sw2 = 0 And A = 1 Then
                'LedR = 0 : LedG = 0 : DelayMS 2
                EWrite 10, [FacTor]
                DelayMS 20
                A = 0
                EndIf
                       
            EndIf
                                            ' mul by 4 max range freq in
                                            ' devide by 2 = 200Hz FS
                                            ' devide by 3 = 150Hz FS
                                            ' devide by 4 = 100Hz FS
          
            Return

            End

top204

#6
In your code, disable the Extended Instructions in the config fuses:

XINST = Off        ; Instruction set extension and Indexed Addressing mode disabled

The compiler does not use these, 'rather redundant', mnemonics and device map, and it will alter the code's operations because it changes the device's memory map, and some other mnemonic operations.

Fanie

Input frequency is not very high, 0 to 600Hz

Thank you Les.