Reading the OC1A Status

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

I am using mode 4 CTC (Clear Timer on Compare) to generate input for a stepper motor driver chip.   (A4988)

An ISR handles changing OCR1A for various speeds

The issue is that each timer compare toggles OC1A.  However I need to generate pulses.

So my idea was to look at the pin state in the ISR and take no action if it is high.  Then when it is low increment my step count and adjust speed if needed.

Of course I could write to the pin in the ISR but I would rather the hardware handle it to avoid jitter from other ISRs and atomic operations.

Quoting the datasheet

If one or both of the COM1A1:0 bits are written to one, the OC1A output
overrides the normal port functionality of the I/O pin it is connected to.

So clearly I can not write to the pin, but it seems that I should be able to read it.  However this test code only spits out +.  The o-scope says otherwise.

if (PORTB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

 Any thoughts?

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

Use PINB to read the pins.

 

--Mike

 

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

However I need to generate pulses

What about PWM mode?  Anyhow...

 

You probably just need a little logic blip; width doesn't matter much  (but you want when the blip occurs controlled accurately).

 

You could simply run the pin toggling at 2x the desired pulse freq & then get 50% duty cycle "pulses" (a square wave).

 

If you want more of a "blip", set comxxx bits to TOGGLE the pin on a match--this will give "exact" timing.  Also have the ocr match interrupt turned on...it will also fire.  Maybe you can somehow use the force output compare bit to generate a toggle (back to low)

– FOC0A: Force Output Compare A  

A FOC0A strobe will not generate any interrupt, nor will it clear the timer in CTC mode using

OCR0A as TOP.

==============

Or even better(maybe)...set up toggle mode & the also the compare IRQ....in the IRQ set the irq for a small amount...you quickly get a toggle (downward)...then set a large number for a longer delay (upward).

In other words set a long delay for the next leading edge, then a short delay for the trailing edge.  like  97, 3, 97, 3, 97, 3....

Rather than using toggle mode, you might track things &  each IRQ alternate between the set  & Clear OC0B on Compare Match.

With toggling, if you lose software sync, your wave will be upside down (giving very wide pulses instead of very narrow).

 

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. Jan 13, 2019 - 05:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

Use PINB to read the pins.

--Mike

Fixed!

// this works on a regular pin
if (PORTB & (1<< PB0)) usart0_putc('/');else usart0_putc('*');
// this is required on a pin connected to the timer.  Strange but true.
if (PINB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

 

 

 

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

To get a pulse you might consider adding some hardware like a R,C and an xor gate. This frees the AVR to just toggle on match.

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

KirkCharles wrote:

// this works on a regular pin
if (PORTB & (1<< PB0)) usart0_putc('/');else usart0_putc('*');
// this is required on a pin connected to the timer.  Strange but true.
if (PINB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

 

That's misleading.  And a bad habit.

 

Reading PORTxn >>never<< tells you what the logic state of a pin is.  It only tells you what the state of the PORTxn register bit is.  It 'works' because the output driver usually overwhelms any input signal on the pin.

 

When a pin is configured for output, the PORTBn bit sets the drive level for that pin.  It tells you nothing about the logic level at the pin.

 

To know the logic level present on a pin, you must always read PINxn.  Always.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

If you want to generate a pulse, be able to fine-tune frequency, use OC1A as output and have it mostly done in hardware, you should use a PWM mode with ICR1 as top, namely mode 8 or mode 10.

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

...never mind...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Jan 13, 2019 - 04:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

...never mind...

???? Are you retracting your comment?  Confused.

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

???? Are you retracting your comment?  Confused.

Not in the slightest.  I made an additional post (#8) in error.  My post #6 stands as is.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

I am looking at this and I must be missing the point somewhere. The A4988 data sheet implies that the chip sees a rising edge on STEP as the signal to step, and couldn't care less when the signal falls. If you are using single slope modes, toggling the pin and changing the period, does it matter if the pin was high or low at the time? Have you considered using OCR1B to create output - set when TCNT1 = 0, clear at some arbitrary value that is shorter than the minimum for OCR1A. That way you get a fixed length pulse at whatever interval is set by OCR1A. So many options.

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

Having a variable step rate seems like a good application for some DDS code.

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

joeymorin wrote:

KirkCharles wrote:

// this works on a regular pin
if (PORTB & (1<< PB0)) usart0_putc('/');else usart0_putc('*');
// this is required on a pin connected to the timer.  Strange but true.
if (PINB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

 

That's misleading.  And a bad habit.

 

Reading PORTxn >>never<< tells you what the logic state of a pin is.  It only tells you what the state of the PORTxn register bit is.  It 'works' because the output driver usually overwhelms any input signal on the pin.

 

When a pin is configured for output, the PORTBn bit sets the drive level for that pin.  It tells you nothing about the logic level at the pin.

 

To know the logic level present on a pin, you must always read PINxn.  Always.

So the way I read your comment (PORTB | (1<< PB4)) should never be done because it reads PORTB.  Still not understanding your point.  Why is such a bad thing to know the register value?

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

Reading portb is not going to give you the correct state of the pin. Ok if you want to test the state of the port register.

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

KirkCharles wrote:
So the way I read your comment (PORTB | (1<< PB4)) should never be done because it reads PORTB.  Still not understanding your point.
He's simply saying:

if (PORTB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

should be:

if (PINB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

You read PINx not PORTx to detect the external state on pins that the DDR register has set as inputs.

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

Why is reading the datasheet so unfashionable?

 

 

 

 

In the above diagram the area outlined in green is the latch that receives the value you write to a PORT and the buffer controlled by RRx is the one that reads a PORT.

 

The multiplexer outlined in red is the one that disconnects the general I/O function from a pin and allows the alternate functions to control it instead.

 

You will see the the buffer to read a PORT is before that multiplexer and so reading a PORT will not return any information about what a physical pin is doing when its not a general I/O pin.

 

The line in yellow shows the path taken by a signal when you read a PIN, controlled by the RPx signal and buffer. So you can see that the only way to see what is actually on a physical pin is to read a PIN not a PORT.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

KirkCharles wrote:
Still not understanding your point
Look at it this way.  When a pin is configured for output, its PORTxn bit sets the level to which that pin is driven by it's output buffer.  An analogy might be the accelerator pedal in a car.  Reading the state of the accelerator pedal (i.e. foot on, or foot off) tells you nothing about the speed of the vehicle.  If you want to know the speed, examine the speedometer.  The fact that most of the time with your foot off the accelerator the speed of the vehicle will be slow, and most of the time with your foot on the accelerator the speed of the vehicle will be fast, is not particularly useful.  If you doubt it, try telling the police officer 'but my foot wasn't even on the accelerator' next time you get pulled over for speeding ;-)

 

Your comments:

// this works on a regular pin
if (PORTB & (1<< PB0)) usart0_putc('/');else usart0_putc('*');
// this is required on a pin connected to the timer.  Strange but true.
if (PINB & (1<< PB1)) usart0_putc('+');else usart0_putc('-');

... especially the 'strange but true', suggest that you did not understand the difference, and that you are stabbing in the dark in your effort to understand.  This is not a disparagement.  It is meant to improve your understanding, and that of any others who come along in the future and read this thread.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Brian Fairchild wrote:

Why is reading the datasheet so unfashionable?

It was unfortunate you truncated the image, and missed showing that RPx is the read pin signal. Otherwise a faultless explanation.

 

I think it is confusing to say " Reading PORTxn >>never<< tells you what the logic state of a pin is. ". If the port is configured for output and there are no overriding factors and the port is driving into a suitable load and nothing has failed (a lot of ANDs there) then it is fair to assume the pin value is the same as the port value. Sometimes we can't see what we want to see directly, but can infer it from sound logic [if you want a bizarre example, you can't measure time. You infer elapsed time by observing two things, one which is expected to occur by definition in a certain amount of time - e.g. quartz crystal vibration - and the period you are trying to measure]. So saying 'never' is misplaced. However, in this case we have a method of reading the logic state directly so there is no need to infer it by an indirect (and in this case, incorrect) method.

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

Guys,

We have strayed a long way from the topic here.  I fear that we are at risk of a firestorm.  I doubt that we have provided a concise archive of information on the subject matter.  Lots of unrelated comments have been made. (Sadly I too have contributed.)

 

avr-mike's comment got me on the right track.  Brian Fairchild's comments in line #16 are spot on and the best explanation of the issue at hand.  Now I know how to make it work and WHY.  Thanks Brian and Mike!

 

After the mayhem of an unrelated project cools down I will post the selected solution and why it was selected over so many possible alternates.  

Thanks again to those that took the time to understand the issue, the goals and the purpose of the test code.

 

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

KirkCharles wrote:

avr-mike's comment got me on the right track.

 

Was that pun intended?  ;-)

I recall my first couple posts were misinterpreted puns....

 

--Mike

 

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

avr-mike wrote:

Was that pun intended?  ;-)

OH Yes :)

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

OH Yes :)

And I grew up in Shaler Township.  Learned to count by counting the cars on the B&O line (Now AVR) through Allison Park.

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

KirkCharles wrote:
Lots of unrelated comments have been made. (Sadly I too have contributed.)
Presumably including #21 and #22 ?? cheeky

 

The fact is that the moderation we employ here is fairly lax (a Good Thing(tm) IMHO!), a bit of wander in thread topic doesn't really do anyone any harm (until it strays to religion or politics at which point moderation will happen!)

 

Moderator

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

clawson wrote:
a bit of wander in thread topic doesn't really do anyone any harm (until it strays to religion or politics at which point moderation will happen!)

You will burn in hell for that, after being disenfranchised and deported.  and that information ain't useless.

 

I just scanned through the thread.  Probably my old eyes, but where is the unrelated information that is verbose?  Because 'Freak eyes spotted a better way of reaching the objective than racing to read the pin and taking action?

 

 

 

 

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.