c18 Bit Verschiebung

OP #2197314
Ich baue mir gerade ein kleines Menu (ausgabe über LCD).
Steuerung über 4 tasten an PortB via Interrupt.
die 1. Taste ist dabei immer die "weiter" taste zum nächsten menupunkt.

da ich genau 8 menupunkte habe, dachte ich mir, dies sehr einfach per 
BIT-Rotation zu bewerkstelligen. KLappt aber leider nicht wie geplant^^

Mal der abgespeckte Code wie ich es handhabe:
1
unsigned char MenuFlag = 1;
2
...
3
...
4
... PORTB Interrupt Routine (funzt auch)
5
if(Taste1)   
6
  {
7
  Clear_LCD();
8
  MenuFlag <<=1;
9
  }
10
... ende Interrupt routine ...

also ich schreibe das menu anfänglich als 0b00000001 ...
die Interrupt sollte dann das bit 1 nach links verschieben
aber er schiebt um 2 ... woran kann das liegen? oder fehlt eine 
definition, da er eine rotation ausführt (im ASM kann man ja ums 
carry-flag routieren lassen)

weiß jemand rat?
> aber er schiebt um 2 ... woran kann das liegen?

Ich denke mal es liegt daran, dass dein Taster prellt.

Es gibt keinen Grund Taster über einen Interrupt anzuhängen (ausser wenn 
der INterrupt den µC aus dem Tiefschlaf holen muss).
Ganz normales Pollen reicht völlig aus. In Kombination mit einem Timer 
gibt das eine wunderbare Entprellung und Tastenerkennung:

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29


> oder fehlt eine
> definition, da er eine rotation ausführt (im ASM kann man ja ums
> carry-flag routieren lassen)

In C kann man nicht einfach Bit rotieren.

Machs nicht so kompliziert. Zähl eine Variable hoch und wenn 8 erreicht 
ist, dann setzt du sie zurück auf 0. Das ist einfach, simpel und doch 
effektiv.
Gast
Hallo,

das Change Notification Modul loest bei jeder Aenderung einen Interrupt 
aus, also bei steigender und fallender Flanke. Das musst du in deinem 
Sourcecode abfangen!

Gruss
Stefan
OP
...genau, dieser umstand ist mir bewusst. deswegen hab ich ja in die 
Interrupt-routine jeweils eine port-zustandsabfrage eingebaut mittels
1
if(PORTBbits.RB7) {... tu das ...}

normalerweise müsste die anweisung der if-schleife nur ausgeführt 
werden, wenn RB7 HIGH ist (layout-bedingt bei mir = Taste gedrückt) ,, 
wenn ich taste loslasse erfolgt zwar ein weiterer Interrupt, aber 
softwaremäßig dürfte er nichts ausführen, bis auf flags löschen..
1
#define Taste1      PORTBbits.RB7
2

3

4

5
#pragma interruptlow MY_LOW_HANDLER
6
void MY_LOW_HANDLER(void)
7
{
8
if(INTCONbits.RBIF)
9
  {
10
  INTCONbits.RBIE = 0;                
11
  INTCONbits.RBIF = 0;                
12
  if(Taste1)   
13
    {
14
    Clear_LCD();
15
    MenuFlag += 1;
16
    //MenuFlag <<=1;
17
    }
18
  INTCONbits.RBIE = 1;
19
}
sieh's doch ein: beim drücken, wird ein interrupt ausgelösst und korrekt 
abgearbeitet (um 1 shiften). da der taster prellt, wird ein zweiter 
interrupt ausgelösst, der nochmals um 1 shiftet. dies geschieht so 
schnell, dass du glaubst, es wäre nur ein interrupt gewesen, der falsch 
ausgeführt würde (um 2 shiften)...

ps: "INTCONbits.RBIF = 0;" erst ganz an den schluss der interruptroutine 
schreiben.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.