PDA

View Full Version : Can't get switch to work



JeffnDana
- 4th April 2007, 17:46
I'm just starting out and trying to create a very simple clock as a first project. I'm using a PIC16F628A and a DS1307 Real Time Clock. For some reason I'm unable to get any input response from a switch. I checked the wiring with a volt meter and it shows the correct voltage change when the switch is pressed so I assume I have overlooked something in the code. At this point I am just trying to have my display read 12:30 if the LeftButton is pressed. Any help is appreciated. My code follows.

Thanks,
Jeff

DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 19200
define DEBUG_MODE 0 ' 1 = inverted, 0 = true

' DS1307 control pins
SDA VAR PORTB.1 ' DS1307 SDA pin #5
SCL VAR PORTB.2 ' DS1307 SCL pin #6

TRISA = %11111111

LeftButton var PORTA.1 ' Control Button
RghtButton var PORTA.2

second var byte
minute var byte
hour var byte
tock var byte

PAUSE 1000 ' Allow power to stabilize on power-up

GOSUB Blink_1200 ' Blink 12:00 time on entry


Tick:

gosub Read_1307 ' Read the time from the DS1307 Clock

tock = second // 2 ' Get the Mod of second

If tock = 0 then
High PORTB.0 ' Turn on LED connected to PORTB.0
debug "P",12,"~" ' Turn on colon
else
Low PORTB.0 ' Turn off LED connected to PORTB.0
debug "P",0,"~" ' Turn off colon
endif

' Display time
DEBUG "D",hour DIG 1,hour DIG 0,minute DIG 1, minute DIG 0

Goto Tick ' Go back to Tick



Read_1307:
' Read time Seconds,Minutes,Hours
I2CREAD SDA,SCL,$D0,$00,[second,minute,hour] ' Read time from DS1307
return

Write_1307:
' Set time to 12:00
I2CWRITE SDA,SCL,$D0,$00,[$00,$1E,$C,$01,$01,$01,$00,$90] ' Write to DS1307
RETURN ' Sec Min Hr Day D M Y Control

Blink_1200:
' Write 12:00 on display
DEBUG "D",1,2,0,0
debug "P",12,"~" ' Turn on colon
pause 1000
debug "C","~" ' Clear Display
debug "P",0,"~" ' Turn off colon
pause 1000

if LeftButton = 1 then
gosub Write_1307
goto Tick
endif

Goto Blink_1200



End

skimask
- 4th April 2007, 18:03
I was going to rewrite everything for you, but then you wouldn't learn anything and we'd be here for months.

Look at your code as you've written it. Look at it as a bunch of blocks of code instead of lines. Look at the structure of it. Follow your code thru. You'll see that it never gets a chance to loop around and around the way you probably want it to. I see a couple of GoSub's without RETURNs (very bad idea!). # of Gosubs = # of Returns.

You've got the jist of it, the idea is ok. The reading and writing of the 1307 probably won't work, don't know...but that's beside the point at the moment. Try putting all of your subroutines at either the start of the program and jump over them to a 'main loop'.

While your at it, do a search here on the site for DS1307 and you'll find a load of hits for program ideas.

Bruce
- 4th April 2007, 19:12
Hi Jeff,

Give this a shot. I've tested it on a 16F627A, and it works fine.


DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 19200
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true

' DS1307 control pins
SDA VAR PORTB.1 ' DS1307 SDA pin #5
SCL VAR PORTB.2 ' DS1307 SCL pin #6

TRISA = %11111111

LeftButton var PORTA.1 ' Control Button
RghtButton var PORTA.2

second var byte
minute var byte
hour var byte
tock var byte

CMCON = 7 ' all digital - comparators disabled
PAUSE 1000 ' Allow power to stabilize on power-up

GOSUB Blink_1200 ' Blink 12:00 time on entry


Tick:
gosub Read_1307 ' Read the time from the DS1307 Clock

tock = second // 2 ' Get the Mod of second

If tock = 0 then
High PORTB.0 ' Turn on LED connected to PORTB.0
DEBUG "P",12,"~" ' Turn on colon
else
Low PORTB.0 ' Turn off LED connected to PORTB.0
DEBUG "P",0,"~" ' Turn off colon
endif

' Display time
DEBUG "D",hour DIG 1,hour DIG 0,minute DIG 1, minute DIG 0
PAUSE 1000
Goto Tick ' Go back to Tick

Read_1307:
' Read time Seconds,Minutes,Hours
I2CREAD SDA,SCL,$D0,$00,[second,minute,hour] ' Read time from DS1307
return

Write_1307:
' Set time to 12:00
I2CWRITE SDA,SCL,$D0,$00,[$00,$00,$0C,$01,$01,$01,$00,$90] ' Write to DS1307
RETURN ' Sec Min Hr Day D M Y Control

Blink_1200:
' Write 12:00 on display
DEBUG "D",1,2,0,0
DEBUG "P",12,"~" ' Turn on colon
pause 1000
DEBUG "C","~" ' Clear Display
DEBUG "P",0,"~" ' Turn off colon
pause 1000

if LeftButton = 1 then
gosub Write_1307
'goto Tick
return
endif

Goto Blink_1200
End
You can compare this to your original to see where I made the few changes.

JeffnDana
- 4th April 2007, 19:54
Bruce:

Thanks for your help. Those changes solved it. Which line was responsible for keeping it from working?

CMCON = 7 ' all digital - comparators disabled

OR

The RETURN in the IF THEN block?

Thanks again for your help!

Jeff

mackrackit
- 4th April 2007, 20:14
Bruce:

Thanks for your help. Those changes solved it. Which line was responsible for keeping it from working?

CMCON = 7 ' all digital - comparators disabled

OR

The RETURN in the IF THEN block?

Thanks again for your help!

Jeff

That is why Skimask did not do a re-write for you, you did not learn or listen to him.

Blocks of code, GOSUBS/RETURNS,etc and CMCON.

Print you code and the code Bruce did, study side by side - line by line.

Your first try was not far off for a first timer:) pun intended

Bruce
- 4th April 2007, 20:44
Hi Jeff,

CMCON was the show stopper for the switch input, but GOSUB's without the
RETURN (as already mentioned) was another problem.

You might also want to include a conversion routine just after your GOSUB
Read_1307 to convert before displaying the results.

Something like this;

Temp var byte ' for conversion routine

Then just after GOSUB Read_1307 insert GOSUB Convert.

Here's Convert:


Convert:
IF hour >=$10 THEN
Temp = (hour>>4)&$0F
Temp = (temp*10)+(hour&$0F)
hour=temp
ENDIF
IF minute >=$10 THEN
Temp = (minute>>4)&$0F
Temp = (temp*10)+(minute&$0F)
minute=temp
ENDIF
IF second >=$10 THEN
Temp = (second>>4)&$0F
Temp = (temp*10)+(second&$0F)
second=temp
ENDIF
RETURN
I just happened to be working on a few routines for the SLED-C4, and figured
I would give you a boost.

And, yes, you should also get cozy with the 16F62xA datasheet so you'll
know what each I/O-pin can do & what you'll need to write to certain
registers to make things work right...;o}