PDA

View Full Version : 16F627A to 16F88 conversion problem



PICpocket
- 17th February 2009, 23:46
I was working on a project and ran out of room on my 627A and switched over to a 16F88 spare that I had.

My code is a clock that can be programmed via IR signals. Strangely, the clock portion works fine, however the IR part no longer works. There was no problem changing the device over to the 88, and the program compiled just fine, so I am not sure what is wrong exactly.

Here is a copy of the code:


INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
Include "modedefs.bas"

DEFINE LOADER_USED 1 ' Using boot-loader for initial prototype
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 19200
define DEBUG_MODE 0 ' 1 = inverted, 0 = true

Enter CON 11 'Enter key on remote

Out VAR BYTE(4) '7 seg display
TChange VAR BYTE(4) 'Time change digits
Enable1 VAR BYTE(4) 'Power goes on for memory 1
Disable1 VAR BYTE(4) 'Power goes off for memory 1
Enable2 VAR BYTE(4) 'Power goes on for memory 2
Disable2 VAR BYTE(4) 'Power goes off for memory 2
TimeSet VAR BIT '1 = Enabled 0= Disabled
Second var byte
Minute2 VAR BYTE ' Ones column for minutes
Minute1 VAR BYTE ' Tens column for minutes
Hour2 VAR BYTE ' Ones column for hours
Hour1 VAR BYTE ' Tens column for hours
Counts VAR BYTE ' Counts for timer
Loop VAR BYTE ' Loop counter
Index VAR BYTE ' Index counter
IR_PULSE VAR BYTE(13) ' 13-bytes. 8 data ; 5 address
PULSE_IN VAR WORD ' Raw pulsin value
DBYTE VAR BYTE ' Holds 8-bit data byte
ABYTE VAR BYTE ' Holds 5-bit hardware address

Second = 0
Minute1 = 0
Minute2 = 0
Hour1 = 1
Hour2 = 2
Loop = 0

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, ReloadTMR1, ASM, no ; MUST be first
INT_Handler TMR1_INT, _T1handler, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

;--- Change these to match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq = 10 ; Frequency of Interrupts in Hz
@Prescaler = 2 ; Timers Prescaler setting
T1CON = $10 ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value

@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
GOSUB StartTimer ; Start the Timer

Main:
@ INT_ENABLE TMR1_INT
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main '// so clear outputs & return.
ENDIF
@ INT_DISABLE TMR1_INT
GOTO Verify

'--Main 2 used after values have been entered without Enter press to get around INT
Main2:
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main2 '// so clear outputs & return.
ENDIF

Verify: '// Read, Decode, then verify data
FOR Index = 0 TO 12 '// Setup to read-in 13 pulses
PULSIN PORTB.7,0,IR_PULSE[Index] '// Read 13 low-going pulses on RA.7
NEXT Index '// Loop x times
DBYTE = $FF '// Start with all 1's and find each 0
FOR Index = 0 TO 7 '// Get 8 "data" bits
IF IR_PULSE[Index] < 100 THEN DBYTE.0[Index]=0 '// Less than 1mS = 0
NEXT Index

Result:
Loop = Loop + 1
Out[Loop] = DBYTE + 1
If Out[Loop] = 10 then
Out[Loop] = 0
EndIF
DEBUG "D", Out[1],out[2],out[3],out[4]
PAUSE 500
IF Loop = 5 Then
Loop = 0
EndIF

If TimeSet = 1 then 'Time change
IF OUt[5] = 12 THEN 'If enter pressed, with valid time entry
IF (Out[1] = 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
ENDIF
IF (Out[1] <= 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
EndIF
GOTO Main
ENDIF
ENDIF




IF OUT[1]=1 AND Out[2]=7 and OUt[3]=7 and Out[4]=12 THEN 'TimeSet entry correct (177 + enter)?

Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 1 'If they enter the correct code, then unlock features

GOTO Main
ENDIF
GOTO Main2

T1handler:

Counts = Counts + 1 ; Increase the 1/10th sec count
IF counts = 10 then
Counts = 0
Second = Second + 1 'Calculate time and change values

If Second = 60 then
Minute2 = Minute2 +1
Second = 0
IF Minute2 = 10 THEN
Minute1 = Minute1 + 1
Minute2 = 0
IF Minute1 = 6 then
Hour2 = Hour2 + 1
Minute1 = 0
IF Hour2 = 10 THEN
Hour1 = Hour1 + 1
Hour2 = 0
endif
endif
endif
endif

IF Hour1 = 2 AND HOUR2 = 4 THEN 'Roll clock over from 23 to 0
Hour1 = 0
Hour2 = 0

endif

If Hour1 = 0 then 'If hour 1 is 0 then do not display it
Hour1 = 20 'SLED-C4 will not display anything if the
Endif 'value is above 10

DEBUG "D", Hour1,Hour2,Minute1,Minute2 ' Display time
DEBUG "P",12,"~" ' Display Colon
ELSE
@ INT_RETURN
ENDIF
@ INT_RETURN

;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM ; Calculate Timer Reload Constant
ReloadInst = 8 ; # of Intructions used to reload timer
if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
endif
else
error Invalid Prescaler
endif
ENDASM

@Timer1 = TMR1L ; map timer registers to a word variable
Timer1 VAR WORD EXT
TimerReload CON EXT ; Get the External Constant
TMR1ON VAR T1CON.0 ; Alias the Timers ON/OFF bit

;---Reload Timer1------
ASM
ReloadTMR1
MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
MOVLW LOW(TimerReload) ; 1 Add TimerReload to the
ADDWF TMR1L,F ; 1 value in Timer1
BTFSC STATUS,C ; 1/2
INCF TMR1H,F ; 1
MOVLW HIGH(TimerReload) ; 1
ADDWF TMR1H,F ; 1
MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
INT_RETURN
ENDASM

;---Start/Stop controls -----
StartTimer:
Timer1 = TimerReload ; Load Timer
TMR1ON = 1 ; start timer
RETURN

StopTimer:
TMR1ON = 0 ; stop timer
RETURN


Thanks for the help

Darrel Taylor
- 18th February 2009, 04:14
The 16F88 has a lot of Analog pins that need to be disabled.

It has an A/D module, the 627A only has comparators.
<br>

Archangel
- 18th February 2009, 06:20
16F648A uses the same data sheet (as the 627A) and has twice the code space.

PICpocket
- 18th February 2009, 15:38
Thanks for the responses. Ill figure out how to adjust my I/O pins (never done it) and im sure it would work fine.

I purchased 16F628A PIC's to replace the 16F627A that I was using. They seemed to have double the memory if I recall correctly (3.5kb as opposed to 1.75kb) and the 648's had 7kb of memory.

Did I miss something?

Darrel Taylor
- 18th February 2009, 19:20
Ill figure out how to adjust my I/O pins (never done it)

Then let's make the first one easy...
ANSEL = 0

Whenever you start using a new chip, the first thing you should do is look at the Comparator and Analog-to-Digital sections of the datasheet for the device you are using.

The different varieties of PIC's have many different ways of disabling the Analog functions, so you have to look in the datasheet to know which way to do it on that particular chip.

For the 16F88, the comparators are disabled at Power-Up.
For many other chips, that's not the case.
<br>