Continue to Site

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.

  • 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.

Binary Clock still wont work

Status
Not open for further replies.

Sigma150

New Member
On my previous post I was trying to make a binary clock with LEDs. I decided to rewrite and clean up my code but this time only program it to illuminate the leds that are associated with the hours display(the first 4 LEDs that are to the far left of my display). It seemed that it worked correctly except that when the LED that is to the far left(connected to pin 3) illuminates the two LEDs on the far right (connected to pins 12 an 13) also illuminate. This makes no sense since nowhere in my code do those LEDs illuminate. What is going on?

Thanks in advance

Code:
 LIST R=DEC
 INCLUDE "p16f630.inc"
	__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF ) 
	ERRORLEVEL -224        ;remove tris message

 CBLOCK 0x020                ;  Variable Declaration
	DlayValue:2                  ;  Requires 24 Bit Counter (w/ WREG)
 	minutes
	hours
	int13
	int60
 ENDC

	;Set all ports to output
	movlw B'00000000'    ; all bits low in W
	tris PORTA           ; contents of W copied to PORT A ...
	tris PORTC           ; and PORT B

	;set time variable
	movlw d'12' ;hours cant start at zero, start time at 12'oclock
	movwf hours
	
	movlw 0x00
	movlw minutes ;start minutes at zero
	
	;set general variable
	movlw d'13'
	movwf int13
	
	movlw d'60'
	movwf int60

	;set display
	movlw 0xFF		;all lights off		
    movwf PORTA
    movwf PORTC

;////////////////////////////////////////Delay MACRO/////////////////////////Created by:Myke Predko/////////////////////////////////
Dlay Macro Cycles
 variable CyclesLeft            ;  Keep Track of Remaining Cycles
 variable LargeNum
CyclesLeft = Cycles
 local LongLoop
 if Cycles > 0x04FFFF00         ;  Can't Handle the Anything > 83 Seconds (@ 4 MHz)
 error "Required Delay is longer than 'Dlay' Macro can support"
 endif
 if Cycles > 327681             ;  Need Large Loop?  
LargeNum = CyclesLeft / 327681
  movlw   LargeNum
  movwf   DlayValue + 2         ;  Calculate Number of Loops
LongLoop:                       ;  Repeat for Each Loop
  clrf    DlayValue + 1         ;  Do Maximum Possible Loop Count
  clrf    DlayValue
  decf    DlayValue, f
  btfsc   STATUS, Z
   decfsz DlayValue + 1, f
    goto  $ - 3
  decfsz  DlayValue + 2, f      ;  Repeat Loop
   goto   LongLoop
CyclesLeft = CyclesLeft - ((LargeNum * 327681) + 1 + (LargeNum * 3))
 endif  ;  Need Large Loop
 if Cycles > 14                 ;  Will a Loop be required?  
  movlw   high (((CyclesLeft - 3) / 5) + 256)
  movwf   DlayValue + 1
  movlw   low (((CyclesLeft - 3)/ 5) + 256)
  movwf   DlayValue
  decf    DlayValue, f          ;  5 Cycle Constant Delay Loop
  btfsc   STATUS, Z
   decfsz DlayValue + 1, f
    goto  $ - 3
CyclesLeft = CyclesLeft - (3 + (5 * ((CyclesLeft - 3)/ 5)))
 endif                          ;  Finished with Loop Code
 while CyclesLeft >= 2          ;  Put in 2 Instruction Cycle Delays
  goto    $ + 1
CyclesLeft = CyclesLeft - 2
 endw
 if CyclesLeft == 1             ;  Put in the Last Required Cycle
  nop
 endif
 endm
;///////////////////////////////////End of Delay MACRO//////////////////////////////////////////////////////////

;////////////////////  By Luke BrownGold


		
START	
	
	;check to see if hours have reached 13
	movf    int13, w               ;  if hours >= int13 then resetHours
	subwf   hours, w
	btfsc   STATUS, C
	goto   resetHours	;reset hours will return us back to start

	;check to see if minutes have reached 60
	movf    int60, w               ;  if minutes >= int60 then resetMinutes
	subwf   minutes, w
	btfsc   STATUS, C
	goto   resetMinutes  ;reset hours will return us back to start

	;display the time
	
	;clear display
    movlw 0xFF	
    movwf PORTA 
    movwf PORTC 

;/////////////////-------------HOURS LEDS
	BTFSC hours,d'3' ;    is bit set
    BCF PORTA,d'4' ;      yes, so illuminate LED
    
	BTFSC hours,d'2'
    BCF PORTC,d'5'

	BTFSC hours,d'1' ;    is bit set
    BCF PORTC,d'4' ;      yes, so illuminate LED
    
	BTFSC hours,d'0'
    BCF PORTC,d'3'

	;delay
	Dlay 100000  ;  Delay 0.1s, will make longer(shorter for testin purposes

	;increment minutes
	incf minutes,d'1'

	goto START
;-----------------------------------------------------------------------;
;                       	Reset the hours varialbe                    ;
;-----------------------------------------------------------------------;
resetHours
	movlw d'1'
	movwf hours
	
	movlw d'13'		;just incase var int13 get reset by equals method
	movwf int13
 goto START

;-----------------------------------------------------------------------;
;                       	Reset the hours varialbe                    ;
;-----------------------------------------------------------------------;
resetMinutes
	movlw 0x00
	movwf minutes

	incf hours, d'1'	;increment the hours by one
	
	movlw d'60'		;just incase var int60 get reset by equals method
	movwf int60
 goto START

;-----------------------------------------------------------------------;
;                        Delay for ten seconds                          ;
;-----------------------------------------------------------------------;
tenSec:
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
	Call oneSec
 return
;-----------------------------------------------------------------------;
;                        Delay for one second                           ;
;-----------------------------------------------------------------------;
oneSec:
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	Dlay 100000                 ;  Delay 0.1s
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
 return 



 end
 

Attachments

  • schmatics_200.jpg
    schmatics_200.jpg
    41 KB · Views: 864
Sigma150 said:
This makes no sense since nowhere in my code do those LEDs illuminate. What is going on?

This makes perfect sense and the behaviour is expected.

Remove the single resistor in the common anode of the LED bar segment display and connect the pin to +3V instead. Use individual resistors in series for each LED segment going to the PIC.
 
Sigma150 said:
Also dont you only need one resistor if all the leds have the exact same specifications? (like on this website https://www.theledlight.com/ledcircuits.html)

No, it's EXTREMELY poor practice to put LED's in parallel in that way, even if the same colour - if they were EXACTLY the same, and continued to be EXACTLY the same, it would be OK. But things are never EXACTLY the same, and they will change over time as well.
 
While it is bad practice to parallel LEDs, this can not be the problem in this case. If you have 4 Leds connected to 5V and some of them have 0v as there other connection then the ones with 0v will light - the brightness may vary but LED connected to 5V will not light up. From the description of the problem some pins that are connected to 5V still light the corresponding LED.

I don't know the answer to the problem but I do know that no one has added anything constructive to find the answer.

Mike.
 
P.S.
It is now approaching midnight here and I'm going to bed. I'll have a look tomorrow and see if I can spot the problem.

Mike.
 
Pommie said:
P.S.
It is now approaching midnight here and I'm going to bed. I'll have a look tomorrow and see if I can spot the problem.

It strikes me as it may be a hardware problem?, with a short possibly across the IC pins? - it seems coincidental that the offending pins are directly across from pin 3.

Easy to try, unplug the PIC from it's socket, and try grounding the pins one by one with a wire and see what lights up!.
 
Hardware problem seems unlikly since I have replace the pic with a diffferent pic (same model:pic16f630) and the same problem continues.
 
I did what you said Goodwin and grounded each pin. Each pin lit up each led seperatly. I also tried adding

Code:
;

////////////////-------------HOURS LEDS

	BTFSC hours,d'3' ;    is bit set
        BCF PORTA,d'4' ;      yes, so illuminate LED
	
	BSF PORTA,d'1'   ;added code
	BSF PORTA,d'0'   ;added code

to see if I could get the LEDs to turn off. Something unusual happened. The first four leds to the far left worked the same(correctly) but now it didnt matter whether the LED connected to pin 3 was lit or not... The led connected to pin 12 stayed on and the led connected to pin 13 stayed off.
 
(While I don't program my PICs with that assembler language and don't quite understand the format....)

Perhaps you are using decimal literal prefixes for the BTFSC and BSF instead of binary literal prefixes? (the d'3' - does that always mean decimal or does it also mean binary in a binary orientated instruction??? should it be b'3') :shrug:

Rick
 
Code:
   __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF )

Finally, someone has posted fuse configuration code correctly, instead of an unreadable magic number. :D

You deserve all the help but sorry, I'm on my way out to visit a client. I'll try to take a look at your code as soon as I get back.
 
I can't see anything that would cause the problem you describe. I have however spotted 1 problem.
The instruction
DlayValue:2
only allocates 2 bytes therefore, you are writing over the minutes variable.

Also, although it should work fine the use of the tris instruction is not recommended.
Instead use,
Code:
   ;Set all ports to output 
   movlw B'00000000'    ; all bits low in W 
   bsf  STATUS,RP0      ;switch to bank 1
   movwf TRISA          ; contents of W copied to PORT A ... 
   movwf TRISC          ; and PORT B 
   bcf  STATUS,RP0      ; back to bank 0

Can I also suggest a more elegant way to count minutes and hours.
Code:
START    
   incf    minutes,F    ;inc minutes
   movlw   d'60'        ;check to see if minutes have reached 60
   subwf   minutes, w
   btfss   STATUS,Z 
   goto    DoneTime     ;Not at 60 yet
   clrf    minutes      ;reached 60 so set to 0
   incf    hours,F      ;and increment hours
   movlw   d'13'        ;check to see if hours have reached 13
   subwf   hours, w
   movlw   1
   btfsc   STATUS,Z     ;skip the store if we haven't reached 13
   movwf   hours        ;set hours to 1
DoneTime

Having your constants in variable is not recommended. I assume you rewrite them because you think they may be getting corrupted.

I notice also, the line
Code:
   incf hours, d'1'   ;increment the hours by one
The comment suggest you think the 1 indicates how much to increment hours by.
The 1 tells the processor to store the value back in hours and is the same as.
Code:
   incf hours,F ; edited because I'm stupid.

HTH

Mike.
 
Sigma150 said:
Hardware problem seems unlikly since I have replace the pic with a diffferent pic (same model:pic16f630) and the same problem continues.

NOT the PIC, the board you're connecting it to! - replacing the PIC wouldn't help. Have you tried it without the PIC as I suggested?, and manually operated the LED's.
 
Well I haven't replaced the breadbord that I was connecting the components to but I have moved all the compenents on a different spot farther down on the breadboard. Nothing changed. I have illuminated each LED seperatly so the display doesnt seem to be the problem. I will make all the changes to the code that people have suggested and see if anything happens.
 
Sigma150 said:
when the LED that is to the far left(connected to pin 3) illuminates the two LEDs on the far right (connected to pins 12 an 13) also illuminate. This makes no sense since nowhere in my code do those LEDs illuminate. What is going on?

Thanks in advance

Code:
 LIST R=DEC
 INCLUDE "p16f630.inc"
	__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF ) 
	ERRORLEVEL -224        ;remove tris message

 CBLOCK 0x020                ;  Variable Declaration
	DlayValue:2                  ;  Requires 24 Bit Counter (w/ WREG)
 	minutes
	hours
	int13
	int60
 ENDC

	;Set all ports to output
	movlw B'00000000'    ; all bits low in W
	tris PORTA           ; contents of W copied to PORT A ...
	tris PORTC           ; and PORT B

	;set time variable
	movlw d'12' ;hours cant start at zero, start time at 12'oclock
	movwf hours
	
	movlw 0x00
	movlw minutes ;start minutes at zero
	
	;set general variable
	movlw d'13'
	movwf int13
	
	movlw d'60'
	movwf int60

	;set display
	movlw 0xFF		;all lights off		
    movwf PORTA
    movwf PORTC
...

I think you are making a logical error. doesn't movlw require 2 parameters?
because I see movlw 0xFF, and if it means move data, normally the parameters are the source and the destination.

Also, you have your LEDS connected in an inverted fashion, You must remember that 0x00 is all LED's on.

The way you can get the proper bit pattern is to subtract the number you want from 0xFF (which is 255).

But rather than creating a complex situation, why not connect the cathodes of the LED's together through 100+ ohm resistors? so that the lights will go on properly without worrying about subtraction.

Let me show you:

If you were to continue using the inverted fashion like you use now:

00000000 = 0xFF = 0
00000001 = 0xFE = 1
00000010 = 0xFD = 2
00000011 = 0xFC = 3
.....


and if you were to follow my suggestion and go natural, you would get:

00000000 = 0x00 = 0
00000001 = 0x01 = 1
00000010 = 0x02 = 2
00000011 = 0x03 = 3
.....

It is your choice which method to choose, but let me tell you, my method seems easier to use, and it is more natural. In fact, if you wanted to, you can take the lowest 4 bits and drive them into a 74xx47 7-segment decoder and the display will show the right numbers.
 
mstechca said:
I think you are making a logical error. doesn't movlw require 2 parameters?
because I see movlw 0xFF, and if it means move data, normally the parameters are the source and the destination.

Why try and comment on something you obviously don't know the first thing about?.

MOVLW is 'MOVe Literal to W' and only takes a single parameter (obviously!).

This is the most basic PIC instruction there is, so proves you don't have the faintest clue what you're talking about!.
 
I tried this improved code but it still has the same problem.

Code:
LIST R=DEC
 INCLUDE "p16f630.inc"
	__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF ) 


 CBLOCK 0x020                ;  Variable Declaration
	minutes
	hours
	d1
	d2
	d3
 ENDC

   ;Set all ports to output
   movlw B'00000000'    ; all bits low in W
   bsf  STATUS,RP0      ;switch to bank 1
   movwf TRISA          ; contents of W copied to PORT A ...
   movwf TRISC          ; and PORT B
   bcf  STATUS,RP0      ; back to bank 0 

	;set time variable
	movlw d'12' ;hours cant start at zero, start time at 12'oclock
	movwf hours
	
	movlw 0x00
	movlw minutes ;start minutes at zero
	

	;set display
	movlw 0xFF		;all lights off		
    movwf PORTA
    movwf PORTC

START   
;//Pommie's code/////////////
   incf    minutes,F    ;inc minutes
   movlw   d'60'        ;check to see if minutes have reached 60
   subwf   minutes, w
   btfss   STATUS,Z
   goto    DoneTime     ;Not at 60 yet
   clrf    minutes      ;reached 60 so set to 0
   incf    hours,F      ;and increment hours
   movlw   d'13'        ;check to see if hours have reached 13
   subwf   hours, w
   movlw   1
   btfsc   STATUS,Z     ;skip the store if we haven't reached 13
   movwf   hours        ;set hours to 1
;//Pommie's code/////////////
DoneTime 

	;display the time
	
	;clear display
    movlw 0xFF	
    movwf PORTA 
	movlw 0xFF
    movwf PORTC 

;/////////////////-------------HOURS LEDS

	BTFSC hours,d'3' ;    is bit set
    BCF PORTA,d'4' ;      yes, so illuminate LED
	
;	BSF PORTA,d'1'
;	BSF PORTA,d'0'

	
	BTFSC hours,d'2'
    BCF PORTC,d'5'

	BTFSC hours,d'1' ;    is bit set
    BCF PORTC,d'4' ;      yes, so illuminate LED
    
	BTFSC hours,d'0'
    BCF PORTC,d'3'


	


	;delay
	CALL myDELAY


	goto START


;/////.1 Seconds Delay
myDELAY:
	movlw	0x1F
	movwf	d1
	movlw	0x4F
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

			;2 cycles
	goto	$+1
 return
 end
 
The only answer left is your hardware must have a problem. As I said earlier, I cannot see how it could cause the problem you describe but just in case, can you change your resistors to higher value ones - around 1K should work. Such that they are all wired as shown below.

Edit,
Another thing to try is changing your code to
Code:
;/////////////////-------------HOURS LEDS 

   movlw b'11101111'
   BTFSC hours,d'3' ;    is bit set 
    movwf PORTA
    
   BTFSC hours,d'2' 
    BCF PORTC,d'5' 

   BTFSC hours,d'1' ;    is bit set 
    BCF PORTC,d'4' ;      yes, so illuminate LED 
    
   BTFSC hours,d'0' 
    BCF PORTC,d'3'

Mike.
 
Last edited:
I agree here, put a resistor on each LED. Only something like 470 Ohms will be required. Your problem here could be that one resistor is drawing to much powering the leds as they are and your pic is going into brown out, especially from a 3v power supply.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top