I need to determine a pin change

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

I have an autoguider that is used for correcting my telescope errors while taking a photograph. It has four active low pins that signal when a correction is required.

Now I have thought of using Pin Change interrupts but the problem I am struggling with remains. Here is the scene.

The guider is connected to PortB pins 5,4,1 and 0.
When no action is required "Anding" a pin mask with PortB will tell me when the pin goes low. So far so good. Now when the guider has detected that enough correction has occurred the pin goes high. I need to detect this change and react to it.

I react by changing the pulse rate on either Timer0 or Timer1 depending on which axis is being corrected.

I am using a Tiny2313 and Assembler.

My thoughts are that I save the condition of the port at the beginning of each scan and then compare the bit to see if it has changed. Looking through the AVR command list I can see commands that compare Registers but not individual bits in that Register.

The simple solution is if the pin is high set the OCRx register for the normal speed. However I am not sure what the effect on the accuracy of the pulse stream would be if the value was being written to on a continuous basis.

If I use Pin Change Interrupts I still have to determine which pin caused the interrupt and whether it had changed from High-to-Low or from Low-to-High.
So I do not know which is best; a tight loop polling the pins or an interrupt. The processor is not doing anything else while the guiding routine is running so I do not have worry about load sharing.

Thank you

Bob Parry

Bob Parry

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

Quote:
Looking through the AVR command list I can see commands that compare Registers but not individual bits in that Register.

SBIC would work. It will skip next one instruction until condition is true.
sbic   pinb,2   ;if bit is high
rjmp   needed change   ;do this 
sbic   pinb,3    ;else if this bit is high
rjmp   other stuff   ;do this 

Edited for stupid mistake :lol:

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

Quote:
Looking through the AVR command list I can see commands that compare Registers but not individual bits in that Register.

If you >>really<< want to compare bits in a Register use SBRS and SBRC but my first suggestion check if input to pin is low or high.

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

Quote:

If I use Pin Change Interrupts I still have to determine which pin caused the interrupt and whether it had changed from High-to-Low or from Low-to-High.
So I do not know which is best; a tight loop polling the pins or an interrupt.

If there are clean edges on the pin(s), with no bounce as you might see from a push button or toggle switch, then you can probably get away with reacting to the pin change(s) directly. If there could be bounce then it is probably milliseconds long; then I always poll the pins at a few milliseconds interval and debounce.

Here is one of my sequences to gather a number of button states periodically, debounce, and calcualte rising & falling edges.

// ***********
// Switches -- every 10 ms.
// ***********
		// Fetch switch state every 10ms.
		button_prev = button_current;	// for calculating edges


 		scratch = key_fetch();		// strobe and process switch inputs
		button_current = signal_debounce(scratch, buttons);		//  and create edge triggers & current state

// Rising & falling edges
//
// Note:  no edges.  If needed:
//	Rising & falling edges = composite_io ^ previous_io;
//	Rising edges = (composite_io ^ previous_io) & composite_io;
//	Falling edges = (composite_io ^ previous_io) & previous_io;
//

		button_rising = (button_current ^ button_prev) & button_current;
		button_falling = (button_current ^ button_prev) & button_prev;

In your case, it gets simplified a bit if clean edges 'cause all your signals are on the same port and same pin-change bank.

// in pin-change interrupt

		button_prev = button_current;	// for calculating edges

 		button_current = PINB & 0x33;	// get the new state

// Rising & falling edges
		button_rising = (button_current ^ button_prev) & button_current;
		button_falling = (button_current ^ button_prev) & button_prev;

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.