News:

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

Main Menu

is there same command with proton?

Started by hitronics, Dec 02, 2022, 08:35 AM

Previous topic - Next topic

hitronics

I see this command with arduino

unsigned long time;_
while(digitaRead(13));
time_ = micros;

how to make same code with proton?


Pepe

this is an example to do this function in Proton

Device = 18F26K22
Declare Xtal = 64
Declare Create_Coff On
Declare Optimiser_Level = 3
Declare Bootloader off
Declare Float_Display_Type = Fast
Declare Dead_Code_Remove = 1        ' Remove dead code
Declare Watchdog Off
Declare Reminders Off

Symbol PLLEN = OSCTUNE.6  ' PLL enable
Symbol PLLRDY = OSCCON2.7 ' PLL run status

Symbol GIEL = INTCON.6  ' Peripheral Interrupt Enable
Symbol GIEH = INTCON.7  ' Global Interrupt Enable

Symbol TMR0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
Symbol TMR0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol IPEN = RCON.7    ' Interrupt Priority Enable bit

Symbol TMR0IP = INTCON2.2' TMR0 Overflow Interrupt Priority bit

Symbol INT2IF = INTCON3.1 ' INT2 External Interrupt Flag
Symbol INT2IE = INTCON3.4 ' INT2 External Interrupt Enable


Symbol    PERIOD      100.0      ; 100 us
Symbol    Xtl          64000000    ; crystal frequency - 16MHz
Symbol    ICLK        (Xtl/4)    ; crystal is divided by four
Symbol    SCALE        8          ; prescale by 8 - check for overflow!

Symbol    PRELOAD        258-(PERIOD*ICLK/SCALE)/1000000
 
 Dim count As Dword
 Dim offset As Byte
 Dim time_ As Dword
 
  OSCCON = $7c

  PLLEN = 1                                    ' Enable PLL 4x 16MHz = 64Mhz

  While PLLRDY = 0 : Wend
 
 
  TRISB = 0xFF
   
 
 On_Hardware_Interrupt GoTo Isr

                   
  IPEN = 1
 
  TMR0IP = 1
 
  T0CON = 0xC2
 
  TMR0IE = 1
 
  INT2IE = 1 
  TMR0L = 0
  GIEH = 1
  GIEL = 1
 
  Clrwdt
 
  WDTCON = 1
 
  offset = 108
 
  While PORTB.0 <> 0
  Wend
 
  time_ = micros()
 
  End
 
 
 Proc micros(),Dword
 Result =  count * 100 + offset + TMR0L/2
 EndProc
 
Isr:

 Context Save
 
 If TMR0IF = 1 Then
                    TMR0IF = 0
                    DelayCS 3
                    TMR0L = PRELOAD
                    Inc count
                   
 End If                 
 Clrwdt 
 
Context Restore

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

;Device = 18F26K22

Declare Reminders Off
@ CONFIG_REQ = 0 ; Override Compiler's configuration settings
Asm-
Config FOSC = INTIO67    ;Internal oscillator block
Config PLLCFG = OFF    ;Oscillator used directly
Config PRICLKEN = On    ;Primary clock enabled
Config FCMEN = OFF    ;Fail-Safe Clock Monitor disabled
Config IESO = OFF    ;Oscillator Switchover mode disabled
Config PWRTEN = On    ;Power up timer enabled
Config BOREN = OFF    ;Brown-out Reset disabled in hardware and software
Config BORV = 190    ;VBOR set to 1.90 V nominal
Config WDTEN = SWON    ;WDT is controlled by SWDTEN bit of the WDTCON register
Config WDTPS = 256    ;1:256
Config CCP2MX = PORTC1    ;CCP2 input/output is multiplexed with RC1
Config PBADEN = OFF    ;PORTB<5:0> pins are configured as digital I/O on Reset
Config CCP3MX = PORTB5    ;P3A/CCP3 input/output is multiplexed with RB5
Config HFOFST = OFF    ;HFINTOSC output and ready status are not delayed by the oscillator stable status
Config T3CMX = PORTB5    ;T3CKI is on RB5
Config P2BMX = PORTB5    ;P2B is on RB5
Config MCLRE = INTMCLR    ;RE3 input pin enabled; MCLR disabled
Config STVREN = OFF    ;Stack full/underflow will not cause Reset
Config LVP = OFF    ;Single-Supply ICSP disabled
Config XINST = OFF    ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
Config Debug = OFF    ;Disabled
Config Cp0 = On    ;Block 0 (000800-003FFFh) code-protected
Config CP1 = On    ;Block 1 (004000-007FFFh) code-protected
Config CP2 = On    ;Block 2 (008000-00BFFFh) code-protected
Config CP3 = On    ;Block 3 (00C000-00FFFFh) code-protected
Config CPB = On    ;Boot block (000000-0007FFh) code-protected
Config CPD = OFF    ;Data EEPROM not code-protected
Config WRT0 = On    ;Block 0 (000800-003FFFh) write-protected
Config WRT1 = On    ;Block 1 (004000-007FFFh) write-protected
Config WRT2 = On    ;Block 2 (008000-00BFFFh) write-protected
Config WRT3 = On    ;Block 3 (00C000-00FFFFh) write-protected
Config WRTC = On    ;Configuration registers (300000-3000FFh) write-protected
Config WRTB = On    ;Boot Block (000000-0007FFh) write-protected
Config WRTD = OFF    ;Data EEPROM not write-protected
Config EBTR0 = OFF    ;Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
Config EBTR1 = OFF    ;Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
Config EBTR2 = OFF    ;Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
Config EBTR3 = OFF    ;Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
Config EBTRB = OFF    ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Endasm-
Declare Reminders On

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------

hitronics

#2
@Pepe I want to use 12F508 MCU :) could you please help, thanks

unsigned long time_;
unsigned long time_1;
unsigned long time_2;
while(digitaRead(13));
time_ = micros;
while(digitaRead(12));
time_1 = micros;
while(digitaRead(11));
time_2 = micros;

Pepe

Cannot use PIC 12F508 because it has no interruptions and does not handle Dword variables

hitronics

#4
Quote from: Pepe on Dec 02, 2022, 04:57 PMCannot use PIC 12F508 because it has no interruptions and does not handle Dword variables
no need for dword variable
is there a way to get counting cycles inside any part of code ?

joesaliba

QuoteDim Time as Word = 0

While PORTB.0 = 0
Inc Time
Delayms 1
Wend

The above will increase variable Time until when PORTB.0 is low.

I think that what are you looking for.

Joe


Pepe

A variable of type word can be increased within the while wend loop and the condition of the input read is returned as true as long as it does not exceed the value 65535 since the successive samples are cumulative

Dim count as word
Dim Time_ as word
Dim Time1_ as word

While gpio.0 <>0
Inc count
Wend
Time_ = count

While gpio.1 <>0
Inc count
Wend
Time1_ = count

hitronics

@joesaliba & @Pepe

could you please have a look at the micros() function with arduino

https://www.arduino.cc/reference/en/language/functions/time/micros

is there an equivalent function at proton?


Pepe

#8
No, there isn't, I've already seen the micros function in arduino, In addition, I have already given you an example that simulates the micros function, the 12f508 cannot do much.

John Drew

#9
What resolution do you need? Assuming your code will do more than measure time there are two best answers.
1) use an interrupt and one of the timers then use multiple loops inside the interrupt to get long periods.
2) choose a chip with an inbuilt hardware clock
You'll need a different chip than the one you have.
John
PS by clock in 2 I meant a time of day clock such as a PIC18F4685 using an external clock crystal.

keytapper

There's no option to compare an Arduino with a poor 12F508. So that function cannot be tailored to a 12F508. The only chance is to know what is the clock rate and use the WDT or the timer0 to have a period, which is definitely higher than one microsecond.
Even Arduino has no precision of one microsecond, but four and it runs at 16 MIPS  ;D
Ignorance comes with a cost

joesaliba

If you want micro seconds then change Delayms 1 to Delayus 1 and read the variable time.

As others suggested, you would not be able to go beyond 65535 as it is a word variable.

Joe

Stephen Moss

I beilve that what the Ariduino code is doing is reading the elapsed time since the program started from Power on or a Reset although why you would want to continiually update that while a pin is held high rather then once when it initially goes high is unclear.

The first solution offered by Pepe is the closest but you are limited by the size of the variable the device can hold, so to essentially repete Pepe' solution...
With a 4MHx clock the instruction clock is 1uS wich is good if you want to mine in uS, however the prescaller in the timer input divides that by two, so you need to ensure the Prescaller is assinged to the WDT then.
1) Clear Timer
2) Start Timer
3) On Timer Interrupt, jump to ISR Increment a variable to count number on Interrupts, clear interrupt flag and exit ISR
4) When the I/O pin concerned is High Time_ = (Number_Interrupts * 256) + Timer0, this calculates the accumulated time to that point.

However...
  • At best you are looking at a word variable for Number_Interrutps so the maximum continous count would (if my math is correct) be 104,200,650uS and so it would roll over every 1.7 minutes.
  • If you wanted longer than that you either have to add more variables to increment when lower variable roll over or divide the timer clock down by its maximum amount which would extend the roll over time to about 7 hours, but as the time in no longer in uS the value you read may have no useable meaning.
  • Most Importantly with regard to such a solution is that the device has no interrupt functionality and so any interrupt based solution is not possible with that device. The solution would have to be interrupt based if you are trying to read the elapsed program run time rather then the duration of the pulse.
   

See_Mos

#13
It would help if we knew what Hitronics is trying to make.

Why use a PIC12F508 is not a very good IC.

Did you know that Hitronics is also the name of an American fibre optics company?

Pepe

Example of how to extract from the assembler a function for example pulsein and place it in a procedure correcting the error for the 12f508