Hi!
I want to use an external button on port 2. How can i use the internal Schmitt Trigger for debouncing?
I am a beginner.
Thank you!
Steffen
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi!
I want to use an external button on port 2. How can i use the internal Schmitt Trigger for debouncing?
I am a beginner.
Thank you!
Steffen
The "Schmitt Trigger" is a built-in feature of all port pins in the digital input mode. You do not need to do anything special to use that feature. Without an added external capacitor, it is inadequate to debounce a button. Instead of adding capacitor, software can debounce button inputs more effectively.
I need a hardware debounce for my following project. So i want to use the Schmitt Trigger, but i dont know how to wire and what the needed capacitor or Resistorvalue is. If i understand you answer right the Schmitt Trigger is always active, but it only works with the additional capacitor.
In my planned project i want to measure my gas consumption. The counter has an magnet switch. If the heater uses only a small amount the switch bounces a long time. More than a second. I had good results with my atmega based circuit with an external Schmitt Trigger, but then i switched to the MSP because of the energy consumption.
I hope it is readable, english is not my native language.
Thank You!
Schmitt trigger and debounce are two totally unrelated things.Steffen Müller said:I need a hardware debounce for my following project. So i want to use the Schmitt Trigger,
A Schmitt Trigger is a funcitonality built into a logical gate input. It ensures that the input signal doesn't have just a transition point but a hysteresis. So when the input voltage reaches the transition level, the input won't oscillate around this point due to noise. Once you crossed the trigger point, the signal needs to fall down significantly (the hysteresis level) before anotehr transition is 'detected'.
Debouncing, however, means that you habve a lot of state changes ina short period and want to ignore all but the first. A bouncing button will flip between GND and VCC several times when the contact is made or broken. Depending on the mechanics, this can last for milliseconds. No Schmitt Trigger can help you. The bouncing are valid low/high transitions. You can dampen teh bouncing by a series resistor followed by a capacitor between the button and the port pin. This R/C combo will do a low-pass filtering of the incoming signal.It will turn the number of transitions into a noisy falling signal when the button is pressed. And here the Schmitt Trigger may help to ignore the remaining noise, so the time constant can be rather short.
Alternatively you can do a software debounce. On the first edge interrupt, you deactivate the port interrupt, start a tiemr for your 'debounce' time and when the timer expired, you check the current switch state on the input (maybe it was just a 'spike') and reactivate the port interrupt. Any additional bounces durign the timer delay are ignored then. I'v euse dboth methods in teh past.
The advantage of the software debounce is that you can adjus tthe debounce time easily in code, while you had to change the resistor/capacitor to change the tiem constant. Also, the quality of the signal source may sometimes not allow for an external hardware debounce (the series resistor increases susceptibility to noise or crosstalk on high-impedance sources as found on low-power systems. Also, with an R/C combo, you need an external pullup on the switch while with software debounce, you can use the internal pullup of the MSP (if available). This saves PCB space and cost.
Jens-Michael Gross said:Schmitt trigger and debounce are two totally unrelated things.
Schmitt trigger becomes very related to R/C debouncer in case of noisy power supply rail. It mostly helps R/C debouncer to work properly. TI uses 47k/100nF combo for Launchpad button.
I do not understand why you need hardware debounce and cannot use software debounce. Also, I have never seen any kind of switch that will bounce for anywhere close to a second. Thus I do not know how to help you.
Yes, when used as digital input, the MSP430G2553 port pins are always Schmitt Triggers. The hysteresis is between 0.3 and 1.0 V. There are also built-in pullup/down resistors that can be enabled/disabled in software. The resistance is about 35 kOhm. The parasitic input capacitance is about 5 pF.
Yes, after a hardware debounce, a schmitt trigger can come handy for suppressing noise (as I wrote in my other text) but by itself, a Schmitt trigger has nothing to do with debouncing. Even less it it a debounce hardware on its own.Ilmars said:Schmitt trigger becomes very related to R/C debouncer in case of noisy power supply rail.
For my actual project i dont need hardware debounce, because i use an ordinary pushbutton. But for my following one it is important. But first we tried the software debouncing as you told me.
Here is the code, and we do not understand why the mp marker jumps to 2 on startup. If we set mp to zero at start nothing happens and the program stucks in the switch section. I hope you can understand what we have done. It is a four digit seven segment display we are using.
#include <msp430x20x3.h>
#define SWITCH_IN P2IN
#define SWITCH_OUT P2OUT
#define SWITCH_REN P2REN
#define SWITCH_0 BIT5 //P 2.4
void main_init(void);
// Timekeeping variables
unsigned char hh = 00, mm = 00, ss = 0, am = 0, mp = 0, a = 0, b = 0 , c = 0, d = 0; // AM = aktuelle Minute MP = menü punkt
int bd = 0;
static unsigned int ticks = 0;
volatile unsigned char switch0_state = 0;
volatile unsigned char time_set = 1;
const char show[10]={ 20 , 190 , 49 , 50 , 154 , 82 , 80 , 182 , 16 , 18 }; //Von 0-9 die Pinouts fürs Display in Hex.
int i=1;
inline void showtime(void) {
if (i==1){
P1OUT = 0xFF;
P2OUT = 0x00;
P1OUT = a;
P2OUT = 0x01;
}
if (i==2){
P1OUT = 0xFF;
P2OUT = 0x00;
P2OUT = 0x02;
P1OUT = b;
}
if (i==3) {
P1OUT = 0xFF;
P2OUT = 0x00;
P2OUT = 0x04;
P1OUT = c;
}
if (i==4)
{
P1OUT = 0xFF;
P2OUT = 0x00;
P2OUT = 0x08;
P1OUT = d;
}
i++;
if (i==5){
i=1;
}
}
char calculate (void)
{
a = show[mm / 10];
b = show[mm % 10];
c = show[ss / 10];
d = show[ss % 10];
// a = show[hh / 10];
// b = show[hh % 10];
// c = show[mm / 10];
// d = show[mm % 10];
}
void main(void)
{
// unsigned char i;
main_init();
while(1) {
switch (mp) {
case 0:P1OUT = 0xFF;break;
case 1:calculate ();showtime();break;
case 2:a=show[1];b=show[1];c=show[1];d=show[1];showtime();break;
case 3:a=show[1];b=show[3];c=show[3];d=show[7];showtime();break;
case 4:mp=1;break;
default: break;
}
}
}
void main_init(void)
{
BCSCTL1 = CALBC1_1MHZ; // Running at 1 MHz
DCOCTL = CALDCO_1MHZ;
// Stop the watchdog timer
WDTCTL = WDTPW + WDTHOLD;
// // make it a pullup resistor
SWITCH_OUT |= SWITCH_0;
// // enable resistor
SWITCH_REN |= SWITCH_0;
// Set load capacitance for 32.768kHz crystal
BCSCTL3 |= XCAP1 + XCAP0;
// Enable output for ACLK on P1.0 pin
//P1SEL |= BIT0;
// Setup watchdog timer as an interval timer with one second interrupts
WDTCTL = WDTPW + WDTTMSEL + WDTCNTCL + WDTSSEL + WDTIS1 + WDTIS0;
// Enable the watchdog timer interrupt
IE1 |= WDTIE;
P1DIR |= 0xFF;
P2DIR |= 0x0F;
P1OUT &= ~0xFF;
P2OUT &= ~0x0F;
P2IE = BIT5; // P1.4 interrupt enabled
P2IFG &= ~BIT5; // P1.4 IFG cleared
//make it a pullup resistor
P2OUT |= ~BIT5;
// enable resistor
P2REN |= BIT5;
__enable_interrupt(); // enable all interrupts
}
// Interrupt fired 32768/64 = 512 times a second
#pragma vector=WDT_VECTOR
__interrupt void wdt_interrupt(void)
{
if (bd>0){
bd--;
if (bd==1){
mp++;
}
}
if (ticks > 511)
{
if (mp==1){
am++;
if (am == 5)
{
mp=0;
am=0;
P1OUT = 0xFF;
_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt
}
}
// Implement real time clock
ss++;
// calculate ();
if (ss > 59) {
ss = 0;
mm ++;
if (mm > 59) {
mm = 0;
hh++;
if (hh > 23) hh = 0;
}
}
ticks = 0;
}
ticks++;
}
// Port 1 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
_BIC_SR(LPM3_EXIT);// wake up from low power mode
P2IFG &= ~BIT5;// P1.4 IFG cleared
am=0;
bd=100;
}
Thank You!
To debounce, you need to disable the detection of the input for a short period of time. I did not see you do that in your code at all. Also, your code seems to have a lot of mistakes. Is the switch connected to P2.4 or P2.5? Setting P2OUT=0 will pull-down that pin.
Thank you, i hope its not to annoying. I am an absolute beginner to the MSP 430 and to Microcontrollers too. We thought that we have to disable the interrupt and not the button.
It is not easy for us. What are the mistakes we made? We are working with thinking, reading , try and error. And sometimes we have "Yay!" Moments, and sometimes it feels more like "Argh!".
I will try that disabling the Buttonpin.
Check this document: http://www.eng.utah.edu/~cs5780/debouncing.pdf. Figure 2. on page 12 or Figure3 on page 15 if you want to implement a simple RC debouncer.
Best regards,
István Cserny
Well, clearing the interrupt bit isn't wrong. If you don't, you'll enter the ISR for the same port event over and over again. But it should be done before re-enabling the interrupt (by PxIE bit)Steffen Müller said:We thought that we have to disable the interrupt and not the button.
Basically, IFG bits flag an event. They are set when an evern appears, whether interrupts are enabled or not.
The corresponding IE bit 'gates' the IFG bit. If both bits are set (and the GIE bit) then the interrupt is executed. Clearign the IE bit prevents future itnerrupts to happen, but the IFG bit is set anyway when the event happens. Also, in most cases, the IFg bit is not reset automatically (exceptions are the CCR0.CCIE bits, the ADC10IFG bit). Some are reset with the appropriate action (e.g. writing TXBUF for TXIFG bit or readign RXBUF for RXIFG bit) or are cleared by an event (e.g. the USCI I2C stop/nack IFG bits when a start is detected). All otehrs must be cleared ('rearmed') manually inside the ISR or are cleared when reading the modules IV register, which reports the highest pending interrupt of this module and at the same time clears the IFG bit of this interrupt).
Not disable the pin. Disable the interrupt (clear the IE bit) instead of just clearing the interrupt event (the IFG bit)Steffen Müller said:I will try that disabling the Buttonpin.
**Attention** This is a public forum