PDA

View Full Version : How to set sequence of interrupt for PIC



chai98a
- 19th June 2008, 12:22
I did study about pic basic code but confuse about sequence of interrupt. for now i did make project with 5 sw buttom, IR for control o/p , time ds1307,Temp DS18s20 and 7seg (muliple scan dis)for display time and temp.
Now,our code work with for all but run with individual code.
I have try to combine all code together found problem with flashing on 7 seg or slow reapond of o/p and hang .

I think fail of interrupt management How can advise me about interrupt flow for me

I used pic16F877A / 4 Mhz used bootloader of microcode for try

skimask
- 19th June 2008, 13:33
And the code is a state secret?

chai98a
- 21st June 2008, 11:16
Here is my code , Time/temp display and IR decode

Pls advise ...

Define LOADER_USED 1
DEFINE OSC 4
@ Device pic16F877A, xt_OSC, BOD_OFF, PWRT_ON, WDT_OFF, PROTECT_OFF 'WRT_On

Segments Var PORTC
Digits Var PORTD 'D
i Var Byte
n Var Byte
Value Var Word

' Allocate variables
command var Byte ' Storage for command
J var Byte ' Storage for loop counter
temp var Word ' Storage for temperature
T VAR Word
DQ var PORTD.5 ' Alias DS1820 data pin
DQ_DIR var TRISD.5 ' Alias DS1820 data direction pin
read_done var Byte

'=================DS1307

'include"modedefs.bas"
'SO var portc.6 ' tx
DPIN var PORTE.0 ' I2C DATA PIN 24LC256 and ds1307,with 4K7 pull up
CPIN var PORTE.1 ' I2C CLOCK PIN with pulled up resister 4K7
B1 var Byte
B2 var Byte
B3 var Byte
B4 var Byte
B5 var Byte
B6 var Byte
B7 var Byte
B8 var Byte

BB var Byte
B_H var Byte
B_L var Byte
B_W VAR Word
SEC VAR Byte
M VAR Byte
HR VAR Byte
TIMES VAR Word
LOOPP VAR Byte

'==================DS1307

'IR +++++++++++++++++++++
pulses VAR Byte[16]
BitMask VAR Word
U VAR Byte 'loop index
V VAR Byte 'byte index
LeadIn VAR Word 'start pulse
Lstatus con 10
Bot con 15
Cmd con 17
Bot1 Var Byte
Cmd1 var Byte

Botx Var Byte
Cmdx var Byte
Botxstr Var Byte
Cmdxstr var Byte
n = 0
'===========ir

'TRISA = $F1 '1
'PORTA = $FF
TRISB = $01 '1
PORTB = $01 '1
TRISc = $00 ' Set segment pins to output
portc = $FF
TRISd = $F0 ' F0 Set digit pins to output
portd = $FF 'FF
TRISE = $00 ' Set digit pins to output
portE = $FF 'FF

On Interrupt GoTo IR_B0
INTCON = %10010000 ' Enable RB0 interrupt

' Set time & date to 21:58:00 Tuesday 6th of July 2004
' [$00,$20,$21,$2,$6,$7,$4]
' sec,min,hrs,date,month,year
' I2CWRITE DPIN,CPIN,$D0,$00,[$00,$20,$21,$2,$6,$7,$4] ' Write to DS1307

ADCON1 = 6 ' Set PORTA and PORTE to digital

'debug ====
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_SPBRG 12 ' 19200 Bauds ,4 m
'debug ====

'pause 150

mainloop:
LOOPP = 0
GoSub TEMP_PROCESS
date:
GoSub TIMEDS1307
GoTo mainloop

'=========================
TEMP_PROCESS:
GoSub init1820 ' Init the DS1820

command = $cc ' Issue Skip ROM command

GoSub write1820

command = $44 ' Start temperature conversion

GoSub write1820

'Pause 2000 ' Wait 2 seconds for conversion to complete

GoSub init1820 ' Do another init

command = $cc ' Issue Skip ROM command

GoSub write1820

command = $be ' Read the temperature

GoSub write1820

GoSub read1820

'Display the decimal temperature

value = ((temp>> 1)*100)+((TEMP.0*5)*10)
GoSub display
If LOOPP < 254 Then 'goto TIMEDS1307
LOOPP = LOOPP + 1
GoTo TEMP_PROCESS
EndIf
Return 'return to mainloop

' Initialize DS1820 and check for presence
init1820:
Low DQ ' Set the data pin low to init
Pauseus 500 ' Wait > 480us
DQ_DIR = 1 ' Release data pin (set to input for high)

Pauseus 100 '100 ' Wait > 60us
If DQ = 1 Then
'Lcdout $fe, 1, "DS1820 not present"
PORTC = $39
Low DIGITS.0
PAUSE 150
PORTC = $0
'Pause 150
GoTo mainloop ' Try again
EndIf
Pauseus 400 ' Wait for end of presence pulse
Return


' Write "command" byte to the DS1820
write1820:
For i = 1 To 8 ' 8 bits to a byte
If command.0 = 0 Then
GoSub write0 ' Write a 0 bit
Else
GoSub write1 ' Write a 1 bit
EndIf
command = command >> 1 ' Shift to next bit
Next i
Return

' Write a 0 bit to the DS1820
write0:
Low DQ
Pauseus 60 ' Low for > 60us for 0
DQ_DIR = 1 ' Release data pin (set to input for high)
Return

' Write a 1 bit to the DS1820
write1:
Low DQ ' Low for < 15us for 1
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
Pauseus 60 ' Use up rest of time slot
Return


' Read temperature from the DS1820
read1820:
For i = 1 To 16 ' 16 bits to a word
temp = temp >> 1 ' Shift down bits
GoSub readbit ' Get the bit to the top of temp
Next i
Return

' Read a bit from the DS1820
readbit:
temp.15 = 1 ' Preset read bit to 1
Low DQ ' Start the time slot
@ nop ' Delay 1us at 4MHz
DQ_DIR = 1 ' Release data pin (set to input for high)
If DQ = 0 Then
temp.15 = 0 ' Set bit to 0
EndIf
Pauseus 60 ' Wait out rest of time slot
Return

'========================================

chai98a
- 21st June 2008, 11:17
' and next

'READ TIME FROM DS1307

TIMEDS1307:
LOOPP=0
loop:
i2cread dpin,cpin,$d0,$00,[b1,b2,b3,b4,b5,b6,B7]
'pause 10
'BB=B1
'gosub conv
'SEC = ((B_H*10)+B_L)
'serout SO,t9600,["sec ",#SEC,10]
BB=B2
GoSub conv
M=(B_H*10)+ B_L
'serout SO,t9600,["Min ",#M,10]
BB=B3
GoSub conv
hR=(B_H*10)+ B_L
'serout SO,t9600,["Hour ",#HR,":",#M,":",#SEC,10]
value = ((HR*100) + m)
'serout SO,t9600,["TIMES ",#VALUE,10]

GoSub display_TIME
If LOOPP > 254 Then loopp =0 :Return ' GOTO MAINLOOP
LOOPP=LOOPP+1
GoTo loop
'RETURN mainloop

conv:
B_L=BB&%00001111
B_H=BB&%11110000
B_H=B_H>>4

Return

'================== 7 seg ment display ==============================
display: 'Display Temp
Disable Interrupt

PORTC =$58 '$39 "C"

Low DIGITS.0
PAUSE 3 'INCREASE BRITE OF LED "C"
'PAUSEUS 850
'PORTC =$00 '$39 "C"
'value = 125

For i = 1 To 4 ' Loop through 4 digits

n = Value Dig i ' Get digit to display

' Gosub display1 ' Display the value
Digits = $ff

LookUp n, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F,_
$77, $7C, $39, $5E, $79, $71, $0FF], Segments

If i = 2 Then segments = segments + 128 'Digit 2 show dot

Digits = ~DCD i

PAUSE 1 'INCREASE BRITE OF LED "number"
Next i

Enable Interrupt
Return

display_TIME: 'Display time
Disable Interrupt
dot var Byte

For i = 0 To 4 ' Loop through 4 digits

n = Value Dig i ' Get digit to display

' Gosub display1 ' Display the value
Digits = $ff

LookUp n, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F,_
$77, $7C, $39, $5E, $79, $71, $0FF], Segments
If dot < 100 Then
If i = 2 Then segments = segments + 128 'Digit 2 show dot
Digits = ~DCD i
dot = dot+1
Else
dot = dot+1
If dot < 254 Then
Digits = ~DCD i
Else
dot = 0
digits = ~DCD i
EndIf
EndIf

PAUSE 1 'INCREASE BRITE OF LED

Next i
Enable Interrupt
Return
'+++++++ir decode +++++++++++++++++++++++++

Showoutput:

'HSEROUT ["Bot ",dec bitmask.LOWBYTE,13,10]
'HSEROUT ["Cmd ",dec bITMASK.highbyte,13,10]

'botx = bitmask.lowbyte
'Cmdx = bitmask.highbyte
Disable Interrupt
If bitmask.LowByte = 164 Then ' 36 BOTTM 9
If bitmask.HighByte = 64 Then ' 32
Toggle PORTB.7 'RELAY B.1
EndIf
EndIf
If bitmask.LowByte = 36 Then ' 36 BOTTM 9
If bitmask.HighByte = 32 Then ' 32
Toggle PORTB.6 'RELAY B.1
EndIf
EndIf
If bitmask.LowByte = 168 Then ' 36 BOTTM 9
If bitmask.HighByte = 32 Then ' 32
Toggle PORTB.5 'RELAY B.1
EndIf
EndIf

BITMASK =0

'enable interrupt
GoTo ActiveINT_B0

'============IR decode =======================
Disable
IR_B0:

PulsIn PORTB.0, 0, LeadIn
'Sumsung and Hitachi check
AB:

If LeadIn < 400 Then GoTo ActiveINT_B0 '885 hitachi, sumsung 400
If LeadIn > 1045 Then GoTo ActiveINT_B0

For U = 0 To 15
PulsIn PORTB.0, 1, pulses[U]

Next U
For U = 0 To 15
PulsIn PORTB.0, 1, pulses[U]

Next U
For U = 0 To 11
If (pulses[U] < 40) Or (pulses[U] > 300) Then
GoTo ActiveINT_B0
EndIf
If pulses[U] > 99 Then
BITMASK.0 = 1
BITMASK = BITMASK << 1
EndIf
BITMASK.0 = 0
BITMASK = BITMASK << 1
Next U

GoTo Showoutput

ActiveINT_B0: 'active interrupt b0
PULSES = 0
INTCON.1 = 0
value =0
Resume
Enable Interrupt
End