www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem bei Steuerung über MIDI und ATtiny2313


Autor: povla (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
/********************************************************
 *   midiled für ATTiny2313                *
 *   über Port b0 led mit midinote schalten        *
 ********************************************************/

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

#define MCU AVR_ATtiny2313                // Microcintrollertyp
#define F_CPU 8000000                  // 8Mhz Quarz
#define UART_BAUD_RATE 31250              // 31250 Baudrate

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

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



int main (void)                      // Anfang Hauptprogramm
{


    UBRRH = UART_BAUD_SELECT;              // Baudrate einstellen

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

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

    while(1) {

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

               
                break;
            case 'a':                  // Note a abfragen
         PORTB |= (1<<PINB0);           // Pinb0 von PortB auf high setzen
        PORTD |= (1<<PIND6);          // Pinb6 von PortD auf high setzen  
      _delay_ms(180);                  // .18 sek warten
                PORTB &=~ (1<<PINB0);          // Pinb0 low setzen
                PORTD &=~ (1<<PIND6);          // Pinb6 von PortD auf low setzen
        break;
            default:                  // Bei allen anderen Zeichen nichts machen
                break;
    }

    }
  }
}

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

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

              // notentabelle für octave 0

#define c    0x0C    // n12 (c0)
#define db    0x0D    // n13 (d#0)
#define d    0x0E    // n14 (d0)
#define e    0x0F    // n15 (e0)
#define eb    0x10    // n16 (e#0)
#define f    0x11    // n17 (f0)
#define fb    0x12    // n18 (f#0)
#define g    0x13    // n19 (g0)
#define gb    0x14    // n20 (g#0)
#define a    0x15    // n21 (a0)
#define b    0x16    // n22 (b0)
#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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> case 'noteon':         // Note an abfragen
Wozu die Hochkommas?

> (1<<TXEN)
Warum schaltest du den Sender ein?

> #define a    0x15    // n21 (a0)
Du definierst damit das kleine Ascii-a um. Willst du das?

Sieh dir mal die Warnungen des Compilers genau an. Da kommen sicher 
welche. :-/

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du definierst damit das kleine Ascii-a um. Willst du das?

Tut er doch gar nicht.

a ist nun 0x15
'a' bleibt 'a'

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 'a' bleibt 'a'

Ergänzung: deswegen stören auch die Hochkommas bei case 'noteon'.

Autor: bronko (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der mechatroniker schrieb:
> 'a' bleibt 'a'
Richtig, ein ASCII-a bleibt ein ASCII-a.
Soweit reicht das define zum Glück nicht  ;-)
Ich habe das mal ausprobiert:
#define a 0x15
#define b 'b'

int main(int argc, char* argv[])
{
   printf("%c %c   %c %c   \n", a, 'a', b, 'b');
}
Ausgabe:   § a   b b


Bleiben also die Hochkommas...

Autor: Michael W. (retikulum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UBRRL muss 0 sein? UBRRH muss 0 sein und UBRRL muss 15 sein.

Michael

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>>>> UBRRH = UART_BAUD_SELECT;              // Baudrate einstellen
> UBRRL muss 0 sein? UBRRH muss 0 sein und UBRRL muss 15 sein.
Auf jeden Fall sollten beide was abbekommen... ;-)
Ich würde das so probieren:
UBBRH = UART_BAUD_SELECT >> 8;
UBBRL = UART_BAUD_SELECT & 0xff;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
#define NOTE_ON 0x90
#define NOTE_a  0x15

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

            case NOTE_a:                  // 
  ...

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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.