Input Capture control

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been struggling with this problem for a while and I'm just not getting it.

ATmega328P @ 16MHz, 5V

 

I'm receiving a pulse on the ICP1 line and I want to have the ability to turn the Input Capture unit on and off.

 

In my main method I have:


	TCCR1B  |= (1 << ICES1);
	DDRB |= (1 << PB0);
	PORTB |= (1 << PB0);

 

then in my Run method I have:

	// Set port to input
	DDRB &= (0 << PB0);

	// Configure no prescale
	TCCR1B  |= (1 << CS10);

	// Enable Input Capture Interrupt
	TIMSK1 |= (1 << ICIE1);

then in my Stop method I have;

	// Enable Input Capture Interrupt
	TIMSK1 &= (0 << ICIE1);
        // Stop clock
	TCCR1B  &= (0 << CS10);
        // Set port to output
	DDRB |= (1 << PB0);

Any help appreciated!

 

This topic has a solution.

Happy Trails,

Mike

JaxCoder.com

Last Edited: Sat. Mar 16, 2019 - 06:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DDRB &= (0 << PB0);

 

Doesn't this just clear the register? Is that what you really want to do?

Mike

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:

then in my Run method I have:

// Set port to input
DDRB &= (0 << PB0);

then in my Stop method I have;

// Enable Input Capture Interrupt
TIMSK1 &= (0 << ICIE1);
// Stop clock
TCCR1B  &= (0 << CS10);

 

All of the &= above will set the entire register

to zero, not just the bit you want.

 

The way to turn off a single bit is like this:

DDRB &= ~(1 << PB0);

Since PB0 is 0, the mask will become 11111110.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is with all this |= stuff?  Show a complete test program.  >>Set<< the configuration registers.

 

theusch wrote:
As I am fond of saying:

https://www.avrfreaks.net/commen...

 

For some reason, many posters on this site have a love affair with |=. There must be a sale on "|" in full-reel quantities.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Mar 15, 2019 - 01:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you can't believe I've made this rookie mistake.

 

I used to always use _BV() but just recently switched to the (x << y) way of doing it and saw the val &= (0 << n) and just ass-u-me-d.  (blushing profusely)

 

But the question still remains, how to I control the ICP1 port?

 

Also I'm not getting response notifications and I have checked the box below.  Not working?

Happy Trails,

Mike

JaxCoder.com

Last Edited: Fri. Mar 15, 2019 - 12:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:
But the question still remains, how to I control the ICP1 port?
theusch wrote:
What is with all this |= stuff? Show a complete test program. >>Set<< the configuration registers.

What do you mean by "control the port"?  If you mean disabling the interrupt, you haven't shown the corrected code, nor a complete program. 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please explain what you are trying to do. The input

capture feature just causes whatever value is in TCNT

to be copied into ICR when an event occurs. An event

is either the analog comparator flipping state (on some

chips), or an external pin change.

 

--Mike

 

EDIT: ICR, not ICP

 

Last Edited: Fri. Mar 15, 2019 - 03:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

What is with all this |= stuff?  Show a complete test program.  >>Set<< the configuration registers.

 

theusch wrote:
As I am fond of saying:

https://www.avrfreaks.net/commen...

 

For some reason, many posters on this site have a love affair with |=. There must be a sale on "|" in full-reel quantities.

 

There seems to be a similar love affair with PB, as in PB0.

The children are really ugly.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:
I used to always use _BV() but just recently switched to the (x << y) way of doing it
But it's the same whichever of those us use. If I want to clear bit 5 in something I can say

SOMETHING &= ~(1 << 5);

or I can say

SOMETHING &= ~_BV(5);

but in both cases you need a 1 bit and then you also need the ~ that inverts it (a byte with everything but that bit set).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Think about what (0<<N) does. Go back to first principles ...

 

Into a byte which is 0b00000000, you left-shift a zero N places. So, what do you get? 0b00000000!

 

When you OR that with anything, as in "|=", 0 OR'd with anything changes nothing. E.g. X |= 0x00 = X

 

When you AND that with anything as in "&=", 0 AND'd with anything makes zero. E.g. X &= 0x00 = 0x00

 

To clear a bit, first you create a bit mask, as in (1<<N). For example, (1<<PB3) = 0b00001000

Then you complement it, ~(1<<N). For example ~(1<<PB3) = 0b11110111

Now, you AND this with the byte containing the bit to be cleared. For example PORTB |= ~(1<<PB3).

That zero in the complemented mask clears the PB3 bit in PORTB.

 

<edit> Perhaps to point out the obvious (which might not be), neither the shift (to create the mask) nor the complement take any run-time. The compiler figures it out and uses the constant equivalent. </edit>

 

Hope This Helps

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Fri. Mar 15, 2019 - 11:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:

Thank you can't believe I've made this rookie mistake.

 

I used to always use _BV() but just recently switched to the (x << y) way of doing it and saw the val &= (0 << n) and just ass-u-me-d.  (blushing profusely)

 

But the question still remains, how to I control the ICP1 port?

 

Also I'm not getting response notifications and I have checked the box below.  Not working?

 

Be careful with _BV() and even (x << y).  The macro for _BV() will fail if the supplied parameter is greater than 14. This is because with AVR-GCC, the default is an INT (signed 16 bit value).

 

So, if you do this:  REGISTER |= _BV(15)  it will fail because the macro tries to do (1 << 15) where 1 is a signed int.  You need to either edit the macro (in sfr_defs.h) and change the 1 to 1UL or else use (1UL << x).

 

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First let me say that the

TIMSK1 &= (0 << ICIE1);

I used above is only used in that one area.  Every other place I do that I use

TIMSK1 &= ~(1 << ICIE1);

so I'm not sure why I did it there except pure frustration.

 

Second I use |= method because I feel that

TIMSK1 |= (1 << ICIE2);

is a lot more meaningful and informative than

TIMSK1 = 0x20;

that is my and appears many others opinion.

 

Third I don't list the entire program because it is 4K worth of code and this is the only part that is not working.  I thought I post enough to give a general idea of what I was doing.

My syntax may have been bad but my question was more in line of is my logic correct.

 

Forth;  what I'm trying to do is enable/disable the input capture port and associated interrupt handler.   So I will give it one more try.

 

My initialization code


	// Set internal pullup resistor for Timer1 ICP1
	DDRB &= ~(1 << PB0);
        TCCR1B |= (1 << ICES1);
	PORTB |= (1 << PB0);

 

To enable

	// Configure for rising edge detect and no prescale
	TCCR1B  |= (1 << CS10);
	// Enable Input Capture Interrupt
	TIMSK1 |= (1 << ICIE1);

To disable

	TCCR1B  &= ~(1 << CS10));
	TIMSK1 &= ~(1 << ICIE1);

Obviously the logic is not correct because it does not work. 

 

Any help appreciated

Happy Trails,

Mike

JaxCoder.com

Last Edited: Sat. Mar 16, 2019 - 03:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:
that is my and appears many others opinion.

Bull.  Now, you still haven't given us context.  We don't know what else may be going on.  I gave you links above, and can give many more, where gratuitous use of |= has caused problems.

 

But let's put all that aside, and let me re-read the thread ...

mike32217 wrote:
Third I don't list the entire program because it is 4K worth of code and this is the only part that is not working.

Construct a complete test program that demonstrates the symptoms.  Often, that process will uncover the cause of that situation. 

mike32217 wrote:
Obviously the logic is not correct because it does not work.

I re-read the thread, and am still not clear what "does not work" means. 

 

What are "methods"?  C++/Arduino, perhaps.  Which has default setups for timers.  Which indeed makes |= important. 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:

 

Second I use |= method because I feel that

TIMSK1 |= (1 << ICIE2);

is a lot more meaningful and informative than

TIMSK1 = 0x20;

that is my and appears many others opinion.

 

Did you mean hat using the bit names is more informative than the magic numbers?  Of course.  But then don't use the |=.

 

As luck would have it I went from this thread to the "rouge bit" thread https://www.avrfreaks.net/forum/...

The cause there may very well be the gratuitous |= ...

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mike32217 wrote:

Obviously the logic is not correct because it does not work.

 

The code you're showing looks fine, so what

do you mean when you say it's not working?

 

I'd have to guess that you are toggling ICP1

and your interrupt is not getting called? Make

sure the interrupt name matches the name in

the datasheet. Is the compiler printing any

warnings? Set the warning level to "All" and

fix anything and everything it mentions.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

mike32217 wrote:

Obviously the logic is not correct because it does not work.

 

The code you're showing looks fine, so what

do you mean when you say it's not working?

 

I'd have to guess that you are toggling ICP1

and your interrupt is not getting called? Make

sure the interrupt name matches the name in

the datasheet. Is the compiler printing any

warnings? Set the warning level to "All" and

fix anything and everything it mentions.

 

--Mike

 

 

Finally, thank you that's all I wanted to know. 

Happy Trails,

Mike

JaxCoder.com