Light Meter on 2 digit display using PIC16F506 does'nt work

Discussion in 'Embedded Systems and Microcontrollers' started by nestbulala, Sep 14, 2016.

  1. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    I am working on a tutorial from Gooligum about this light meter on Lesson 10 example 2 and my resources have been running out. I have been doing the exercises like lighting the LED, flashing, counters and so on but this one puzzles me. If I power up the first digit transistor, I can see 1 on the display. It seems that my multiplexing program does'nt work. Can anyone please enlighten me on this? I am a newbie and I know I have missed something here. Attached were the drawing and the code.

    Code (Microchip Assembler):
    1.  
    2. ;**********************************************************************
    3. ;  Description:  *
    4. ;  Display Light Meter on 2 digit seven segment display  *
    5. ;  MPLABXIDE Version 3.26  *
    6. ;  MPASMWIN (v5.66)  *
    7. ;**********************************************************************
    8. ;  *
    9. ;  Filename:  LightDisp.asm  *
    10. ;  Date:  September 11, 2016  *
    11. ;  File Version:  0.01  *
    12. ;  *
    13. ;  Author:  Nestor Bulala  *
    14. ;  Company:  Seven Net  *
    15. ;  *
    16. ;  *
    17. ;**********************************************************************
    18. ;  *
    19. ;  Notes:  *
    20. ;  Pin Assignment:  *
    21. ;   AN2 (pin 11)    = voltage to be measured ( LDR)  *
    22. ;  RB0-1, RB4, RC1-4 = 7 segment display bus ( common cathode)  *
    23. ;  RC5 (pin 5)    = "tens" digit enable ( active high)  *
    24. ;  RB5 (pin 2)    = "ones" digit enable (active high)  *  
    25. ;**********************************************************************
    26.  
    27.   list  p=16F506  ; list directive to define processor
    28.   #include <p16F506.inc>  ; processor specific variable definitions
    29.  
    30.   radix  dec
    31.    
    32.   __CONFIG  _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC_RB4EN & _IOSCFS_OFF
    33.  
    34. ; '__CONFIG' directive is used to embed configuration word within .asm file.
    35. ; The lables following the directive are located in the respective .inc file.
    36. ; See respective data sheet for additional information on configuration word.
    37.  
    38. ; pin assignments
    39.   #define TENS  PORTC,5    ; "tens" digit enable
    40.   #define ONES  PORTB,2    ; "ones" digit enable
    41.    
    42. ;***** VARIABLE DEFINITIONS
    43.   UDATA_SHR
    44. temp  RES   1      ; used by set7seg routine (temp digit store)
    45.    
    46. ;**********************************************************************
    47. ;*********** RC CALIBRATION
    48. RCCAL   CODE   0x3FF      ; processor reset vector
    49.    res 1        ; holds internal RC cal value as a movlw k
    50.    
    51. ; Internal RC calibration value is placed at location 0x3FF by Microchip
    52. ; as a movlw k, where the k is a literal value.  
    53.    
    54. ;************RESET VECTOR *********************************************
    55. RESET   CODE   0x000      ; effective reset vector
    56.    movwf   OSCCAL      ; apply internal RC factory calibration
    57.    pagesel   start
    58.    goto   start      ; jump to main code
    59.    
    60. ;***** Subroutine vectors
    61. set7seg          ; display digit on 7-segment display
    62.    pagesel   set7seg_R
    63.    goto   set7seg_R
    64.  
    65. ;***** MAIN PROGRAM ***************************************************
    66. MAIN   CODE
    67.    
    68. ;***** Initialisation
    69. start
    70.    ; configure ports
    71.    clrw        ; configure PORTB and PORTC as all outputs
    72.    tris   PORTB
    73.    tris   PORTC
    74.    clrf   CM1CON0      ; disable comparator 1, RB0, RB1 digital
    75.    clrf   CM2CON0      ; disable comparator 2, RC0, RC1 digital
    76.    clrf   VRCON      ; disable CVref, RC2 usable
    77.    
    78.    ; configure ADC
    79.    movlw   b'01111001'    ; configure ADC:
    80.      ; 01------     AN2 (only) analog (ANS = 01)
    81.      ; --11----     clock = INTOSC/4 (ADCS = 11)
    82.      ; ----10--     select channel AN2 (CHS = 10)
    83.      ; -------1     turn ADC on (ADON = 1)
    84.    movwf   ADCON0      ; AN2 ready for sampling
    85.    
    86.    ; configure timer
    87.    movlw   b'11010111'    ; configure Timer0:
    88.      ; --0-----     timer mode (TOCS = 0), RC5 usable
    89.      ; ----0---     prescaler assigned to Timer0 (PSA = 0)
    90.      ; -----111     prescale = 256 (PS = 111)
    91.      
    92.    option        ; increment every 256 us
    93.           ; (TMR0 2 cycles every 2.048 ms)
    94.            
    95. ;***** MAIN LOOP
    96. main_loop
    97.    ; sample input
    98.    bsf   ADCON0,GO    ; start conversion
    99. w_adc   btfsc   ADCON0,NOT_DONE    ; wait until conversion complete
    100.    goto   w_adc
    101.    ; display high nibble for 2.048 ms
    102. w10_hi   btfss   TMR0,2      ; wait for TMR0 2 to go high
    103.    goto   w10_hi
    104.    swapf   ADRES,w      ; get "tens" digit
    105.    andlw   0x0F      ; from high nibble of ADC result
    106.    pagesel   set7seg
    107.    call   set7seg      ; then output it
    108.    pagesel   $
    109.    bsf   TENS      ; enable "tens" display
    110. w10_lo   btfsc   TMR0,2      ; wait for TMR0 2 to go low
    111.    goto   w10_lo
    112.    
    113.    ; display ones for 2.048 ms
    114. w1_hi   btfss   TMR0,2      ; wait for TMR0 2 to go high
    115.    goto   w1_hi
    116.    movf   ADRES,w      ; get ones digit
    117.    andlw   0x0F      ; from low nibble of ADC result
    118.    pagesel   set7seg
    119.    call   set7seg      ; then output it
    120.    pagesel   $
    121.    bsf   ONES      ; enable "ones" display
    122. w1_lo   btfsc   TMR0,2      ; wait for TMR0 2 to go low
    123.    goto   w1_lo
    124.    
    125.    ; repeat forever
    126.    goto   main_loop
    127.  
    128. ;***** LOOKUP TABLES ***********************************************
    129. TABLES   CODE   0x200      ; locate at beginning of a page
    130.    
    131. ; pattern table for 7 segment display on PORTB
    132. ;  RB4 = E, RB1:0 = FG
    133. get7sB   addwf   PCL,f
    134.    retlw   b'010010'    ; 0
    135.    retlw   b'000000'    ; 1
    136.    retlw   b'010001'    ; 2
    137.    retlw   b'000001'    ; 3
    138.    retlw   b'000011'    ; 4
    139.    retlw   b'000011'    ; 5
    140.    retlw   b'010011'    ; 6
    141.    retlw   b'000000'    ; 7
    142.    retlw   b'010011'    ; 8
    143.    retlw   b'000011'    ; 9
    144.    retlw   b'010011'    ; A
    145.    retlw   b'010011'    ; b
    146.    retlw   b'010010'    ; C
    147.    retlw   b'010001'    ; d
    148.    retlw   b'010011'    ; E
    149.    retlw   b'010011'    ; F
    150.    
    151. ; pattern table for 7 segment display on port C
    152. ; RC4:1 = CDBA
    153. get7sC   addwf   PCL,f
    154.    retlw   b'011110'    ; 0
    155.    retlw   b'010100'    ; 1
    156.    retlw   b'001110'    ; 2
    157.    retlw   b'011110'    ; 3
    158.    retlw   b'010100'    ; 4
    159.    retlw   b'011010'    ; 5
    160.    retlw   b'011010'    ; 6
    161.    retlw   b'010110'    ; 7
    162.    retlw   b'011110'    ; 8
    163.    retlw   b'011110'    ; 9
    164.    retlw   b'010110'    ; A
    165.    retlw   b'011000'    ; b
    166.    retlw   b'001010'    ; C
    167.    retlw   b'011100'    ; d
    168.    retlw   b'001010'    ; E
    169.    retlw   b'000010'    ; F
    170.    
    171. ; Display digit passed in W on 7 segment display
    172. set7seg_R
    173.    ; disable displays
    174.    clrf   PORTB      ; clear all digit enable lines on PORTB
    175.    clrf   PORTC      ; and PORT C
    176.    
    177.    ; output digit pattern
    178.    movwf   temp      ; save digit
    179.    call   get7sB      ; lookup pattern for port B
    180.    movwf   PORTB      ; then output it
    181.    movf   temp,w      ; get digit
    182.    call   get7sC      ; then repeat for port C
    183.    movwf   PORTC
    184.    retlw   0
    185.    
    186.    END
    187.  
    Mod edit: code tags
     
    Last edited by a moderator: Sep 14, 2016
  2. TQFP44

    New Member

    Sep 3, 2016
    25
    3
    PIC's need a pullup 10k on MCLR
     
    absf likes this.
  3. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    Yes.
    You can disable MCLR in the config.
    You have in your program:
    __CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC_RB4EN & _IOSCFS_OFF
    You can disable MCLR by using this instead:
    __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC_RB4EN & _IOSCFS_OFF
    But it is still not a good idea to leave the MCLR input pin floating so the pullup resistor is the best solution.
     
    absf likes this.
  4. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    Thanks Albert, TQFP44, I have added 10K pull up on MCLR pin 4 but there was a changed. The display 1 has gone when I supplied the RC5 pin 5 for the first digit.
     
    Last edited: Sep 14, 2016
  5. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    The digit select assignment is wrong in the code.
    ; pin assignments
    #define TENS PORTC,5 ; "tens" digit enable
    #define ONES PORTB,2 ; "ones" digit enable

    ONES should be PORTB,5

    also the digits are never switched off.

    w10_hi btfss TMR0,2 ; wait for TMR0 2 to go high
    goto w10_hi
    swapf ADRES,w ; get "tens" digit
    andlw 0x0F ; from high nibble of ADC result
    pagesel set7seg
    call set7seg ; then output it
    pagesel $
    bsf TENS ; enable "tens" display
    w10_lo btfsc TMR0,2 ; wait for TMR0 2 to go low
    goto w10_lo

    ; display ones for 2.048 ms
    w1_hi btfss TMR0,2 ; wait for TMR0 2 to go high
    goto w1_hi
    movf ADRES,w ; get ones digit
    andlw 0x0F ; from low nibble of ADC result
    pagesel set7seg
    call set7seg ; then output it
    pagesel $
    bsf ONES ; enable "ones" display
    w1_lo btfsc TMR0,2 ; wait for TMR0 2 to go low
    goto w1_lo

    Before bsf TENS add the line
    bcf ONES ; disable "ones" display
    and before bsf ONES add the line
    bcf TENS ; disable "tens" display
     
    absf likes this.
  6. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    Actually those two lines disabling the digits would be better placed before the lines 'call set7seg' so the digit is disabled before the data lines change.
     
  7. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    Thanks Albert, noted and upload to the device but it failed.
    Target voltage detected
    Target has invalid calibration data (0x00).

    The following memory area(s) will be programmed:
    program memory: start address = 0x0, end address = 0x242
    configuration memory

    Device Erased...

    Programming...
    program memory
    Address: 0 Expected Value: 25 Received Value: 0
    Failed to program device
     
  8. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    The programmer cannot communicate with the PIC. The changes to the source code cannot do that.
    If the display(s) are in a socket, try unplugging it (them) while programming. The programmer uses RB0/RB1 to communicate and they have 330Ω to the display(s) which may be upsetting the programmer signals.
     
  9. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    I have removed the resistors on RB0 and RB1 but still program failed. Target has invalid calibration data (0x00) and Program Memory Address: 0 Expected Value : 25 Received Value : 0.
     
  10. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    What is the PIC supply voltage? Please actually measure it.
    Please check carefully the connections between PIC and programmer.
     
  11. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    The voltage on pin 1 is 5.04 volts. All pins have zero voltage except pin 4 which is 5 volts and pin 11 has 3.51 volts. Maybe I should remove connections to pin 4 and pin 11 before downloading?
     
    Last edited: Sep 14, 2016
  12. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    The only pins that matter while programming are the supply, MCLR, and the ICSP pins (RB0 and RB1).
    Something has changed with the connections to these pins as it was programming correctly.
     
  13. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    Thanks Albert, you are right, there was a wire connection to the MCLR pin 4 of the target that was going back to Pickit3 which was disconnected while I soldered the pull up resistor. It is successful downloaded but the result still the same. At least digit 1 should be displayed because when I supplied the pin 5 for the transistor to power up the first digit, a digit 1 is displayed.
     
  14. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    Okay. I'll simulate your code and see if it works in the simulator. If it does then I'll come up with some way of debugging it.
     
    nestbulala likes this.
  15. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    Thank you so much for your time Albert. I really appreciate it.
     
  16. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    I found .that, in the simulator, the comparator output enables were still disabling the normal output even though the comparators were switched off. I have changed the code to set CM1CON0 and CM2CON0 to 0x40 which turns the comparators off and disconnects the comparator outputs from the output pins. I am not sure whether this is a quirk of the simulator or is matched by the silicon but it will do no harm in the silicon.

    Please check what happens with this code. If the displays are still blank, measure the voltage on the PIC pins 2 and 5 and on the collectors of the two transistors. These are the digit enables and should have a 50:50 square wave and so should read about 2.5V as the meter will take the average.
     
  17. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    There were no voltage output on pin 2 and pin 5. But when I supplied it with 5 volts it shows 2 digits 11.
     
    Last edited: Sep 17, 2016
  18. nestbulala

    Thread Starter Member

    Dec 12, 2015
    68
    1
    I mean pin 5. Sorry for the mistake.
     
  19. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    Please also check MCLR voltage. pin 4.
    If this is 5V, then I will make a very cut down program for you to try.
    (I am beginning to suspect the PIC).
     
  20. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,941
    383
    Here is the simple file. It sets and clears all I/O pins each second.
    With your hardware the display should display '88' or blank, alternating each second.
     
    nestbulala likes this.
Loading...