1. 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.
    Dismiss Notice

Making PICs go faster

Discussion in 'Microcontrollers' started by BobW, Mar 1, 2017.

  1. BobW

    BobW Active Member

    Joined:
    Apr 28, 2010
    Messages:
    434
    Likes:
    45
    Location:
    Canada
    I once interfaced a 16F628A (using INTOSC) via its serial port to an FTDI FT230XQ serial to USB adapter chip, but ran into problems at high standard baud rates. As I recall, I couldn't go any higher than about 9600 baud. Since the FTDI chip is capable of non standard baud rates, I changed to something that was an exact SPBRG value, and was able to go up to something like 250kbaud, which was faster than I needed.
     
  2. NorthGuy

    NorthGuy Well-Known Member

    Joined:
    Sep 8, 2013
    Messages:
    1,218
    Likes:
    206
    Location:
    Northern Canada
    http://www.microchipdirect.com
     
  3. BobW

    BobW Active Member

    Joined:
    Apr 28, 2010
    Messages:
    434
    Likes:
    45
    Location:
    Canada
    I decided to check Microchip's site to find one of the modern PIC's that's pin compatible with the 16F630 (14 pin DIP) that I used in this project. It looks like I can drop in a 16F1703, which has a 32 MHz internal oscillator. That will make two more I/O pins available if I need them, plus more program memory and more variable memory. With way more memory, and variables, and two more I/O pins, I could conceivably add more features to the project without making any significant changes to the PC board.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    9,687
    Likes:
    277
    Location:
    Brisbane Australia

    My favourite pin compatible with the 16F630 is the 16F18326. For development it has all the features that you need. Once developed pick one of the family that meets your needs. It has 7 timers, 4 ccp, ADC, DAC, 16kW program etc.

    Mike.
     
  6. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    38,704
    Likes:
    590
    Location:
    Derbyshire, UK
    The enhanced mid-range series are extremely useful, and work well with either assembler or C.
     
  7. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    839
    Likes:
    80
    Location:
    Fresno, CA
    Regardless of how "good" the internal oscillator is, isn't the clock accuracy of them temperature dependent?
     
  8. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    38,704
    Likes:
    590
    Location:
    Derbyshire, UK
    It's obviously not as good as a crystal, but you're not losing two I/O pins either :D

    But it's plenty good enough for the majority of uses, I've not built a board with a crystal on it for a very long time (with the exception of the occasional 32KHz timer1 crystal :D )
     
  9. MrAl

    MrAl Well-Known Member Most Helpful Member

    Joined:
    Sep 7, 2008
    Messages:
    10,892
    Likes:
    938
    Location:
    NJ
    ONLINE
    Hi,

    If Microsoft could go to college for computer science they'd fail every course. What they do and what they have done in the past is not science.

    Nice to know about the Pickit 3 requirement Les.
     
  10. BobW

    BobW Active Member

    Joined:
    Apr 28, 2010
    Messages:
    434
    Likes:
    45
    Location:
    Canada
    Having a look at the datasheet for the PIC16F1703, the internal high speed oscillator has an accuracy of ±2%; certainly not crystal grade, but decent enough for many things. I'll reiterate that I don't need accuracy, just speed.

    That's good to know. I have to order several of those too.
     
  11. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    839
    Likes:
    80
    Location:
    Fresno, CA
    Considering I do a lot of MIDI devices and the MIDI specification allows for an error no greater than 1%, a crystal oscillator is my only option.

    Don't even get me started on DMX.
     
  12. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    9,687
    Likes:
    277
    Location:
    Brisbane Australia
    The internal oscillator has a max error of 1% so should work fine for MIDI. If you can use the baud autodetect then it should be spot on.

    Mike.
     
  13. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,558
    Likes:
    86
    Location:
    Michigan, USA
    The whole 18000 series are worth a look. They also have a full 20-bit NCO (Numerically Controlled Oscillator), two or four CLC (Configurable Logic Cell) modules, and other features too numerous to mention. The PPS (Peripheral Pin Select) module can be used to have EUSART and SPI or I2C ports running at the same time. The caveat is that programming a device with this many peripherals and features can be a PITA. For example, check out the little Clock-Gen program below which simply provides a couple of clock signals and an econo-reset signal for a retro 65C02 system.

    Cheerful regards, Mike

    Code (text):

    ;******************************************************************
    ;                                                                 *
    ;    Project: 65C02_Clock                                         *
    ;       File: 16F18313_Clock.asm                                  *
    ;     Author: Mike McLaren, K8LH                                  *
    ;    (C)2016: Micro Application Consultants                       *
    ;           : All Rights Reserved                                 *
    ;       Date: 04-Apr-2016                                         *
    ;                                                                 *
    ;    16F18313 Clock-Gen + Econo-Reset for 65C02 (8-MHz crystal)   *
    ;    produces a 1, 2, 4, or 8 MHz CPU clock and an ACIA clock.    *
    ;                                                                 *
    ;        IDE: MPLABX v3.05                                        *
    ;       Lang: MPASM v5.62 (absolute addressing mode)              *
    ;                                                                 *
    ;******************************************************************

            #include p16F18313.inc
            errorlevel -302,-311    ; suppress bank warnings
            list st=off             ; symbol table off
            radix dec

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;  config settings                                                ~
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     __CONFIG _CONFIG1, _FEXTOSC_HS & _FCMEN_OFF
     ;
     ; CLKOUTEN_OFF default
     ; CSWEN_ON     default
     ;
     __CONFIG _CONFIG2, _WDTE_OFF & _PPS1WAY_OFF
     ;
     ; MCLRE_ON     default
     ; PWRTE_OFF    default
     ; LPBOREN_OFF  default
     ; BOREN_ON     default
     ; BOREN_LOW    default
     ; STVREN_ON    default
     ; DEBUG_OFF    default
     ;
     __CONFIG _CONFIG3, _LVP_OFF
     ;
     ; WRT_OFF      default
     ;
     __CONFIG _CONFIG4, _CP_OFF & _CPD_OFF

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;  variables                                                      ~
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            cblock  0x70            ; common RAM available any bank
    delayhi                         ; DelayCy() subsystem variable
            endc

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;  constants                                                      ~
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;
    ;  assign clock and reset pins (RA0..RA2 inclusive).
    ;
    PHI0_clk equ    RA0             ; bit index for RA0 (0)
    ACIA_clk equ    RA1             ; bit index for RA1 (1)
    RESB_out equ    RA2             ; bit index for RA2 (2)
    ;
    ;  associate to "Peripheral Pin Select" output registers.
    ;
    PHI0_PPS equ    RA0PPS+PHI0_clk ; equ RA0PPS
    ACIA_PPS equ    RA0PPS+ACIA_clk ; equ RA1PPS
    RESB_PPS equ    RA0PPS+RESB_out ; equ RA2PPS
    ;
    ;  set 'CLKR_div' constant for desired 65C02 clock frequency.
    ;
    ;               6 ->  0.5-MHz (Fosc / 64)
    ;               5 ->  1.0-MHz (Fosc / 32)
    ;               4 ->  2.0-MHz (Fosc / 16)
    ;               3 ->  4.0-MHz (Fosc / 8)
    ;               2 ->  8.0-MHz (Fosc / 4)
    ;
    CLKR_div equ    4               ; 2.0-MHz PHI0 CPU clock
    ;
    ;  set 'NCO1_inc' constant for desired ACIA clock output.
    ;
    ;          2517 ->    38400-Hz (  2400 * 16) @ 0.01659%
    ;          5033 ->    76800-Hz (  4800 * 16) @ 0.00327%
    ;         10066 ->   153600-Hz (  9600 * 16) @ 0.00327%
    ;         20133 ->   307200-Hz ( 19200 * 16) @ 0.00169%
    ;         40265 ->   614400-Hz ( 38400 * 16) @ 0.00079%
    ;         60398 ->   921600-Hz ( 57600 * 16) @ 0.00004%
    ;        120796 ->  1843200-Hz (115200 * 16) @ 0.00004%
    ;        241592 ->  3686400-Hz (230400 * 16) @ 0.00004%
    ;
    NCO1_inc equ    120796          ; 1.8432-MHz (115200 * 16)

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;  K8LH DelayCy() subsystem macro generates four instructions     ~
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            radix dec
    clock   equ     32              ; 4, 8, 12, 16, 20 (MHz), etc.
    usecs   equ     clock/4         ; cycles/microsecond multiplier
    msecs   equ     usecs*1000      ; cycles/millisecond multiplier
    dloop   equ     5               ; loop size, 5 to ??? cycles
    ;
    ;  -- loop --  -- delay range --  -- memory overhead ----------
    ;  5-cyc loop, 11..327690 cycles,  9 words (+4 each macro call)
    ;  6-cyc loop, 11..393226 cycles, 10 words (+4 each macro call)
    ;  7-cyc loop, 11..458762 cycles, 11 words (+4 each macro call)
    ;  8-cyc loop, 11..524298 cycles, 12 words (+4 each macro call)
    ;  9-cyc loop, 11..589834 cycles, 13 words (+4 each macro call)
    ;
    DelayCy macro   cycles          ; range, see above
        if (cycles<11)|(cycles>(dloop*65536+10))
            error " DelayCy range error "
        else
            movlw   high((cycles-11)/dloop)+1
            movwf   delayhi
            movlw   low ((cycles-11)/dloop)
            call    uLoop-((cycles-11)%dloop)
        endif
            endm

    ;******************************************************************
    ;  reset vector                                                   *
    ;******************************************************************
            org     0x0000
    v_reset
            bra     setup           ;                                 |00

    ;******************************************************************
    ;  interrupt vector                                               *
    ;******************************************************************
            org     0x0004
    v_int
            retfie                  ;                                 |??

    ;******************************************************************
    ;  main setup                                                     *
    ;******************************************************************

    setup
    ;
    ;  turn off analog functions (all I/O will be digital).
    ;
            banksel ANSELA          ; bank 03                         |03
            clrf    ANSELA          ; analog off, digital I/O         |03
    ;
    ;  setup data direction for 'output' pins (default 'input').
    ;
            banksel TRISA           ; bank 01                         |01
            bcf     TRISA,PHI0_clk  ; set phi0 clock pin as output    |01
            bcf     TRISA,ACIA_clk  ; set acia clock pin as output    |01
            bcf     TRISA,RESB_out  ; set resb reset pin as output    |01
    ;
    ;  clear RESB pin output latch (hold the 65C02 in reset).
    ;
            banksel LATA            ; bank 02                         |02
            bcf     LATA,RESB_out   ; RESB_out = '0'                  |02
    ;
    ;  setup Fosc for 32-MHz (external 8-MHz crystal and 4xPLL).
    ;
            banksel OSCCON1         ; bank 18                         |18
            movlw   b'00010000'     ; -001---- NOSC[2:0], Ext 4xPLL   |18
                                    ; ----0000 NDIV[3:0], Clk Div 1   |18
            movwf   OSCCON1         ; 8-MHz Xtal & 4xPLL -> 32-MHz    |18
    stable
            btfss   OSCCON3,ORDY    ; OSC stable? yes, skip, else     |18
            bra     stable          ; loop (wait 'til OSC stable)     |18
    ;
    ;  assign PHI0_clk pin (RA0) and ACIA_clk pin (RA1) resources
    ;  via 'Peripheral Pin Select'.
    ;
            banksel PPSLOCK         ; bank 28                         |28
            movlw   0x55            ; PPS unlock sequence             |28
            movwf   PPSLOCK         ;  "                              |28
            movlw   0xAA            ;  "                              |28
            movwf   PPSLOCK         ;  "                              |28
            bcf   PPSLOCK,PPSLOCKED ;  "                              |28
            banksel PHI0_PPS        ; bank 29                         |29
            movlw   b'00011110'     ; assign CLKR (Ref Clock) output  |29
            movwf   PHI0_PPS        ; to the PHI0 clock pin (RA0)     |29
            movlw   b'00011101'     ; assign NCO module output to     |29
            movwf   ACIA_PPS        ; the ACIA clock pin (RA1)        |29
            banksel PPSLOCK         ; bank 28                         |28
            bsf   PPSLOCK,PPSLOCKED ; all done, lock it up            |28
    ;
    ;  setup CLKR (Reference Clock) module for PHI0 CPU Clock.
    ;
            banksel CLKRCON         ; bank 07                         |07
            movlw   0x10|CLKR_div   ; 50% duty cycle & divider bits   |07
            movwf   CLKRCON         ; prep 1, 2, 4, or 8-MHz output   |07
            bsf     CLKRCON,CLKREN  ; enable Reference Clock output   |07
    ;
    ;  setup NCO to generate the ACIA clock.
    ;
            banksel NCO1CON         ; bank 08                         |08
    ;       bcf     NCO1CON,N1PFM   ; fixed duty cycle mode (default) |08
            movlw   b'01'<<N1CKS0   ; NCO1<1:0> = '01' = Fosc         |08
            movwf   NCO1CLK         ; set NCO clock source            |08
            clrf    NCO1ACCL        ; clear 20-bit phase accumulator  |08
            clrf    NCO1ACCH        ;  "                              |08
            clrf    NCO1ACCU        ;  "                              |08
            movlw   low(NCO1_inc)   ; setup 20-bit phase increment    |08
            movwf   NCO1INCL        ;  "                              |08
            movlw   high(NCO1_inc)  ;  "                              |08
            movwf   NCO1INCH        ;  "                              |08
            movlw   upper(NCO1_inc) ;  "                              |08
            movwf   NCO1INCU        ;  "                              |08
            bsf     NCO1CON,N1EN    ; enable NCO module output        |08
    ;
    ;  complete the 65C02 reset cycle.
    ;
            DelayCy(20*msecs)       ; wait ~20-msecs                  |08
            banksel LATA            ; bank 02                         |02
            bsf     LATA,RESB_out   ; release 65C02 from reset        |02

    ;******************************************************************
    ;  main loop                                                      *
    ;******************************************************************

    loop
            bra     loop            ; loop forever (until reset)      |02

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;  K8LH DelayCy() subsystem 16-bit 'uLoop' timing subroutine      ~
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    a = dloop-1
        while a > 0
            nop                     ; (cycles-11)%dloop entry points  |??
    a -= 1
        endw
    uLoop   addlw   -1              ; subtract 'dloop' loop time      |??
            skpc                    ; borrow? no, skip, else          |??
            decfsz  delayhi,F       ; done?  yes, skip, else          |??
            goto    uLoop-dloop+5   ; do another loop                 |??
            return                  ;                                 |??

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            end
     
     

Share This Page