Is there any benefit/reason to apply a setup & hold constraint to a push button input to an FPGA when the button is asserted asynchronously?
From what I understand a violation can still happen regardless as the button can be pressed within the setup and hold time of the flip-flop that it's connected to inside the FPGA.
Push buttons generate very slow changing signals compared to the system clock (0.001 .. 10Hz vs. several MHz). Applying setup/hold times is a waste of effort. Just apply a timeing ignore rule.
A propper synchronizer and maybe a debouncer circuit is needed anyway.
I agree with previous poster that push button input pin shouldn't be timed (use false_path). If you want to be very safe, you should probably:
Turn on Schmitt trigger for the input pin connected to the button.
Feed the input signal through 2 stage synchronizer (2 flops in serial)
Implement debouncer either using analog circuit on the board, or doing this digitally using a counter after the synchronizer.
Related
The Atmel SAMD21 TCC peripheral provides a STOP command, which pauses the counter. The counter can be resumed with a RETRIGGER command.
When STOP is issued, the TCC enters a fault state, in which the outputs are either tristated, or driven to states specified in a config register. Presumably this mechanism is designed to support a fixed failsafe output state.
In my case I want the output pins to freeze in the state they're in at the time of the STOP command. The only way I can see to to do this is to update the configured fault output state register every time the outputs are updated - requiring interrupt processing which kind of defeats the purpose of much of the TCC's output waveform extension architecture, as well as being a processing load I'd prefer to avoid. There are other complications too, such as accounting for the dead time mechanism, and hardware/software races.
So I've been looking at ways to achieve this that don't involve the STOP command - but I can't see any other way of stopping the counter. There's no way to gate the peripheral clock input, and disabling it in GCLK is ruled out as it also runs TCC1. (And who knows what other effects this would have.) Negating the ENABLE bit, besides being overkill, unsurprisingly also tristates the outputs. Modifying the configuration in various other ways usually requires writing to enable-protected registers, thus requiring disabling the peripheral first.
(One idea I haven't investigated that yet is to drive the counter from the event system, and control the event generation/gating instead.)
So: is there any way of pausing the peripheral in its current state, while maintaining the state of the output pins?
All that I can think of to try is the async 'COUNT' event, which sounds like it is a gate for the clock to the counter.
(page numbers from the 03/2016 manual)
31.6.4.3. Events, p.712;
Count during active state of an asynchronous event (increment or decrement, depending on counter direction). In this case, the counter will be incremented or decremented on each cycle of the prescaled clock, as long as the event is active.
31.8.9. Event Control, p.734;
EVCTRL register,
Bits 2:0 – EVACT0[2:0]: Timer/Counter Event Input 0 Action
0x5 COUNT (async) Count on active state of asynchronous event
The downside is that software events have to be synchronous.
I'm trying to figure out the best approach to my problem.
I have an AT89S52 microcontroller with 3 buttons connected to 3 separate GPIO pins so that the microcontroller can perform different functions based on those buttons.
I'm trying to write code that waits for the user to press any of the three keys. By key press, I mean where the system detects any one key is fully pressed down and then fully released.
The code I presented below might work if I added a schmitt trigger in my hardware but I don't want to redo my circuit board (again).
Without adding interrupts, is there a way I can modify the code shown with just a few lines to reliably detect a user key press?
I ask because keys experience a phenomenon called "bouncing" where as soon as someone presses a key, it actually jitters at high speed and the microcontroller will see it as key being pressed and released multiple times. I don't want that to happen if the user legitimately pressed the key only once.
;KEY1I, KEY2I and KEY3I = GPIO pins connected to the keys
;Pin value is low when key is held down
w4key:
;begin key scan
jnb KEY1I,w4keyend
jnb KEY2I,w4keyend
jnb KEY3I,w4keyend
;here, nothing is pressed so scan again
sjmp w4key
w4keyend:
;key pressed. Hope for release
jnb KEY1I,w4key
jnb KEY2I,w4key
jnb KEY3I,w4key
;here, key is released so return.
ret
mainline:
;do something
acall w4key
;do another thing
...
You can use a timer (AT89S52 has several timers, you can use one of them if there are not otherwise used in your project) and a synchronous state machine. The state machine has 4 states for every key and definite transitions. I found this link that explains the concept quite thorough. Although the provided example code in this link is in C, you can easily "translate" it to your assembly code. If you need help with this, just leave a comment.
https://www.eeweb.com/profile/tommyg/articles/debouncing-push-buttons-using-a-state-machine-approach
I need to write a code that contains an interval loop but contains a push button interrupt that displays RTC values when activated. I have found a way to individually do each task i.e change pushbutton state, loop in intervals, display RTC value but I cannot seem to combine them and create a working. If someone can provide links or an explanation on how to accomplish this I would be so grateful.
If you do not use delay(interval); in your main loop, you can run as many tasks in parallel as you want. Understand the BlinkWithoutDelay sample, and try to extend it to two leds blinking independently. Or read a button while blinking.
And push button and interrupt does not go together well, BTW.
You even might add a small delay(2); to slow down polling the button pin.
This is usually fine for the other parallel running tasks and implements a very simple debounce mechanism.
I have a nearly finished prototype using an arduino uno. Basically its purpose is to switch a 2000w main AC heating load using a heavy relay on and off. The input of the relay is comming from the mains but is connected to the power company using a special meter that is only switched on between 23-07 hrs at night. The power for the arduino is continous by the way, so this stays on.
The whole thing is nicely build into a box with on the front an small lcd display and a button, connected using 20cm wires to the arduino board (I am using a protoshield).
The button is pulled up with a 10k resistor which is pulled to ground when pressed. I have put a 0.47 uF cap on the input pin = pin 2 to also debounce the circuit a bit. In software I am using an interupt on the falling edge to detect button presses. The whole thing works nicely... Except...:
When the load ac input is switched on by the power company this is sometimes recognized as a button press! I am thinking that the suddon power spike induces a voltage in the 20 cm button wires which is recognized as a falling edge. How can I avoid this?
I am equiped with multimeter, oscilloscope, soldering... so I can try out any suggestions in detail.
I am having a similar problem building a fuel injection flow bench. The button press starts a simulated engine run sequence that powers a relay. That relay then powers up to 6 injectors. What happens is as soon as I press the button the injectors closing induces a current and trips the whole system to start over again. The solution I've found that worked was using a battery to supply voltage to the injectors as opposed to the power supply itself. This isolates the arduino supply from the injector supply via my relay. The problem is of course now I need to keep the battery charged. I'm looking for a more elegant solution.
I tried to solve this issue in hardware, but unfortunately failed.
These are the options I tried, but that did NOT work
used a shielded cable for the button
implemented an XY denoise capacitor network on the AC of the load (input)
like this one : http://www.conrad.be/ce/nl/product/450571/K042201052-Ontstoringscondensator-XY-Radiaal-bedraad-01-F-250-VAC-1-stuks?ref=searchDetail
In the end I implemented the following software solution:
The first time the button is pressed, it must be pressed 1 second before the button actually becomes active. This will never happen due to the AC turning on because this is a very brief spike. I programmed this into the arduino using interrupt to detect button press and then micro delay (inside the ISR) to check that after 1 seconds the button is still pressed.
After the initial 1 second button press, the button stays lively for 1 minute
I want to find time difference between two pulses using PIC16F628.
I am using a 4MHz external oscillator, MikroC compiler.
As a simple example let's assume there is a push button. When we press it, it sends a high signal to a pin. We press this button twice with some delay in between, I want to find the time difference between these two button presses.
Thank you.
As mentioned in the comments, the simplest way to do this is to use a timer/counter combo. I found this quick tutorial on how to do this specifically for PIC: http://www.mikroe.com/chapters/view/17/chapter-4-examples/#c4v5.
Have a look at 4.5 and 4.6, they give you exactly the information you'll need to get the count of timer intervals between pulses. The basic technique is to start a timer, associate an interrupt handler (Read: function) with the timer, and then increment a counter everytime the interrupt handler is called. Next time you see the pulse, read what the counter value is.
After that, all you need to know is the timebase you've set the counter to (which will be some integer subdivision of your oscillator rate, and is selectable in code usually) and you can convert # of timer intervals to time in seconds/millis/nanos.