Forum: Mikrocontroller und Digitale Elektronik Denkfehler? UART + Delay danach


von Midibox (Gast)


Lesenswert?

Hallo! Ich habe ein Problem wo ich nach vielen Stunden einfach nicht 
weiter komme.

Ich bin mit einem ATMEGA32 am rumbasteln und möchte eine Box bauen 
welche Midi-Befehle nach Tastendruck sendet.

Hier ein Ausschnitt und eine kurze Erklärung dazu:
1
if ( !(PIND & (1<<PIND2)) )
2
  {
3
  
4
  
5
    PORTD |= (1<<PD7); //LED1 Einschalten
6
    PORTD &= ~( (1<<PD6) | (1<<PD5) ); //LED 2,3 Ausschalten
7
    send(192); // Sende 1. Byte "C0" (Kanalwelchsel)
8
    send(kanal); // Sende 2. Byte mit der int. var. Kanal
9
    _delay_ms(400); // Delay fkt. damit bei Tastendruck PIND2 nicht 1000 Midi-Befehle rausrattern...
10
11
  }

Im prinzip funktioniert alles. Jetzt wollte ich nur noch eine 
_delay_ms(200) Funktion beifügen um den Tastendruck ein wenig zu 
entprellen.
Also so habe ich mir das vorgestellt -> Taste wird gedrückt -> 1x "C0" 
senden -> 1x Kanal senden -> Warteschleife beginnen -> Taster wird 
losgelassen -> warteschleife hört auf.

Jetzt kommt es! Nach dem einfügen der delay fkt. sendet der auf einmal 
nicht mehr über den Uart. LED's werden geschaltet aber mehr nicht. In C 
wird doch alles "nacheinander" abgearbeitet oder sehe ich das irgendwie 
falsch?

Ich hoffe jemand kann mir bei dem Problem helfen.

Grüße

von BattMan (Gast)


Lesenswert?

Zeige bitte einmal noch Deine send()-Funktion.
Sonst sieht man evt. den Zusammenhang nicht.

von Bitflüsterer (Gast)


Lesenswert?

Schau Dir hier mal die Artikel und den Code von Peter Dannegger zur 
Tastenentprellung an. Es ist ohnehin ratsam, vor dem Posten mal zu 
schauen, ob es ähnliche Themen schon gegeben hat.

Allerdings gehst Du auch von einer falschen Annahme aus. Wenn die Taste 
losgelassen wird, dann wird die Funktion [c]delay_ms[\c] nicht 
unterbrochen. Sie wird weiter fortgesetzt, egal was Du mit der Taste in 
der Zwischenzeit machst.

Mir ist allerdings nicht klar, inwiefern Du "In C wird doch alles 
"nacheinander" abgearbeitet" als Begründung für Deine Annahme anführst. 
Vielleicht kann man Dir da noch helfen, wenn Du das mal näher erklärst.

von Midibox (Gast)


Lesenswert?

1
void send(int c)
2
{
3
  while(!(UCSRA & (1<<UDRE)))  //Ausführen so lange wie UDRE gesetzt ist
4
  {
5
  }
6
  UDR = c; // Übergabe der der Midi-Bytes
7
}

Hier noch die Sendefunktion.

@Bitflüsterer - klar die delay-fkt. wird weiter "bearbeitet" bis die 
Zeit rum ist. Ich frage mich nur warum die 2 Midi befehle nicht gesendet 
werden wenn ich die delay-fkt. beifüge
Theoretisch sollten doch erst die 2 Bytes geschickt werden und danach 
soll die delay-fkt. erst starten.

Gruß

von Midibox (Gast)


Lesenswert?

Niemand eine Idee? :/
Klar, ich könnte das entprellen auch anders lösen. Mir stellt sich aber 
nur die Frage warum das so nicht geht, wie ich es programmiert habe.

von Falk B. (falk)


Lesenswert?

@ Midibox (Gast)

>Im prinzip funktioniert alles. Jetzt wollte ich nur noch eine
>_delay_ms(200) Funktion beifügen um den Tastendruck ein wenig zu
>entprellen.

MÖÖÖÖP! Entprellung macht man GANZ anders. Lies den Artikel.

Dein Code hier ist soweit OK. Du redest aber scheinbar von einem anderen 
Code.

von Midibox (Gast)


Lesenswert?

Nope, das ist genau mein Code welchen ich benutze.
Ohne die delay-fkt. klappt alles mit der delay-fkt. nicht mehr?!
Deswegen stelle ich mir immer noch die Frage was daran falsch ist, nach 
meinem uart Sendebefehl einfach eine delay-fkt. anzuhängen.
Das dieses "Entprellen" nicht sinnvoll ist sehe ich schon ein, ich 
möchte aber für meine weitere Bastelzukunft wissen warum das so nicht 
geht :)

Gruß

von Georg G. (df2au)


Lesenswert?

Zeige das komplette Programm. Dann kann man dir helfen. Aus den 
Schnipseln geht nichts hervor.

von Midibox (Gast)


Lesenswert?

1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
void init_USART(void)
6
{
7
  UCSRB |= (1<<TXEN);          
8
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    
9
  UBRRH = 0;              //High=0
10
  UBRRL = 15;              //Low=15  bei 8MHz clock und 31250 Baud
11
}
12
13
void send(int c)
14
{
15
  while(!(UCSRA & (1<<UDRE)))  //Ausführen so lange wie UDRE gesetzt ist
16
  {
17
  }
18
  UDR = c; // Übergabe der der Midi-Bytes
19
}
20
21
22
23
24
25
void main()
26
{
27
init_USART();
28
int bank=0;
29
DDRA = 0xff; //PortA als Ausgang für BCD-Treiber setzen
30
PORTA = 0; //PortA --> 0 als Anfangswert schreiben (Bank anzeige)
31
32
DDRD = 0b11100011;  // Bit 2,3,4 Eingang setzen (Pin 16,17,18 Schalter für den Kanal) 
33
          // Bit 7,6,5 <-(LED S1,S2,S3)
34
          // Bit 0,1 Ausgang -> Uart
35
PORTD = 0b00011111; // Pullups schalten für taster
36
37
38
39
40
while(1)
41
{
42
  
43
  PORTA=bank;
44
  if ( !(PIND & (1<<PIND2)) )
45
  {
46
  
47
  
48
    PORTD |= (1<<PD7); //LED1 Einschalten
49
    PORTD &= ~( (1<<PD6) | (1<<PD5) ); //LED 2,3 Ausschalten
50
    send(192);
51
    send(bank);
52
53
54
  }
55
56
  if ( !(PIND & (1<<PIND3)) )
57
  {
58
    PORTD |= (1<<PD6); //LED2 Einschalten
59
    PORTD &= ~( (1<<PD7) | (1<<PD5) ); //LED 1,3 Ausschalten
60
    send(192);
61
    send(bank);
62
63
  
64
  
65
  }
66
67
  if ( !(PIND & (1<<PIND4)) )
68
  {
69
    PORTD |= (1<<PD5); //LED3 Einschalten
70
    PORTD &= ~( (1<<PD7) | (1<<PD6) ); //LED 1,2 Ausschalten
71
    send(192);
72
    send(bank);
73
74
  
75
  }
76
77
}
78
}

Bitteschööön

von Midibox (Gast)


Lesenswert?

Edit: Hier noch ohne die Delay-fkt. Sobald ich sie aber irgendwo nach 
dem "SEND" beifüge ist vorbei mit SEND.......

von Ein (Gast)


Lesenswert?

Midibox schrieb:
> Jetzt kommt es! Nach dem einfügen der delay fkt. sendet der auf einmal
> nicht mehr über den Uart.

Wie lange hast du dich denn geduldet?

Hast du mal eine LED mit delay() getoogled und deinen tatsächlichen 
µC-Takt kontrolliert?

von Midibox (Gast)


Lesenswert?

Sorry Leute, ich verstehe es gerade nicht?! Aber es klappt nun. Ich habe 
in meinem Programm noch vorher logische Abfragen über die Taster gemacht 
(bevor es in die While ging um zu entprellen...). Den ganzen klatsch 
habe ich weggelassen und dann mal wirklich meinen Code auf das 
"Grundgerüst" optimiert, so wie ich ihn gepostet habe. Ich sollte mich 
wohl mal mehr in die Thematik entprellen einlesen, denn so fummeleien 
führen wohl doch nicht zum gewünschten Ergebnis.

Nun klappt auch die delay-fkt. nach dem uart senden.
z.B.
1
if ( !(PIND & (1<<PIND3)) )
2
  {
3
    PORTD |= (1<<PD6); //LED2 Einschalten
4
    PORTD &= ~( (1<<PD7) | (1<<PD5) ); //LED 1,3 Ausschalten
5
    send(192);
6
    send(bank);
7
  _delay_ms(2000);
8
9
  
10
  
11
  }
 Die Zeit stimmt zwar nicht genau aber mit gefühl kann ich mir jetzt ein 
"einfaches" entprellen auf diese Art und weise bauen. Der µC soll 
sowieso nichts anderes machen als Befehle senden und an einen 
BCD-Treiber die aktuelle Bank-Zahl ausgeben.

Danke trotzdem!!!
Manchmal hilft es eine Nacht drüber zu schlafen :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.