Debounce-funktion färdigt i STM32?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Debounce-funktion färdigt i STM32?

Inlägg av Al_Bundy »

Såg denna goda film på Youtube där han visar hur man löser Debounce-problemet i STM32.


Det är en bra spellista. Jag har redan gjort Digital-Out och fått en LED att blinka :)

Min fråga till er:
Finns det något sätt så man kan lösa detta Debounce-problem igenom att t.ex. sätta något speciell register hög/låg? Eller måste man göra som han gör?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Debounce-funktion färdigt i STM32?

Inlägg av TomasL »

Debounce löser man med filter externa med kondingar och motstånd eller digitala i programkod eller bägge varianter i kombination eller så använder man för ändamålet specifikt designade IC-kretsar. (vilket jag ofta gör, ger en massa andra bra fördelar också).
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Debounce-funktion färdigt i STM32?

Inlägg av Icecap »

Det finns många sätt att göra det på, den han beskriver känner jag till men har förkastat sedan länge - eller rättare: använder en enklare och snabbare version.

Jag brukar göra så att jag har en timer-interrupt som kollar t-bord/knapp-porten från 20gg/sek till 30gg/sek. Den förra avläsning kollas mot den senaste avläsning och stämmer de överens är det en valid knapptryckning. Sedan får man maska ut så att man får rätt nivå osv.

Att jag sedan använder n-key-rollover är en annan sak som inte har med debounce att göra.

Detta sätt har fungerat otroligt stabilt i industriellt miljö under många år så jag har det fint med det - och det rör sig i grunden om att utföra ett par logiska bit-operationer för att debounce - timern har jag nämligen "alltid" aktiverat i mina projekt.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Debounce-funktion färdigt i STM32?

Inlägg av Al_Bundy »

Jag har löst det på detta sätt. Ge gärna en återkoppling om man kan göra det på ett sätt som kräver mindre kod. Icecap: Du sade något om timer-interupts. Hur fungerar det?

Ledsen att jag inte har svarat tidigare. Har varit upptagen.

Kod: Markera allt

// Flag state
	uint8_t state = 0;

	// Loop
	while (1) {
		/*
		 * Check if we press the button or not
		 */
		if (GPIOA->IDR & GPIO_IDR_IDR_6) {
			if (state == 1) {
				state = 2;
			}else if(state == 3){
				state = 0;
			}
		} else {
			if (state == 0) {
				// ON GPIOA pin 5
				GPIOA->BSRRH |= GPIO_BSRR_BS_5;
				state = 1;
			}

			if (state == 2) {
				// OFF GPIOA pin 5
				GPIOA->BSRRL |= GPIO_BSRR_BS_5;
				state = 3;
			}
		}
		// Delay
		for(int i = 0; i < 5000; i++);
	}
Findecanor
Inlägg: 982
Blev medlem: 2 juli 2010, 23:04:07

Re: Debounce-funktion färdigt i STM32?

Inlägg av Findecanor »

I mitt tangentbords-firmware (för AVR) så har jag ett timer-interrupt som varje millisekund räknar upp en global variabel som agerar klocka. Huvudloopen väntar först på att klockan tickar upp ett steg: sen scannar och debounce:ar den varje kolumn i taget.
Genom att ha det som tar mest tid i huvudloopen (och inte i ett interrupt) så dels blockerar man inte andra interrupt, och dels så är det inte katastrof om det råkar ta mer än ett klock-steg.

Man bör vänta ett par mikrosekunder efter att man börjat strobe:a en kolumn innan man börjar läsa raderna, och jag använder den tiden för debouncing av föregående kolumn.

Raderna för varje kolumn läses in i en int: med en bit per tangentrad. En etta för "tryckt" och en nolla för "ej tryckt".
För varje kolumn finns en cirkulär buffer där de skrivs ner.
Debouncing går ut på loopa igenom de n senaste värdena i buffern och AND:a ihop dem resp. OR:a ihop dem
beroende på om man vill reagera på stigande eller fallande kant eller båda.

Min digital joystick-adapter använder samma mainloop och funkar på samma sätt, bara utan strobing.

Men om man bara har ett par knappar så kan man nog använda ett lågpassfilter, ja.
Sen ska det finnas en enkel krets för brytare med tre poler, har jag för mig.
Senast redigerad av Findecanor 12 maj 2019, 20:06:49, redigerad totalt 2 gånger.
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Debounce-funktion färdigt i STM32?

Inlägg av Icecap »

Al: om du inte redan använder interrupts är det på mycket hög tid att du börjar.

Men i essens är det att starta en timer och ställa in den så att den - med känd intervall - ger en hårdvaruinterrupt. Detta trigger en körning av den ISR-rutin man skriver för den timer-interrupt och den tar hand om att kolla knappar osv.

Sedan får man ju komma på hur den ISR (Interrupt Service Routine) ska förmedla knapptryckningar till main-loop men det är en annan sak. Jag gör lite olika beroende av vad som behövs i det aktuella projektet men ibland gör jag en buffer på t.ex. 16 steg där jag lägger in knapptryckningarna som sedan avläsas i main-loop.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Debounce-funktion färdigt i STM32?

Inlägg av Al_Bundy »

Icecap skrev:Al: om du inte redan använder interrupts är det på mycket hög tid att du börjar.

Men i essens är det att starta en timer och ställa in den så att den - med känd intervall - ger en hårdvaruinterrupt. Detta trigger en körning av den ISR-rutin man skriver för den timer-interrupt och den tar hand om att kolla knappar osv.

Sedan får man ju komma på hur den ISR (Interrupt Service Routine) ska förmedla knapptryckningar till main-loop men det är en annan sak. Jag gör lite olika beroende av vad som behövs i det aktuella projektet men ibland gör jag en buffer på t.ex. 16 steg där jag lägger in knapptryckningarna som sedan avläsas i main-loop.
Jag har tagit beslutet att jag ska lära mig input,output,adc,pwm,uart,spi,i2c,timers och interupt igenom att sätta olika register på en stm32. Jag brukar göra det på söndagar. Men det går frammåt. :) Så jag ska använda interupts.

Så om du skulle få visa lite C-kod hur en interupt fungerar igenom att sätta register. Hur skulle den se ut då? Mindre kod än vad jag skrev?
Findecanor skrev:I mitt tangentbords-firmware (för AVR) så har jag ett timer-interrupt som varje millisekund räknar upp en global variabel som agerar klocka. Huvudloopen väntar först på att klockan tickar upp ett steg: sen scannar och debounce:ar den varje kolumn i taget.
Genom att ha det som tar mest tid i huvudloopen (och inte i ett interrupt) så dels blockerar man inte andra interrupt, och dels så är det inte katastrof om det råkar ta mer än ett klock-steg.

Man bör vänta ett par mikrosekunder efter att man börjat strobe:a en kolumn innan man börjar läsa raderna, och jag använder den tiden för debouncing av föregående kolumn.

Raderna för varje kolumn läses in i en int: med en bit per tangentrad. En etta för "tryckt" och en nolla för "ej tryckt".
För varje kolumn finns en cirkulär buffer där de skrivs ner.
Debouncing går ut på loopa igenom de n senaste värdena i buffern och AND:a ihop dem resp. OR:a ihop dem
beroende på om man vill reagera på stigande eller fallande kant eller båda.

Min digital joystick-adapter använder samma mainloop och funkar på samma sätt, bara utan strobing.

Men om man bara har ett par knappar så kan man nog använda ett lågpassfilter, ja.
Sen ska det finnas en enkel krets för brytare med tre poler, har jag för mig.
Har du kod som du kan visa? :) Inte för att jag ska förstå direkt eller kommer förstå. Jag är mest bara ute efter hur jobbet ser ut.
Skriv svar