Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

'standard' PIC clock freqs?

Status
Not open for further replies.

Mike - K8LH

Well-Known Member
I'm trying to design a simple set of Dallas/Maxim One-Wire assembly procedures/functions and I'd like to support a 'standard' set of Clocks for the delay routines.

What 'standard' set of frequencies should I support? 4, 8, 10, 16, 20, 32, 40?

On a similar note, does anyone have 'generic' delay code they'd like to share? I've come up with a simple method (below) that doesn't require a GPR variable but it's only good for delay value constants known at compile time.

Mike

Code:
;******************************************************************
;
;  DelayUS Macro (for constant values known at compile time)
;
;  passed parameter: 10 to 1289 (usecs in 1 usec steps)
;
DelayUS macro   pTime           ;
        movlw   (pTime/5)-1     ;                                 |B0
        call    Delay5us-(pTime%5)
        endm
;
;******************************************************************
        if Clock == 8
;******************************************************************
;
;  Delay code for 8-MHz clock (14 bit core)
;
        goto    $+1             ; 1 usec                          |B0
        goto    $+1             ; 1 usec                          |B0
        goto    $+1             ; 1 usec                          |B0
        goto    $+1             ; 1 usec                          |B0
Delay5us
        call    Wx              ; 2 usec                          |B0
        goto    $+1             ; 1 usec                          |B0
        addlw   -1              ;.5 usec                          |B0
        skpz                    ;.5 usec                          |B0
        goto    Delay5us        ; 1 usec                          |B0
        call    Wx              ; 2 usec                          |B0
        nop                     ;.5 usec                          |B0
Wx      return                  ; 2 usec                          |B0
;******************************************************************
        endif
        if Clock == 4
;******************************************************************
;
;  Delay code for 4-MHz clock (14 bit core)
;
        nop                     ; 1 usec                          |B0
        nop                     ; 1 usec                          |B0
        nop                     ; 1 usec                          |B0
        nop                     ; 1 usec                          |B0
Delay5us
        nop                     ; 1 usec                          |B0
        addlw   -1              ; 1 usec                          |B0
        skpz                    ; 1                               |B0
        goto    Delay5us        ; 2 usec                          |B0
        nop                     ; 1 usec                          |B0
        return                  ; 2 usec                          |B0
;******************************************************************
        endif
 
hi Mike,

I use 4,10 & 20MHz xtals/modules
The 4 & 20 for my 16F877 series and the 10MHz with the 18F452 series [PLL]

Attached a microchip MPLAB Delay extract for your reference.
 
Last edited:
hi,
Looking thru the microchip PIC 16Fxxx data they also list 3.6864MHz and 16MHz Xtals in their data for baud rate selection.
Which suggests its a popular crystal frequency.
 
Eric,

I was wondering if someone was going to mention the usart frequency crystals (grin). I can't imagine how to support them in simple general purpose timing/delay routines.

Does anyone use the usart frequency crystals? I would think they're unnecessary especially when using some of the more recent PIC devices with a 16-bit baud rate generator.

Mike
 
Last edited:
Mike,

In the past [Z80/Z84C90] days I have used 2.4576, 4.91 and 9.83 MHz xtals for RS232 work

Also 4.19MHz xtal's for dividing down to a 1 Sec interval.

In my MPLAB IDE, I have a short conditional assembly routine which checks the value of a
Variable: Xtal1 EQU NN and it preloads the high byte of a Delay loop counter with the appropriate value for the Xtal clock frequency.

The lower byte is loaded by a Macro and is 'LOOPMS .1' thru .255 millisec.

As I sometimes use the PIC Sim, I also use another Variable: Sim1 EQU 0 or 1 and a conditional assembly routine
at the start of the 'Delay Subr', this way if I set Sim1= 1 then all the LCD delays are skipped.
 
Eric,

Thanks for the info'. I'm just starting to discover how to use conditional assembly directives. They're pretty cool.

Mike
 
Mike said:
Eric,

Thanks for the info'. I'm just starting to discover how to use conditional assembly directives. They're pretty cool.

Mike

Hi Mike,

It seems we are the only two members using crystals!:eek:

I wonder what the others use?:confused:
 
ericgibbs said:
Hi Mike,

It seems we are the only two members using crystals!:eek:

I wonder what the others use?:confused:

I use a 555 as that is the best timepiece ever.:D

Mike.
 
ericgibbs said:
Hi Mike,

It seems we are the only two members using crystals!:eek:

I wonder what the others use?:confused:

I use crystals when it gives value using one, otherwise it's just a waste. If the PIC has an internal oscillator option I use that, if it's appropriate, which in most cases it is - and it gives you two extra I/O pins.
 
ericgibbs said:
Hi Mike,

It seems we are the only two members using crystals!:eek:

I wonder what the others use?:confused:
I use crystal too, 4 MHz and sometimes internal oscillator.


I didn't know that you can do this in assembler:
Code:
        movlw   (pTime/5)-1     ;                                 |B0
        call    Delay5us-(pTime%5)
Are they assembler directives? I really don't know about them. :(
 
bananasiong said:
I didn't know that you can do this in assembler:
Code:
        movlw   (pTime/5)-1     ;                                 |B0
        call    Delay5us-(pTime%5)
Are they assembler directives? I really don't know about them. :(
The assembler is perfectly capable of evaluating expressions. You just need to remember that the assembler can only evaluate expressions with values that are known at assembly time. In this case the Delay routines I'm building only work with constant values as parameters but that's all I really need.

Mike
 
So if I want to call a delay say for 750 us, I just define everything as yours and
Code:
DelayUS 750
;
;
right?
The a few goto $+1 and nop are not included in the called delay right?
 
Yes, that's the idea.

The instructions before the Delay5US label are part of the delay code. They're used when the delay value is xxx1, xxx2, xxx3, xxx4, xxx6, xxx7, xxx8, or xxx9 usecs (entry point determined by the call Delay5us-(pTime%5) instruction).

And you realize there's a different subroutine for each different Clock frequency, right? Only one subroutine will get assembled depending on the Clock define (example; #define Clock 8 ).
 
Last edited:
Mike said:
Yes, that's the idea.

The instructions before the Delay5US label are part of the delay code. They're used when the delay value is xxx1, xxx2, xxx3, xxx4, xxx6, xxx7, xxx8, or xxx9 usecs (entry point determined by the call Delay5us-(pTime%5) instruction).
Interesting! But I couldn't install MPLAB in my working computer, I have to see the disassembler listing in MPLAB when I get back home :)
And you realize there's a different subroutine for each different Clock frequency, right?
Ya, I did notice that. But I didn't realize goto takes 2 instruction cycle until I read the datasheet.

Only one subroutine will get assembled depending on the Clock define (example; #define Clock 8 ).
I never define the clock frequency usually because I only stick on 4 MHz.
 
Last edited:
bananasiong said:
I never define the clock frequency usually because I only stick on 4 MHz.
In that case you would simply cut and paste the macro and the 4-MHz code, which by the way has been updated and simplified. The delay routines still do not use any variables. I just trimmed them down a bit.

Code:
        radix   dec
        if Clock == 4
;******************************************************************
;                                                                 *
;  DelayUS() code, 4-MHz clock, 8..1031 usecs   {K8LH, Jun-'07}   *
;                                                                 *
;  requires the use of constant operands known at assembly time   *
;  due to expression evaluation for correct routine entry point   *
;                                                                 *
;  the calling code is generated by this macro;                   *
;                                                                 *
DelayUS macro   delay           ; parameter 8..1031
        movlw   delay/4-1
        call    Delay4us-(delay%4)
        endm
;                                                                 *
Test:   DelayUS(1000)           ; delay 400 usecs                 *
        nop                     ; put simulator breakpoint here   *
;                                                                 *
;       DelayUS(Pulse)          ; Pulse is a constant             *
;       DelayUS(Period-Pulse)   ; Period is also a constant       *
;                                                                 *
;  7 words, 0 ram variables (14 bit core)                         *
;                                                                 *
;******************************************************************

        nop                     ; entry point for (delay%4) == 3  |B0
        nop                     ; entry point for (delay%4) == 2  |B0
        nop                     ; entry point for (delay%4) == 1  |B0
Delay4us
        addlw   -1              ; entry point for (delay%4) == 0  |B0
        skpz                    ;                                 |B0
        goto    Delay4us        ;                                 |B0
        return                  ;                                 |B0
;******************************************************************
        endif
        if Clock == 8
;******************************************************************
;                                                                 *
;  DelayUS() code, 8-MHz clock, 4..1027 usecs   {K8LH, Jun-'07}   *
;                                                                 *
;  requires the use of constant operands known at assembly time   *
;  due to expression evaluation for correct routine entry point   *
;                                                                 *
;  the calling code is generated by this macro;                   *
;                                                                 *
DelayUS macro   delay           ; parameter 4..1027
        movlw   delay/4
        call    Delay4us-(delay%4)
        endm
;                                                                 *
Test:   DelayUS(255)            ; delay 400 usecs                 *
        nop                     ; put simulator breakpoint here   *
;                                                                 *
;       DelayUS(Pulse)          ; Pulse is a constant             *
;       DelayUS(Period-Pulse)   ; Period is also a constant       *
;                                                                 *
;  7 words, 0 ram variables (14 bit core)                         *
;                                                                 *
;******************************************************************

        goto    $+1             ; entry point for (delay%4) == 3  |B0
        goto    $+1             ; entry point for (delay%4) == 2  |B0
        goto    $+1             ; entry point for (delay%4) == 1  |B0
Delay4us
        addlw   -1              ; entry point for (delay%4) == 0  |B0
        skpz                    ;                                 |B0
        goto    Delay4us-2      ;                                 |B0
        return                  ;                                 |B0
;******************************************************************
        endif
 
Last edited:
Hi,
From the code above, does it mean that this DelayUS Macro is able to call a delay from 4 to 1031 micro second? For less than 4 us I will just use nop :)
BTW how to u learn these macro/directives? It makes life easier, really.
*I've found that the default value in the general purpose registers are not zero, am I right?
 
bananasiong said:
Hi,
From the code above, does it mean that this DelayUS Macro is able to call a delay from 4 to 1031 micro second? For less than 4 us I will just use nop :)
BTW how to u learn these macro/directives? It makes life easier, really.

The macro directives are explained in the MPASM helpfile.

*I've found that the default value in the general purpose registers are not zero, am I right?

Same as any other micro, you shouldn't assume any default values for any memory locations, as part of your initialisation you should set them as you wish. From cold they will be essentially random, although they do have a tendency to remember their last value to some extent - but this isn't something you should rely on!!!!!!.
 
Nigel Goodwin said:
Same as any other micro, you shouldn't assume any default values for any memory locations, as part of your initialisation you should set them as you wish. From cold they will be essentially random, although they do have a tendency to remember their last value to some extent - but this isn't something you should rely on!!!!!!.
Ya, I found this was so troublesome before knowing the way to perform indirect addressing mode. I used to clear all the general purpose registers by clrf clrf clrf clrf......

Thanks
 
bananasiong said:
Ya, I found this was so troublesome before knowing the way to perform indirect addressing mode. I used to clear all the general purpose registers by clrf clrf clrf clrf......

It's not something I've ever found any reason to do?, if a GPR needs a specific value then I load it with that value, but if it's written to before it's ever read, then there's no need (or use) to clear it first.

For example, if you've allocated two GPR's to hold the ten bit output from the A2D, there's no need to clear them, because the first thing that happens is that they are written to with the analogue values.
 
Status
Not open for further replies.

Latest threads

Back
Top