Problem bei Steuerung über MIDI und ATtiny2313

Gast #1521404
Lesenswert?

Liebe Mikrokontroller-Gemeinde,

bei meinem eigentlich einfach scheinenden Projekt hänge ich fest.
Es geht um folgendes: eine Steuerung von 6 Diaprojektoren über einen 
ATtiny2313. Das Signal soll ein Musikstück im MIDI-Format sein, was über 
einen PC an die Platine weitergegeben wird.
Jeder Projektor erhält eine Note, wird diese Note gespielt, soll er zum 
nächsten Dia weiterschalten.
Die Platine funktioniert an sich ohne Probleme, den Schaltplan hab ich 
euch drangehängt.
Schwierig wird's beim Code. Ich denke dort ist irgendetwas mit der USART 
- Einstellung nicht in Ordnung. Ich selbst mach das hier zum ersten Mal, 
und bin da leider nicht so versiert - vielleicht kennt sich jemand von 
euch besser aus.
Die Platine kann schalten, leider reagiert sie aber nicht auf 
MIDI-Signale.....

Hier der Code
1
/********************************************************
2
 *   midiled für ATTiny2313                *
3
 *   über Port b0 led mit midinote schalten        *
4
 ********************************************************/
5

6
#include <avr/io.h>                    // Standard Bibliothek
7
#include <util/delay.h>                  // Verzögerung
8
#include "midi.h"                    // Midi Informationen
9

10
#define MCU AVR_ATtiny2313                // Microcintrollertyp
11
#define F_CPU 8000000                  // 8Mhz Quarz
12
#define UART_BAUD_RATE 31250              // 31250 Baudrate
13

14
#define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1)  // Berechnung des Inhalts des UBBR-Registers
15

16
typedef unsigned char  BYTE;              // Datentypdefinitionen
17
typedef unsigned short  WORD;              // braucht man nicht unbedingt
18

19

20

21
int main (void)                      // Anfang Hauptprogramm
22
{
23

24

25
    UBRRH = UART_BAUD_SELECT;              // Baudrate einstellen
26

27
  UCSRB = (1<<RXEN)|(1<<TXEN);
28

29
    DDRB = 0xff;                    // Port B als Ausgang konfigurieren
30

31
    while(1) {
32

33
    if (UCSRA & (1<<RXC)) {                 // Bit RXC im UCSRA gesetzt ?
34
        switch (UDR) {                      // Datenregister auslesen
35
            case 'noteon':                // Note an abfragen
36

37
               
38
                break;
39
            case 'a':                  // Note a abfragen
40
         PORTB |= (1<<PINB0);           // Pinb0 von PortB auf high setzen
41
        PORTD |= (1<<PIND6);          // Pinb6 von PortD auf high setzen  
42
      _delay_ms(180);                  // .18 sek warten
43
                PORTB &=~ (1<<PINB0);          // Pinb0 low setzen
44
                PORTD &=~ (1<<PIND6);          // Pinb6 von PortD auf low setzen
45
        break;
46
            default:                  // Bei allen anderen Zeichen nichts machen
47
                break;
48
    }
49

50
    }
51
  }
52
}

Und hier die Midi-Initialisierung:
1
              // midi.h
2
              // midi definitionen
3

4
#define noteon   0x90    // note an  #define noteoff 0b10000000      // note aus
5
#define oc1    0x0C    // octave +1
6

7
              // notentabelle für octave 0
8

9
#define c    0x0C    // n12 (c0)
10
#define db    0x0D    // n13 (d#0)
11
#define d    0x0E    // n14 (d0)
12
#define e    0x0F    // n15 (e0)
13
#define eb    0x10    // n16 (e#0)
14
#define f    0x11    // n17 (f0)
15
#define fb    0x12    // n18 (f#0)
16
#define g    0x13    // n19 (g0)
17
#define gb    0x14    // n20 (g#0)
18
#define a    0x15    // n21 (a0)
19
#define b    0x16    // n22 (b0)
20
#define bb    0x17    // n23 (b#0)

Falls jemand mir jemand von euch da weiterhelfen kann, wäre das wirklich 
super.
Vielen Dank schon mal fürs durchlesen
Paula
Angehängte Dateien:
Gast #1521458
Lesenswert?

Hi.
Hab deinen Code jetzt nicht im Detail angeschaut, aber hier meine 
MidiInit - die ist getestet und für gut befunden ;)

void uart_as_midi_in(void)
{
        /*Baudratenfaktor berechnen und setzen*/
  u32 baudrate = 31250;
  u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
  outb(UBRRL, bauddiv);
  #ifdef UBRRH
  outb(UBRRH, bauddiv>>8);
  #endif
  UCSRB |= (1<<RXEN);    //Empfang einschalten
}

Gruß
#1521531
Lesenswert?

Lothar Miller schrieb:
> der mechatroniker schrieb:
>> 'a' bleibt 'a'
> Richtig, ein ASCII-a bleibt ein ASCII-a.
> Soweit reicht das define zum Glück nicht  ;-)

Trotzdem würde ich das als nicht so wahnsinnig glückliche Idee 
bezeichnen.
So einbuchstabige Variablennamen kommen in Funktionen schon mal vor, 
ohne dass man sich darüber Gedanken macht, welche Makros da jetzt noch 
ein Wörtchen mitzureden haben. Gerade bei Makros ist die Erfahrung 
eigentlich die: Den Namen lieber so wählen, dass es nur unter sehr 
aussergewöhnlichen Umständen zu Verwechslungen kommen kann.

Was spricht gegen
1
#define NOTE_ON 0x90
2
#define NOTE_a  0x15

dann hat man in der Verwendung
1
       switch (UDR) {                      // Datenregister auslesen
2
            case NOTE_ON:                // Note an abfragen
3
                break;
4

5
            case NOTE_a:                  // 
6
  ...

und das wäre IMHO eigentlich sehr gut im Code lesbar. Und nur darauf 
kommts an. Das Makro kann kompliziert sein wie Sau, in der Verwendung 
des Makros im Code muss sich der Sinn des Makros (die Aussage) auch 
einem Blinden mit Krückstock in 5 Meter Entfernung erschliessen. Und da 
steht jetzt ja eigentlich schon fast im Klartext: wenn der Inhalt von 
UDR (also das empfangene Zeichen) der Note a entspricht, dann ....

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