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

Pic16f818

Discussion in 'Microcontrollers' started by uaefame, Oct 21, 2008.

  1. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    170
    Location:
    Toronto, Canada
    They do make smaller SOIC PICs
     
  2. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,240
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    Is the 16F876 PIC an option.?
     
  3. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Buy a bigger breadboard. I routinely use these single panel ones with 40-pin chips. The two panel ones are nice too. How small is yours?
     
  4. dave

    Dave New Member

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


     
  5. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE

    I am using PIC 16F877 Ya the programming of PIC 16F876 is similar thanks GOD :).

    I mean the pins are so high i mean they doesn't really fit inside the breadboard. The breadboard size is well but I think i need a socket with it.
     
  6. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    170
    Location:
    Toronto, Canada
    Actually the 16F877 & 876 use the same die, PORTD & E are simply not connected.
     
  7. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    I decided to understand the codes

    I have 3 questions. First question about STATUS register.

    Code (text):
    bsf STATUS,RP0
            bcf STATUS,RP1
            bsf STATUS,IRP
    Here we set bank 1 for direct addressing and IRP which is bit 7 of status to 1 which mean bank 2, 3 which is indirect addressing.

    Q1> What is the different between direct and indirect addressing?

    Code (text):
    radix dec
    Q2> what is the meaning of this?


    Code (text):
            cblock  20h
    OnTime:2
    OffTime:2
            endc
    I am using PIC16F877 FYI, and here we r setting OnTime and OffTime in the general purpose resistor then we are adding :2?

    Can you explain this line too.

    Thanks in advance
     
    Last edited: Nov 12, 2008
  8. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    I run the simulation for Pommie codes
    Code (text):
     ;*******************************************************************
    ;                           16F877 PWM Program
    ;*******************************************************************

            include "p16f877.inc"

            errorlevel  -302
            radix   dec

        __CONFIG _CP_OFF & _DEBUG_ON & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF

            cblock  20h
    OnTime:2
    OffTime:2
            endc

            cblock  71h
    int_work
    int_status
    int_pclath
            endc

            org     0h
            nop
            goto    start
            nop
            nop

    interupt    movwf   int_work
            swapf   STATUS,W
            movwf   int_status
            bcf STATUS,RP0
            bcf STATUS,RP1
            movfw   PCLATH
            movwf   int_pclath
            clrf    PCLATH

            btfsc   PORTB,0
            goto    TurnOff
    ; turn on the output and write the on time
            nop;        delay to make both path identical
            bsf PORTB,0;<<<<<<<<<< Break Point
            movfw   OnTime+1
            movwf   CCPR1H
            movfw   OnTime
            movwf   CCPR1L
            goto    DonePWM

    TurnOff     bcf PORTB,0;<<<<<<<<<< Break Point
            movfw   OffTime+1
            movwf   CCPR1H
            movfw   OffTime
            movwf   CCPR1L
    DonePWM
            bcf PIR1,CCP1IF;    reset special event trigger interupt

            movfw   int_pclath
            movwf   PCLATH
            swapf   int_status,W
            movwf   STATUS
            swapf   int_work,F; swap to file
            swapf   int_work,W; swap to work
            retfie


    start       bsf STATUS,RP0
            bcf STATUS,RP1
            bsf STATUS,IRP; all indirest access is to 100h - 1ffh
             movlw  (0<<NOT_RBPU|0<<INTEDG|0<<T0CS|0<<T0SE|0<<PSA|B'000'<<PS0)
            movwf   OPTION_REG
            movlw   b'11111110'
            movwf   TRISB
            bcf STATUS,RP0
            movlw   (b'01'<<T1CKPS0|0<<T1OSCEN|0<<NOT_T1SYNC|0<<TMR1CS|1<<TMR1ON)
            movwf   T1CON;      enable timer 1
            movlw   low(45000)
            movwf   CCPR1L
            movwf   OnTime
            movlw   high(45000)
            movwf   CCPR1H
            movwf   OnTime+1
            movlw   low(5000)
            movwf   OffTime
            movlw   high(5000)
            movwf   OffTime+1
            movlw   (0<<CCP1X|0<<CCP1Y|b'1011'<<CCP1M0);    enable special event trigger on CCP1
            movwf   CCP1CON;   
            bsf STATUS,RP0
            bsf PIE1,CCP1IE;    enable CCP1 interupt
            bcf STATUS,RP0

            movlw   (1<<GIE|1<<PEIE|0<<T0IE|0<<INTE|0<<RBIE|0<<T0IF|0<<INTF|0<<RBIF)
            movwf   INTCON;     enable Peripheral interupts

    Loop       
            goto    Loop


            END
    Its only go around Start then Loop Loop Loop Loop ... forever whatabout the remaining codes when they are called or used? Any ideas?

    Unused code in my view
    Code (text):

    nop
            nop

    interupt    movwf   int_work
            swapf   STATUS,W
            movwf   int_status
            bcf STATUS,RP0
            bcf STATUS,RP1
            movfw   PCLATH
            movwf   int_pclath
            clrf    PCLATH

            btfsc   PORTB,0
            goto    TurnOff
    ; turn on the output and write the on time
            nop;        delay to make both path identical
            bsf PORTB,0;<<<<<<<<<< Break Point
            movfw   OnTime+1
            movwf   CCPR1H
            movfw   OnTime
            movwf   CCPR1L
            goto    DonePWM

    TurnOff     bcf PORTB,0;<<<<<<<<<< Break Point
            movfw   OffTime+1
            movwf   CCPR1H
            movfw   OffTime
            movwf   CCPR1L
    DonePWM
            bcf PIR1,CCP1IF;    reset special event trigger interupt

            movfw   int_pclath
            movwf   PCLATH
            swapf   int_status,W
            movwf   STATUS
            swapf   int_work,F; swap to file
            swapf   int_work,W; swap to work
            retfie
     
     
  9. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    I understand indirect addressing, but I don't know what IRP is for. I never diddle those bits directly. I let the assembler do it for me by using the banksel directive. Like this:

    Code (text):
        org 0x0000
    init
        banksel TRISB       ;bank 1
        movlw   0x06        ;configure all pins
        movwf   ADCON1      ;as digital inputs
        clrf    TRISB
        banksel PORTA   ;bank 0
    main    bsf PORTB,0
        call    delayc
        call    delay
        goto    main
    --------------------------------------

    The radix sets which numbering system you want to be default. With the above line you've set the radix to decimal. So any number you use with no prefix or suffix (0x or h) is automatically understood to be in decimal. If you don't put any radix definition line in your source the default (I believe) is hexadecimal. I could be wrong. Test it and you'll soon know for sure.

    --------------------------------------

    In the cblock you're allocating space in RAM for two variables, OnTime and OffTime. The :2 tells the assembler to reserve 2 bytes for each variable instead of the usual 1 byte.
     
    Last edited: Nov 12, 2008
    • Like Like x 1
  10. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    PIC 16F877 has two VDD and VSS.

    Do I need to connect 5V and ground to each one? Or one is enough?

    Thanks in advance
     
  11. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Microchip says to connect all VDD and VSS pins.
     
  12. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    Here are Pomie codes
    Code (text):
      ;*******************************************************************
    ;                           16F877 PWM Program
    ;*******************************************************************

            include "p16f877.inc"

            errorlevel  -302
            radix   dec

        __CONFIG _CP_OFF & _DEBUG_ON & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF

            cblock  20h
    OnTime:2
    OffTime:2
            endc

            cblock  71h
    int_work
    int_status
    int_pclath
            endc

            org     0h
            nop
            goto    start
            nop
            nop

    interupt    movwf   int_work
            swapf   STATUS,W
            movwf   int_status
            bcf STATUS,RP0
            bcf STATUS,RP1
            movfw   PCLATH
            movwf   int_pclath
            clrf    PCLATH

            btfsc   PORTB,0
            goto    TurnOff
    ; turn on the output and write the on time
            nop;        delay to make both path identical
            bsf PORTB,0;<<<<<<<<<< Break Point
            movfw   OnTime+1
            movwf   CCPR1H
            movfw   OnTime
            movwf   CCPR1L
            goto    DonePWM

    TurnOff     bcf PORTB,0;<<<<<<<<<< Break Point
            movfw   OffTime+1
            movwf   CCPR1H
            movfw   OffTime
            movwf   CCPR1L
    DonePWM
            bcf PIR1,CCP1IF;    reset special event trigger interupt

            movfw   int_pclath
            movwf   PCLATH
            swapf   int_status,W
            movwf   STATUS
            swapf   int_work,F; swap to file
            swapf   int_work,W; swap to work
            retfie


    start       bsf STATUS,RP0
            bcf STATUS,RP1
            bsf STATUS,IRP; all indirest access is to 100h - 1ffh
             movlw  (0<<NOT_RBPU|0<<INTEDG|0<<T0CS|0<<T0SE|0<<PSA|B'000'<<PS0)
            movwf   OPTION_REG
            movlw   b'11111110'
            movwf   TRISB
            bcf STATUS,RP0
            movlw   (b'01'<<T1CKPS0|0<<T1OSCEN|0<<NOT_T1SYNC|0<<TMR1CS|1<<TMR1ON)
            movwf   T1CON;      enable timer 1
            movlw   low(45000)
            movwf   CCPR1L
            movwf   OnTime
            movlw   high(45000)
            movwf   CCPR1H
            movwf   OnTime+1
            movlw   low(5000)
            movwf   OffTime
            movlw   high(5000)
            movwf   OffTime+1
            movlw   (0<<CCP1X|0<<CCP1Y|b'1011'<<CCP1M0);    enable special event trigger on CCP1
            movwf   CCP1CON;   
            bsf STATUS,RP0
            bsf PIE1,CCP1IE;    enable CCP1 interupt
            bcf STATUS,RP0

            movlw   (1<<GIE|1<<PEIE|0<<T0IE|0<<INTE|0<<RBIE|0<<T0IF|0<<INTF|0<<RBIF)
            movwf   INTCON;     enable Peripheral interupts

    Loop       
            goto    Loop


            END
    I modified it and here is the new codes
    Code (text):

    ;*******************************************************************
    ;                           16F877 PWM Program
    ;*******************************************************************

            include "p16f877.inc"

            errorlevel  -302
            radix   dec

        __CONFIG _CP_OFF & _DEBUG_ON & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF

            cblock  20h
    OnTime:2
    OffTime:2
            endc

            cblock  71h
    int_work
    int_status
    int_pclath
            endc

            org     0h
            nop
            goto    start
            nop
            nop
            org     04h
            goto    interupt
    interupt    movwf   int_work
            swapf   STATUS,W
            movwf   int_status
            bcf STATUS,RP0
            bcf STATUS,RP1
            movfw   PCLATH
            movwf   int_pclath
            clrf    PCLATH

            btfsc   PORTB,0
            goto    TurnOff
    ; turn on the output and write the on time
            nop;        delay to make both path identical
            bsf PORTB,0;<<<<<<<<<< Break Point
            movfw   OnTime+1
            movwf   CCPR1H
            movfw   OnTime
            movwf   CCPR1L
            goto    DonePWM

    TurnOff     bcf PORTB,0;<<<<<<<<<< Break Point
            movfw   OffTime+1
            movwf   CCPR1H
            movfw   OffTime
            movwf   CCPR1L
    DonePWM
            bcf PIR1,CCP1IF;    reset special event trigger interupt

            movfw   int_pclath
            movwf   PCLATH
            swapf   int_status,W
            movwf   STATUS
            swapf   int_work,F; swap to file
            swapf   int_work,W; swap to work
            retfie


    start       bsf STATUS,RP0
            bcf STATUS,RP1
            bsf STATUS,IRP; all indirest access is to 100h - 1ffh
             movlw  (0<<NOT_RBPU|0<<INTEDG|0<<T0CS|0<<T0SE|0<<PSA|B'000'<<PS0)
            movwf   OPTION_REG
            movlw   b'11111110'
            movwf   TRISB
            bcf STATUS,RP0
            movlw   (b'01'<<T1CKPS0|0<<T1OSCEN|0<<NOT_T1SYNC|0<<TMR1CS|1<<TMR1ON)
            movwf   T1CON;      enable timer 1
            movlw   low(45000)
            movwf   CCPR1L
            movwf   OnTime
            movlw   high(45000)
            movwf   CCPR1H
            movwf   OnTime+1
            movlw   low(5000)
            movwf   OffTime
            movlw   high(5000)
            movwf   OffTime+1
            movlw   (0<<CCP1X|0<<CCP1Y|b'1011'<<CCP1M0);    enable special event trigger on CCP1
            movwf   CCP1CON;   
            bsf STATUS,RP0
            bsf PIE1,CCP1IE;    enable CCP1 interupt
            bcf STATUS,RP0

            movlw   (1<<GIE|1<<PEIE|0<<T0IE|0<<INTE|0<<RBIE|0<<T0IF|0<<INTF|0<<RBIF)
            movwf   INTCON;     enable Peripheral interupts

    Loop       
            goto    Loop


            END
     
    I only did this change
    Code (text):
            org     04h
            goto    interupt
     
    My Main question how does the program call the interupt command? I mean the interupt loop?

    I added these codes is it right or i need to remove it?
     
    Last edited: Nov 13, 2008
  13. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,240
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    hi,
    The ISR [interrupt service routine] is called by the STATE of bits set by the PIC's internal peripherals or external interrupts.

    EDIT your post by selecting ALL the code text and then click the '#' sign on the menu bar. This will keep the formatting for the code text.

    I see you changed it while I was replying.
     
    Last edited: Nov 13, 2008
  14. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    The interrupt (I must learn how to spell interrupt) code is run when the CCP1 interrupt is triggered. To use the code you would set On_Time and Off_Time in the empty Loop (2500=1mS). Adding the goto is a bad thing and could cause the pic to crash if more code is added.

    Mike.
     
    • Like Like x 1
  15. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    Interesting,

    I somehow enjoy learning PIC I don't know why :). Maybe Because you guys keep helping me :)

    Can you explain it?

    I am just interested in knowing how On_Time and Off_Time can actually call interrput? Is the formating an issue? Or There is a special way of triggering the interrput codes. Its amazing how interput will be excuted even though you didn't tell the program about it.
    I mean like goto interrput and call interrput?

    hi eric

    you mean STATUS? or STATE because i can't find STATE in the register file map?

    Thanks in advance
     
  16. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,240
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    hi,
    The STATE is used to refer to voltage level of a BIT, when its at +V its a High state and when its 0V its a Low state.

    When you write the BIT pattern to the different peripheral control registers it instructs the peripheral to generate an Interrupt [or not to] when certain conditions are met.

    I will not answer Pommies part as he is dealing with your program.:)
     
    Last edited: Nov 13, 2008
  17. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    Code (text):

            movfw   PCLATH
            movwf   int_pclath
            clrf    PCLATH
     
    Sorry for keep asking questions about these codes.
    Q1> PCLATH what is PCLATH?
    Q2> Why we are interested in saving it value i mean stacking it up and then poping it again?

    I understand that PCLATH has something to do with 2k pages? But i couldn't understand it well any help here?

    Thanks in advance
     
  18. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,331
    Likes:
    653
    Location:
    Derbyshire, UK
    As with all of your question - READ THE DATASHEET.

    But in that fragment of code it's saving PCLATH so it can be restored later when the ISR exits.
     
  19. BeeBop

    BeeBop Active Member

    Joined:
    Dec 22, 2005
    Messages:
    1,281
    Likes:
    23
    Location:
    Vancouver Canada
    A1> Program Counter LATch High The PC is more than 8 bits wide, so these are the most significant bits of the program counter.

    A2> The 'slice' of code you posted is out of context, but I'm guessing it is part of an interrupt service routine? You would want to save it as part of the context when your micro handles an interrupt so the program counter can return to where it was working before the interrupt occurred.

    You should look up PCLATH in the data sheet. :D
     
    • Like Like x 1
  20. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    Thanks again,

    I see why I was confused because PC is a 13bit. Usually in the manual it's written as PCL and PCH this time PCH is not used therefore i was confused and instead PCLATH is used now i understand what PCLATH is.

    Ya you are right! I need to look up the manual. Sometimes you read the manual without knowing the basic is a bit confusing now things are cleared up, I will give it another try thanks again.
     
  21. uaefame

    uaefame New Member

    Joined:
    Feb 22, 2008
    Messages:
    271
    Likes:
    9
    Location:
    Dubai, UAE
    General Question about Pommie coding

    In page 5, the codes is presented. The program is Loop goto Loop. How the interrupt works? How the program know when to handle interrupt.

    What I understand is:
    First> In interrupt, it will stack the values of w, status and PCLATH
    Second> It will check PORTB,0 if its on or off
    Third> Move the value of ontime and ontime+1 to CCPR1H and CCPR1L same if it was off but the values changes
    Fourth> Reset special event trigger interrupt
    5th> Pop everything back
    6th> Interrupt happen again Don't know how?
    7th> same as 1
    8th> same as 2
    and the else is same the only thing I understand which is happening it is swaping everytime between on and off timing.

    My main question: How it know when an interrupt happens? Does the word interrupt ring a bell in assembly language?
     
    Last edited: Nov 18, 2008

Share This Page