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

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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:
;**********************************************************************
;  Description:  *
;  Display Light Meter on 2 digit seven segment display  *
;  MPLABXIDE Version 3.26  *
;  MPASMWIN (v5.66)  *
;**********************************************************************
;  *
;  Filename:  LightDisp.asm  *
;  Date:  September 11, 2016  *
;  File Version:  0.01  *
;  *
;  Author:  Nestor Bulala  *
;  Company:  Seven Net  *
;  *
;  *
;**********************************************************************
;  *
;  Notes:  *
;  Pin Assignment:  *
;   AN2 (pin 11)    = voltage to be measured ( LDR)  *
;  RB0-1, RB4, RC1-4 = 7 segment display bus ( common cathode)  *
;  RC5 (pin 5)    = "tens" digit enable ( active high)  *
;  RB5 (pin 2)    = "ones" digit enable (active high)  *   
;**********************************************************************

  list  p=16F506  ; list directive to define processor
  #include <p16F506.inc>  ; processor specific variable definitions

  radix  dec
   
  __CONFIG  _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC_RB4EN & _IOSCFS_OFF

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

; pin assignments
  #define TENS  PORTC,5    ; "tens" digit enable
  #define ONES  PORTB,2    ; "ones" digit enable
   
;***** VARIABLE DEFINITIONS
  UDATA_SHR
temp  RES   1      ; used by set7seg routine (temp digit store)
   
;**********************************************************************
;*********** RC CALIBRATION
RCCAL   CODE   0x3FF      ; processor reset vector
   res 1        ; holds internal RC cal value as a movlw k
   
; Internal RC calibration value is placed at location 0x3FF by Microchip
; as a movlw k, where the k is a literal value.   
   
;************RESET VECTOR *********************************************
RESET   CODE   0x000      ; effective reset vector
   movwf   OSCCAL      ; apply internal RC factory calibration
   pagesel   start
   goto   start      ; jump to main code
   
;***** Subroutine vectors
set7seg          ; display digit on 7-segment display
   pagesel   set7seg_R
   goto   set7seg_R

;***** MAIN PROGRAM ***************************************************
MAIN   CODE
   
;***** Initialisation
start
   ; configure ports
   clrw        ; configure PORTB and PORTC as all outputs
   tris   PORTB
   tris   PORTC
   clrf   CM1CON0      ; disable comparator 1, RB0, RB1 digital
   clrf   CM2CON0      ; disable comparator 2, RC0, RC1 digital
   clrf   VRCON      ; disable CVref, RC2 usable
   
   ; configure ADC
   movlw   b'01111001'    ; configure ADC:
     ; 01------     AN2 (only) analog (ANS = 01)
     ; --11----     clock = INTOSC/4 (ADCS = 11)
     ; ----10--     select channel AN2 (CHS = 10)
     ; -------1     turn ADC on (ADON = 1)
   movwf   ADCON0      ; AN2 ready for sampling
   
   ; configure timer
   movlw   b'11010111'    ; configure Timer0:
     ; --0-----     timer mode (TOCS = 0), RC5 usable
     ; ----0---     prescaler assigned to Timer0 (PSA = 0)
     ; -----111     prescale = 256 (PS = 111)
     
   option        ; increment every 256 us
          ; (TMR0 2 cycles every 2.048 ms)
           
;***** MAIN LOOP
main_loop
   ; sample input
   bsf   ADCON0,GO    ; start conversion
w_adc   btfsc   ADCON0,NOT_DONE    ; wait until conversion complete
   goto   w_adc
   ; display high nibble for 2.048 ms
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
   
   ; repeat forever
   goto   main_loop

;***** LOOKUP TABLES ***********************************************
TABLES   CODE   0x200      ; locate at beginning of a page
   
; pattern table for 7 segment display on PORTB
;  RB4 = E, RB1:0 = FG
get7sB   addwf   PCL,f
   retlw   b'010010'    ; 0
   retlw   b'000000'    ; 1
   retlw   b'010001'    ; 2
   retlw   b'000001'    ; 3
   retlw   b'000011'    ; 4
   retlw   b'000011'    ; 5
   retlw   b'010011'    ; 6
   retlw   b'000000'    ; 7
   retlw   b'010011'    ; 8
   retlw   b'000011'    ; 9
   retlw   b'010011'    ; A
   retlw   b'010011'    ; b
   retlw   b'010010'    ; C
   retlw   b'010001'    ; d
   retlw   b'010011'    ; E
   retlw   b'010011'    ; F
   
; pattern table for 7 segment display on port C
; RC4:1 = CDBA
get7sC   addwf   PCL,f
   retlw   b'011110'    ; 0
   retlw   b'010100'    ; 1
   retlw   b'001110'    ; 2
   retlw   b'011110'    ; 3
   retlw   b'010100'    ; 4
   retlw   b'011010'    ; 5
   retlw   b'011010'    ; 6
   retlw   b'010110'    ; 7
   retlw   b'011110'    ; 8
   retlw   b'011110'    ; 9
   retlw   b'010110'    ; A
   retlw   b'011000'    ; b
   retlw   b'001010'    ; C
   retlw   b'011100'    ; d
   retlw   b'001010'    ; E
   retlw   b'000010'    ; F
   
; Display digit passed in W on 7 segment display
set7seg_R
   ; disable displays
   clrf   PORTB      ; clear all digit enable lines on PORTB
   clrf   PORTC      ; and PORT C
   
   ; output digit pattern
   movwf   temp      ; save digit
   call   get7sB      ; lookup pattern for port B
   movwf   PORTB      ; then output it
   movf   temp,w      ; get digit
   call   get7sC      ; then repeat for port C
   movwf   PORTC
   retlw   0
   
   END
Mod edit: code tags
 

Attachments

Last edited by a moderator:

AlbertHall

Joined Jun 4, 2014
12,623
PIC's need a pullup 10k on MCLR
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.
 

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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:

AlbertHall

Joined Jun 4, 2014
12,623
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
 

AlbertHall

Joined Jun 4, 2014
12,623
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.
 

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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
 

AlbertHall

Joined Jun 4, 2014
12,623
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.
 

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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.
 

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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:

AlbertHall

Joined Jun 4, 2014
12,623
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.
 

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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.
 

AlbertHall

Joined Jun 4, 2014
12,623
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.
 

Attachments

Thread Starter

nestbulala

Joined Dec 12, 2015
111
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:

AlbertHall

Joined Jun 4, 2014
12,623
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).
 
Top