Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
multiple PWM capture
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    Forum Index -> ZX-1281
Author Message
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 16:47 PM    Post subject: Reply with quote

sturgessb wrote:
When its waiting for the idle state and to reach desired logic, does it only halt the task its in, or the entire mcu?
PulseIn() effectively halts everything while it is running. Interrupts are disabled and no task switching occurs. Note, however, that the RTC is updated for missed ticks after the pulse is received but other interrupt driven functions are dead in the water (e.g. serial I/O).

PulseIn() is completely implemented in software - that's why interrupts must be disabled. InputCapture(), on the other hand, is implemented in hardware and can read the widths of one or more pulses without shutting down everything else.
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 22:15 PM    Post subject: Reply with quote

Thanks for the help guys, got it working nicely with external interrupts on the zx128ne.

Is it possible to have an ISR driven by a PinChange Interrupt, if i wanted to put this code onto the 644 rather than the 128?

The docs show PCINT0 - 3. Does this equate to individual pins or Ports?

how are these enabled for ISR use? on the 128 I do this...
Code:

Register.EICRA = Bx0101_0101
   Register.EICRB = Bx0101_0101
   Register.EIMSK = Bx0000_1111     'enable INT0,1,2,3


what would be the equivilent for the 644 using PCINT0 - 3

Also, on the 644 and 328, are any of the interrupts needed for I2C?


Last edited by sturgessb on 05 January 2009, 22:39 PM; edited 1 time in total
Back to top
mikep



Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX

Posted: 05 January 2009, 22:37 PM    Post subject: Reply with quote

sturgessb wrote:
Is it possible to have an ISR driven by a PinChange Interrupt, if i wanted to put this code onto the 644 rather than the 128?

The docs show PCINT0 , 1 , 2, 3. Does this equate to individual pins or Ports or pins?
Good news on getting it working. Each pin change interrupt relates to a whole port. You turn on the interrupt for specific I/O pins and then inside the ISR you will need to determine which pin caused the pin change interrupt. The 644p datasheet is your friend here. The relevant registers are:
PCICR - Pin Change Interrupt Control Register
PCMSKx – Pin Change Mask Register x (where x is 0, 1, 2, or 3

The ISR needs to examine the state of the pins (Register.Pinx) to determine what changed. XOR can be your friend here if you save the previous state.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 22:57 PM    Post subject: Reply with quote

As Mike pointed out, the pin change interrupts are sensitive to any change, either the leading or the trailing edge of the pulse. The external interrupt can be programmed to operate the same way but it seemed simpler to configure it first for a rising edge and then to reconfigure it for a falling edge, etc.

If you have all four PWM inputs on the same port, you'll only need one ISR but you'll need code to figure out which pin or pins changed as Mike indicated. Alternately, you could choose to put each PWM input on a different port. The would increase the amount of setup work required and would require four separate ISRs but it would obviate the need to try to determine which pin changed. The latter strategy would not work on a ZX-328n because it only supports three ports: B, C and D.

strugessb wrote:
Also, on the 644 and 328, are any of the interrupts needed for I2C?
Interrupts are not used to implement I2C master mode but an interrupt is required to implement I2C slave mode.

One further note: you should do some research to determine the waveform generated for the four PWM channels by the controller. Some web pages that I've looked at show a waveform where the trailing edge of the channel 1 pulse is coincident with the leading edge of the channel 2 pulse and so on down the line. If this is indeed the case (or if the leading edge of one channel follows very closely the trailing edge of the preceding channel) you'll need to code the ISR carefully to allow for that timing.
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 22:59 PM    Post subject: Reply with quote

Thanks Mike

So...
Code:

   Register.SREG = Bx1000_0000
   Register.PCICR = Bx0000_0001
   Register.PCMSK0 = Bx0000_0001


Would enable which pin on the zx-24? pin 12?

Code:
ISR PCINT0()
   tempint = tempint + 1
END ISR


doesnt seem to work, am i missing something?
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 666

Posted: 05 January 2009, 23:24 PM    Post subject: Reply with quote

dkinzer wrote:
Some web pages that I've looked at show a waveform where the trailing edge of the channel 1 pulse is coincident with the leading edge of the channel 2 pulse and so on down the line.


This round-robin method of doing the PWM should be relatively easy to handle. If the PC interrupt is set up to trigger on both edges, then you have to do the XOR of the port with the last port state, then go sequentially through each of the "true" bits. If the state change on a particular pin was a rising edge, then grab the timer reading and save it.

If the edge was a falling edge, then grab the timer reading and subtract it from the saved value. Then store that resulting value somewhere for future processing. Probably a flag would need to be set as well.

One question would be about when to reset the timer to zero. It would be nice to be able to reset the timer rather than let it wrap around as it overflows. However it might take too much effort (and another timer?) to do.

This still does not answer the question of how accurate (how often the same measurement results in the same answer) and how precise (how different measured variables need to be to get the reading of the two to be different) this is going to be.

An interrupt that takes a long time to process will reduce the overall precision. An interrupt that takes a variable amount of time to process will reduce accuracy. Other interrupts occuring at the sime time will also reduce accuracy.

The only way to find out how it will actually work is to try it and see. I think you are well along the process to being able to try it out!

Oh, to answer the question of whether I2C requires interrupts. The answer is YES. The hardware I2C functions do use interrupts. If you do your own software I2C then you will not need interrupts. If you were concerned about the latency in servicing a Pin Change interrupt, then it is probably better to use the hardware I2C rather than use a new task for the software I2C. The added overhead to OS to serivce the extra task is likely to be worse than the I2C interrupt.

-Tony
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 23:27 PM    Post subject: Reply with quote

spamiam, I have tried it, it works well, accuracy and resolution is more than enough, with a 16bit timer anyway.

Just cant get it working on PinChange Interrupts, can't get the ISR to fire.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 23:34 PM    Post subject: Reply with quote

sturgessb wrote:
Just cant get it working on PinChange Interrupts, can't get the ISR to fire.
Which pins are you using? Can you show the code that you're trying.
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 23:39 PM    Post subject: Reply with quote

I have a pulse line going into pin 12. on the zx-24.


code is.....


Code:

Public tempint as INTEGER

Sub Main()

Register.SREG = Bx1000_0000
Register.PCICR = Bx0000_0001
Register.PCMSK0 = Bx0000_0001

If Semaphore(Register.Timer1Busy) Then
   Register.TCCR1A = 0
   Register.TCCR1B = &H02
   Register.TCCR1C = 0
End If

End Sub

ISR PCINT0()
  tempint = tempint + 1
END ISR
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 23:46 PM    Post subject: Reply with quote

sturgessb wrote:
Code:

   Register.SREG = Bx1000_0000
   Register.PCICR = Bx0000_0001
   Register.PCMSK0 = Bx0000_0001
Would enable which pin on the zx-24? pin 12?

PCINT0 corresponds to PortA (PCINT1->PortB, etc.) so the code above would enable a pin change interrupt on pin 20 of a 24-pin ZX. If you want to use pin 12 (PortC) then you need to use PCINT2.

Generally speaking, you shouldn't manipulate Register.SREG directly as you've shown. The global interrupt flag is enabled by default. If you should need to turn it off and on (which, for this purpose, you don't), use DisableInt()/EnableInt().
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 23:50 PM    Post subject: Reply with quote

sturgessb wrote:
I have a pulse line going into pin 12. on the zx-24.

You need to use PCINT2:
Code:

Public tempint as INTEGER

Sub Main()
  If Semaphore(Register.Timer1Busy) Then
    Register.TCCR1A = 0
    Register.TCCR1B = &H02
    Register.TCCR1C = 0
  End If
  Register.PCIFR = &Hff
  Register.PCMSK0 = Bx0000_0001
  Register.PCICR = Bx0000_0100  ' PCINT2, PortC
End Sub

ISR PCINT2()
  tempint = tempint + 1
END ISR


Last edited by dkinzer on 05 January 2009, 23:51 PM; edited 1 time in total
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 23:51 PM    Post subject: Reply with quote

ah yes, thanks. I was incorrectly assuming the PC numbers on the schematic referred to the PCINT numbers.

now onto the port state comparison... Im so out of my depth here!


Last edited by sturgessb on 05 January 2009, 23:57 PM; edited 1 time in total
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 05 January 2009, 23:57 PM    Post subject: Reply with quote

hmmm for some reason thats not working. When i used my orignal Port A code and changed to pin 20, it worked. But switched to exactly your code with Port C and PCINT2 /pin 12 and nothing. Weird.

I could just use port a but was hoping to keep that free for adc use. (Fixed)


Last edited by sturgessb on 06 January 2009, 0:07 AM; edited 3 times in total
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 05 January 2009, 23:57 PM    Post subject: Reply with quote

sturgessb wrote:
Im so out of my depth here!
Otherwise known as an extraordinary opportunity to learn.
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 06 January 2009, 0:03 AM    Post subject: Reply with quote

ah figured it, needed to be Register.PCMSK2
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZX-1281 Time synchro. with the server - Timezone/DST with your computer
Goto page Previous  1, 2, 3, 4  Next
Page 3 of 4

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group