View previous topic :: View next topic |
Author |
Message |
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Dec 23, 2010 11:18 am Post subject: PCINT Interrupts how to use? |
|
|
I want to use PCINT8 as an Interrupt but am having a hard time finding some sort of example on how to use these sort of Interrupts in Bascom I can find little bits but not a step by step example that explains it can any body point me to one. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Thu Dec 23, 2010 11:34 am Post subject: |
|
|
did you checked the pcint_change.bas sample from the samples dir? _________________ Mark |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Dec 23, 2010 11:45 am Post subject: |
|
|
Did not see that! I have been going through the help trying to work it out I will have a look at the example and see if I can work it out thank you for the pointer (again!)
regards Paul |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Thu Dec 23, 2010 12:02 pm Post subject: |
|
|
the sample shows 2 ways, it would be better to make an example for non interrupt based, and interrupt based.
maybe an enthusiast user can make better samples _________________ Mark |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Dec 23, 2010 12:05 pm Post subject: |
|
|
So looking at the example
Enable Interrupts 'enable global ints
Enable Pcint0 'we enable pcint0 as this has pcint0-pcint7
Then would
Enable Pcint1 cover pcint8-pcint15
Regards paul |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Dec 23, 2010 12:17 pm Post subject: |
|
|
When I get this hardware to work I will post the whole program. I am trying to respond to a DTMF decoder when it has a lock on a tone pair. As I can do this in a loop I will do it that way as an example but also want to do it as a jump due to an interrupt so that it does not slow things up. The reason for PCINT8 is that its spare on the board to be used. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Thu Dec 23, 2010 12:23 pm Post subject: |
|
|
Paulvk wrote: | So looking at the example
Enable Interrupts 'enable global ints
Enable Pcint0 'we enable pcint0 as this has pcint0-pcint7
Then would
Enable Pcint1 cover pcint8-pcint15
Regards paul |
yes that is right. _________________ Mark |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Tue Dec 28, 2010 7:21 am Post subject: |
|
|
Ok I have the pin change interrupt working (PCINT8) but how do I get it to respond only to a rising change ie logic 0 to 1 but not when it goes back 1 to 0 again. |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Tue Dec 28, 2010 7:42 am Post subject: |
|
|
You can not.
PCINT.... are only change interrupts and can not be configured.
If you need rising or falling then you need to use int0 or int1 for example.
The possibility you have with PCINT is to read the port pin on interrupt and determine the state of the input, so you can determine if this is the interrupt to perform the wanted action.You hopefuly masked the interrupt, otherwise you also get int's from the other pcints in that group (I did not read the sample).
See the AVR datasheets for external interrupts.
Hubert |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Tue Dec 28, 2010 8:02 am Post subject: |
|
|
Ok that confirms what I suspected after reading through the data sheets and bascom (a number of times) yes I have masked the interrupt, I did not use one of the normal interrupts as I did not want to make a total new artwork and did not know then that INT0, INT1 would be the best to use. It has taught me more though, I will also learn more as I work around the state changes and move on to the next problem I have given myself, how to swap around binary 0100 to 0010 as I have the 4 bits around the wrong way at least the hardware works it detects the DTMF and decodes it. |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Tue Dec 28, 2010 9:27 am Post subject: |
|
|
If you talk about input bits in a nibble, there are a few possibilities.
You can make a 16-byte conversiontable but the easiest maybe not most elegant is to declare 1 variable read the corresponding bitlocation and write the bit to the new location in the variable. An other mothode would be to AND, then shift and add also in extra variables 4 times ( a bit more time consuming).
Hubert |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Tue Dec 28, 2010 10:02 am Post subject: |
|
|
This has the interrupt working for a 0 to 1 transition and the bits I want are 1,2,3,4 as I used 0 as the pin change a re-do of the hardware would get rid of the mirror bits but what the heck I have learnt more this way.
Code: | Isr_pcint1:
If Pinc.0 = 1 Then
Cls
Locate 1 , 1
Lcd "Pin change "
'As you see the mask does not change, so to find out which pin changed,
'you need to read the PINC register.
'Wait 2
A = Pinc
B = A And &B0001_1110 'Mask To Get to get bits 1,2,3,4
Shift B , Right
Locate 2 , 1
Lcd B
' C = A And &B0000_1111 'Mask To Get Only Low Nibble Of Byte , Store As C
'Wait 2
Return
End If
Return
|
Regards Paul |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sat Jan 15, 2011 8:38 am Post subject: |
|
|
Ok I have a working example of pin change interrupt this uses a VOIP ATA to enable remote control of some relays, it answers the call after a pre set number of rings then waits and decodes DTMF tones sent to it. This is the prototype made with 3 seperate boards I am now making a finished version on one board this code would show how to use the interrupts if mark wants he can use it to replace the example in bascom. Any improvements/comments are most welcome.
Code: | '---------------------------------------------------------------------------
'---------------------------------------------------------------------------
'
' DTMF-DECODE.BAS
' This shows how to use the PIN CHANGE interrupts to decode DTMF using
' a HT9170 DTMF decoder that has a 4 bit output to enable remote control over
' a VOIP telephone adapter. It counts the number of rings and loops the adapter
' at a pre set number of rings then waits for DTMF digits
'---------------------------------------------------------------------------
$regfile = "m168pdef.dat" 'Using the Mega168p
$crystal = 8000000
'$crystal = 1000000 'Using the internal RC at 8 meg
$baud = 19200
'Print "{027}[2J"; ' when you have a terminal emulator, this will clear the screen
'Print "Test M88 ints" ' init message
'The M88 and M168 can detect a level change on all port pins.
Dim A As Byte 'These are 8 bits
Dim B As Byte
Dim D As Byte
Dim R As Byte
Dim Timeout As Byte
Dim Dtmf As String * 1 'Only one character in this string
Dim Con As String * 16 'Can be 16 characters in this string
Config Pinc.0 = Input 'enable port as input
Config Pinb.7 = Input 'enable port as input
Config Pinb.2 = Output 'enable port as output
Config Pind.6 = Output 'enable port as output
Config Pind.7 = Output 'enable port as output
'An Alias makes it easy to refer to the PIN
Rly Alias Portd.7
Led Alias Portb.2 'the GATE of the FET transistor connected to PortB.2,
'with resistor (390 Ohm) to turn on LCD backlight take to GND
Relay Alias Portd.6 'A transistor on this port operates a relay to loop the line
Enable Interrupts 'enable global Interrupts
Enable Pcint0 'we enable pcint0 as this has pcint0-pcint7
On Pcint0 Isr_pcint0 'we jump to this label when one of the pins is changed
Pcmsk0 = &B10000000
'76543210--pcint7--pcint0 pcint7 is on
Enable Pcint1 'we enable pcint1 as this has pcint8-pcint15
On Pcint1 Isr_pcint1 'we jump to this label when one of the pins is changed
Pcmsk1 = &B00000001 'enable pcint8 (portc.0)
'15.14.13.12.11.10.9.8--pcit8 is on With pcmsk you individualy select which pins must react on a logic level
'When you write a 1, the change in logic level will be detected.
Set Led 'Turn on LCD backlight
Do
Cls
Locate 1 , 1
Lcd "loop de loop"
Lcd R
Locate 1 , 14
Lcd Timeout
Locate 2 , 1
Lcd "NUMBERS " ; Con
If R > 4 Then
Set Relay 'This sets the port to a 1 which is +5V turning on the transistor and with it the relay
R = 0
End If
If Len(con) > 6 Then 'If too many digits are sent it clears variable to start over
Con = ""
End If
Wait 1
If Relay = 1 Then 'Start a time out counter
Timeout = Timeout + 1
End If
If Timeout = 60 Then 'When the counter = 1 min hang up
Timeout = 0 'Reset counter to 0
Con = "" 'Clear any digits
Reset Relay 'Release line
Waitms 20 'wait for things to stablize
R = 0 'Reset ring counter
End If
If Con = "##58##" Then
Reset Relay 'This resets the port to a logic 0 which is 0V turning off the transistor and with it the relay
Con = ""
Waitms 20
R = 0
End If
If Con = "##66##" Then
'Cls
'Locate 1 , 1
'Lcd "SET RLY"
'Wait 1
Set Rly
'Pind.7 = 0
Con = ""
End If
If Con = "##67##" Then
'Cls
'Locate 1 , 1
'Lcd "RESET RLY"
'Wait 1
Reset Rly
'Pind.7 = 0
Con = ""
End If
Loop
Isr_pcint0:
If Pinb.7 = 0 Then
Cls 'Clear the LCD
Locate 1 , 1
Lcd "Phone is Ringing"
Locate 2 , 1
Lcd Str(r)
R = R + 1
Do
Waitms 100 'Wait 100 mili seconds
Loop Until Pinb.7 = 1 'Loop until pinb.7 goes to a logic 1 +5V
'this tells us that the line is not ringing
End If
Return
Isr_pcint1:
If Pinc.0 = 1 Then 'There is a DTMF digit to decode
Timeout = 0 'Reset timeout counter
'Cls
'Clear the LCD
'Locate 1 , 1
'Lcd "Pin change "
'As you see the mask does not change, so to find out which pin changed,
'you need to read the PINC register.
A = Pinc 'Read pin register for portC
B = A And &B0001_1110 'Mask To Get to get bits 1,2,3,4
'&B0000_1111 Mask To Get Only Low Nibble Of Byte
'&B1111_0000 Mask To Get Only High Nibble Of Byte
Shift B , Right 'Move the bits one to the right so they represent
'a 4 bit binary number 0 to 16
'Locate 2 , 1
'Lcd B
'Since I have the 4 bits backwards I have to translate the values
Select Case B
Case 5 : Dtmf = "0"
Case 8 : Dtmf = "1"
Case 4 : Dtmf = "2"
Case 12 : Dtmf = "3"
Case 2 : Dtmf = "4"
Case 10 : Dtmf = "5"
Case 6 : Dtmf = "6"
Case 14 : Dtmf = "7"
Case 1 : Dtmf = "8"
Case 9 : Dtmf = "9"
Case 13 : Dtmf = "*"
Case 3 : Dtmf = "#"
Case 11 : Dtmf = "A"
Case 7 : Dtmf = "B"
Case 15 : Dtmf = "C"
Case 0 : Dtmf = "D"
End Select
'Cls 'Clear the LCD
'Locate 2 , 5 'Print at line 2 position 5 on LCD
'Lcd Dtmf 'Print the DTMF value to the LCD
Con = Con + Dtmf 'Add the value to the string
'Locate 2 , 7 'Print at line 2 position 7 on LCD
'Lcd Con 'Print the recived values thus far to the LCD
End If
Return
End
|
|
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Sat Jan 15, 2011 5:50 pm Post subject: |
|
|
The ENABLE INTERRUPTS would normaly be the last thing after all the setup.
I would also not spend so much time in the ISR routines because as long as you are in the ISR no other interrupt is serviced with atmega.
This might not be a problem with your specific application but it is not a good practice in general.
Interrupts should only set a condition and then you do the evaluation from the main routine possibly in a sub.
If you have 4 pins that can change then you could use all four interrupts and branch in the main program after reading the port and AND with an "ON VALUE" or "CASE".
Just some thoughts
Hubert |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sun Jan 16, 2011 6:59 am Post subject: |
|
|
All information is welcome, the events that trigger the interrupts are hardware events one is when the DTMF chip has valid tone pairs the other is when the ATA puts ring on the line, it could have been done in a loop but I wanted to teach myself how to use the interrupts. I do understand that spending as short a time in the interrupt as possible is the best way but want I wanted to do was to have a program that runs but do something else when hardware events happen then go back to where it was and keep running. The project has served its purpose well it has and still is teaching me a lot plus I will have a usefull bit of harware to control devices with. When its finnished I will make both the code and hardware plans avaliable for all. |
|
Back to top |
|
|
|