c18 Bit Verschiebung

OP #2197314
Lesenswert?

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?
#2197326
Lesenswert?

> 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.
OP #2199218
Lesenswert?

...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
}
#2199225
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren