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

PIC16F1827 Code Help

Discussion in 'Microcontrollers' started by Suraj143, Nov 7, 2017.

  1. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,579
    Likes:
    2
    Location:
    South Mald Isld
    First time I'm using this chip.I need to verify the initialisation part.The wiered thing that I noticed is.. before I write to a register everytime I have to call BANKSEL directive.Then what's the point of BSR core register?Is my code ok?

    Code (text):
                List        P=16F1827
                #include    <P16F1827.INC>
                errorlevel    -302
                __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
                __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF

                org        0000h
                goto        Initialise_Ports

                org        0004h
                retfie
    Initialise_Ports  
                BANKSEL        PORTA
                clrf        PORTA
                BANKSEL        LATA
                clrf        LATA
                BANKSEL        ANSELA
                clrf        ANSELA
                BANKSEL        TRISA
                clrf        TRISA
                ;          
                BANKSEL        PORTB
                clrf        PORTB
                BANKSEL        LATB
                clrf        LATB
                BANKSEL        ANSELB
                clrf        ANSELB
                BANKSEL        TRISB
                clrf        TRISB
                   
    Setup_TMR2      
                BANKSEL        T2CON
                movlw        b'00011101'        ; pre scaler = 1:4,Post Scaller = 1:4
                movwf        T2CON          
                movlw        .249
                movwf        PR2
                BANKSEL        PIE1
                bsf        PIE1,TMR2IE          
                movlw        b'11000000'        ; turn on GIE & PEIE
                movwf        INTCON
                BANKSEL        PORTA
                bcf        PIR1,TMR2IF  
                goto        Clear_Registers        
     
  2. jpanhalt

    jpanhalt Well-Known Member Most Helpful Member

    Joined:
    Jun 21, 2006
    Messages:
    5,979
    Likes:
    510
    Location:
    Cleveland, OH, USA
    ONLINE
    Go to Table 3-3, page 24 and following of the datasheet. You will see which banks the various registers are in. If you organize your initialization, you can minimize the number of banksel's you must use. You can also use the instruction, "movlb (insert bank #)" to do the same thing.

    Overall, it is not a huge waste of time to do it the way you did. What is important is that you know why, because if you don't, it will bite you later.

    Your code looks OK as far as it goes. You enable interrupts, but don't have an Interrupt Service Routine (ISR).

    I am checking into the default oscillator settings, as I always set that up too. Edit: Looks like default is 500 kHz, so be sure to consider that in your timings.
     
    Last edited: Nov 7, 2017
  3. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,579
    Likes:
    2
    Location:
    South Mald Isld
    Good info. The default frequency is 500Khz.I have to change that to 4Mhz in the OSCCON register. But after setting the OSCCON register do I also need to check the OSCSTAT register? Medium OSC ready bit?
     
  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:
    10,080
    Likes:
    326
    Location:
    Brisbane Australia

    As already pointed out, you have no ISR (just a retfie) but you do enable Timer2 interrupt. When this fires your code will lock up as it will continually execute the ISR.

    Mike.
     
  6. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,579
    Likes:
    2
    Location:
    South Mald Isld
    Hi here is my ISR routine. I'm multiplexing 4 seven segments.Segments are RB0 to RB7 & common pins are RA0,1,2,3.I also share RB0,1,2,3 as input switches.
    I need to compact my code. Any improvements...!! Really tired of shifting banks...:-(

    Code (text):
                org        0004h
    ;====================================================================        
    ;TMR2 interrupt rate = 4mS
    ;====================================================================
                btfss        PIR1,TMR2IF
                goto        ISR_Exit
                bcf        PIR1,TMR2IF
                ;
                decfsz        Key_Counter,F
                goto        Multiplex_Display
                movlw        .4
                movwf        Key_Counter
    ;-------------------------------------------------------------------
    ;KEY read rate = 4mS X 4 = 16mS
    Read_Keys    
                BANKSEL        LATB
                clrf        LATB            ; clear segment data
                clrf        LATA            ; clear common cathodes
                BANKSEL        PORTB
                clrf        PORTB
                BANKSEL        TRISB
                movlw        b'00001111'        ; make RB0,1,2,3 = inputs for a short time
                movwf        TRISB
                BANKSEL        WPUB
                movlw        b'00001111'
                movwf        WPUB
                BANKSEL        PORTB
                btfss        PORTB,0
                bsf        SW_Flag,SW_1
                btfss        PORTB,1
                bsf        SW_Flag,SW_2
                btfss        PORTB,2
                bsf        SW_Flag,SW_3
                btfss        PORTB,3
                bsf        SW_Flag,SW_4
    ;==================================================
    ;Display Multiplex @ 4mS rate
    ;Common Cathodes [RA0=D1, RA1=D2, RA2=D3,RA3=D4]
    ;==================================================
    Multiplex_Display
                BANKSEL        LATB
                clrf        LATB            ; clear segment data
                clrf        LATA            ; clear common cathodes
                movlb        00h            ; back to Bank 0
                btfss        Display_Select,0
                goto        Display_1
                btfss        Display_Select,1
                goto        Display_2
                btfss        Display_Select,2
                goto        Display_3
                goto        Display_4
                ;        
    Display_1        movf        Digit_1,W        ; Show D1 segment
                call        Segment_Table        ; //
                movlb        01h            ; Bank 1
                movwf        LATB                    
                bsf        LATA,0            ; turn on D1
                movlb        00h            ; back to Bank 0                                                
                bsf        Display_Select,0
                goto        ISR_Exit
                   
    Display_2        movf        Digit_2,W        ; Show D2 segment
                call        Segment_Table        ; //    
                movlb        01h            ; Bank 1
                movwf        LATB                    
                bsf        LATA,1            ; turn on D1
                movlb        00h            ; back to Bank 0                    
                bsf        Display_Select,1
                goto        ISR_Exit
           
    Display_3        movf        Digit_3,W        ; Show D3 segment
                call        Segment_Table        ; //    
                movlb        01h            ; Bank 1
                movwf        LATB                    
                bsf        LATA,2            ; turn on D1
                movlb        00h            ; back to Bank 0
                bsf        Display_Select,2
                goto        ISR_Exit        

    Display_4        movf        Digit_4,W        ; Show D4 segment
                call        Segment_Table        ; //    
                movlb        01h            ; Bank 1
                movwf        LATB                    
                bsf        LATA,3            ; turn on D1
                movlb        00h            ; back to Bank 0
                clrf        Display_Select
                ;        
    Backup_Digits        movf        S_Digit_1,W        ; 1
                movwf        Digit_1
                movf        S_Digit_2,W        ; 2
                movwf        Digit_2
                movf        S_Digit_3,W        ; 3
                movwf        Digit_3
                movf        S_Digit_4,W        ; 4
                movwf        Digit_4
    ISR_Exit    
                retfie
     
  7. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,080
    Likes:
    326
    Location:
    Brisbane Australia
    I notice in your ISR you aren't saving the context (W, Status & BSR) or restoring them before the retfie. Unless your main code is in a very tight loop waiting for the interrupt to complete, it will most likely crash.

    Some suggestions to shorten your code,
    No need to clr PORTB as clearing LATB will do this.
    Leave the WPUs on all the time.
    Instead of testing bits of portb, read it all, and with 0x0f and store in SW_Flag. Rearrange the flags as necessary or use a new variable.
    Use indirect addressing to do the different digits.

    Here a code snippet to get you started,
    Code (text):

            cblock
    Digit_1:4            ;4 bytes for the numbers
    Mask                ;1 byte for the mask
            endb

    initDisplay
                movlw    Digit_1+3    ;point to last so first is shown
                movwf    FSR0L
                clrf     FSR0H
                movlw    0b00001000    ;mask for digit 4
                movwf    Mask
                ret

    Multiplex_Display
                BANKSEL      LATB
                clrf         LATB            ; clear segment data
                clrf         LATA            ; clear common cathodes
                movlb        00h                ; back to Bank 0
                movlw        Digit_1+4        ;has it done all 4
                xorwf        FSR0L,w            ;zero if yes
                movlw        Digit_1            ;so reset
                btfss        STATUS,Z        ;if zero
                movwf        FSR0L            ;to digit 1
                moviw        FSR0++            ;get the value and inc FSR0
                call         Segment_Table
                movlb        01h                ;Bank 1
                movwf        LATB            
                movlb        0
                rlf          Mask,f            ;rotate the cathode mask
                btfsc        Mask,4            ;does it need to wrap
                swapf        Mask,f            ;yes so swap niddles
                movf         Mask,w            ;get the mask
                movlb        01h                ;Bank 1
                movwf        LATA              ;turn on segment
                goto         ISR_Exit
     
    Note the digit locations have to be contiguous.

    Mike.
     
  8. jpanhalt

    jpanhalt Well-Known Member Most Helpful Member

    Joined:
    Jun 21, 2006
    Messages:
    5,979
    Likes:
    510
    Location:
    Cleveland, OH, USA
    ONLINE
    Hi Mike,

    I believe the 16F1827 is enhanced midrange with automatic context saving.

    John
     
  9. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,080
    Likes:
    326
    Location:
    Brisbane Australia
    I knew it was enhanced but didn't know about the auto save bit.
    Guess that's what happens when you do everything in C these days.

    Edit, just read up on the auto save and FSRs are included so the above code won't work.
    Not got time now to edit it but will be able to tomorrow.

    Mike.
     

Share This Page