Ich hab mal ein MiDi Metronom gebastelt.
Hier nur mal der Quelltext, die Sound Dateien usw. hab ich mal nicht mit hochgeladen - zu groß.
Und das File ist für das ATMEL Studio 7:
Über einen Schalter kann die Taktart eingestellt werden über einen 3 Stufen Wechselschalter der Sound.Code:/* * MiDi_Metronom.c * * Created: 11.12.2018 17:06:18 * Author : Krug, Wilhelm * Version: 1.0 */ /* ATMEGA 328P Pin Belegung Pin Name Funktion 1 PC6 Reset 2 PD0 MiDi IN 3 PD1 4 PD2 5 PD3 Test Taster 6 PD4 Sound Auswahl 1 7 VCC 8 GND 9 XTAL1 10 XTAL2 11 PD5 Sound Auswahl 2 12 PD6 PWM Sound Out 13 PD7 14 PB0 Taktauswahl 0 15 PB1 Taktauswahl 1 16 PB2 Taktauswahl 2 17 PB3 Taktauswahl 3 18 PB4 Taktauswahl 4 19 PB5 Taktauswahl 5 20 AVCC 21 AREF 22 GND 23 PC0 LED 1 Ausgang ( Rot ) 24 PC1 LED 2 Ausgang ( Gruen ) 25 PC2 LED 3 Ausgang ( Gruen ) 26 PC3 LED 4 Ausgang ( Gruen ) 27 PC4 LED MiDi aktiv LED ( Rot ) 28 PC5 */ #define F_CPU 20000000 #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <util/delay.h> #include "sound.c" //Zähler, Counter und Flags volatile uint8_t midistate = 0; //MiDi Status Metronom Ein / Aus volatile uint8_t midiclocks = 0; //Zähler für empfangene MiDi Clocks volatile uint8_t beatcomplete = 0; //24 MiDi Clocks wurden Empfangen ein Takt ist zu Ende volatile uint8_t beatcounter = 0; //Zähler für die Takte #define statestop 0 #define staterun 1 //LED Section #define LED0 PORTC |=0b00000001 #define LED1 PORTC |=0b00000010 #define LED2 PORTC |=0b00000100 #define LED3 PORTC |=0b00001000 #define LED_MIDI PORTC |=0b00010000 #define LED_MIDI_OFF PORTC &=0b11101111 #define LEDOFF PORTC &=0b11110000 volatile uint8_t ledcount = 0; #define ledlen 12 volatile uint8_t midiled = 0; #define midiledlen 2 //MiDi Kommandos #define MIDI_START 0xFA #define MIDI_STOP 0xFC #define MIDI_CLOCK 0xF8 #define MIDI_CONTINUE 0xFB //Schalter und Tasten Definitionen #define sel_clock0 (PINB & 0b00000001) //Stumm #define sel_clock1 (PINB & 0b00000010) //Jeder dritte Beat Sound 1 #define sel_clock2 (PINB & 0b00000100) //Jeder vierte Beat Sound 1 #define sel_clock3 (PINB & 0b00001000) //Jeder Beat Sound 1 ( 1/4 ) #define sel_clock4 (PINB & 0b00010000) //Beat1 = Sound 1 Beat2 = Sound 2 ( 2/4 ) #define sel_clock5 (PINB & 0b00100000) //Beat1 = Sound 1 Beat 2 + 3 = Sound 2 ( 3/4 ) #define sel_clock6 (PINB & 0b00111111) //Beat1 = Sound 1 Beat 3 = Sound 2 ( 2/2 = halbe Geschwindigkeit #define test_switch (PIND & 0b00001000) //Der Test Taster wurde gedrückt PINB3 = 0 #define sel_sound (PIND & 0b00110000) //Beat1 = Sound 1 Beat 2...4 = Sound 2 ( 4/4 ) #define sound0 0b00000000 //Fehler keine gültige Auswahl #define sound1 0b00010000 //Klassisches Metronom #define sound2 0b00110000 //Ableton Metronom #define sound3 0b00100000 //Percussion Metronom //USART Section #define FRAMING_ERROR (1<<FE0) #define PARITY_ERROR (1<<UPE0) #define DATA_OVERRUN (1<<DOR0) #define DATA_REGISTER_EMPTY (1<<UDRE0) #define RX_COMPLETE (1<<RXC0) // USART Receiver buffer #define RX_BUFFER_SIZE 255 char rx_buffer[RX_BUFFER_SIZE]; #if RX_BUFFER_SIZE<256 unsigned char rx_wr_index,rx_rd_index,rx_counter; #else unsigned int rx_wr_index,rx_rd_index,rx_counter; #endif // This flag is set on USART Receiver buffer overflow volatile uint8_t rx_buffer_overflow; //Timer 2 Overflow Vektor wird alle 819µs aufgerufen ISR (TIMER2_OVF_vect) { if(ledcount > 0 ) { ledcount --; } else { LEDOFF; } if(midiled > 0) { midiled --; } else { LED_MIDI_OFF; } } ISR (USART_RX_vect) { uint8_t status,data; status=UCSR0A; data=UDR0; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { LED_MIDI; //MiDi Datenempfang Status LED midiled = midiledlen; switch(data) { case MIDI_START: midiclocks = 0; //Neuer Start, alle Zähler auf 0 beatcounter = 1; midistate = staterun; //MiDi Status auf running beatcomplete = 1; //Ein Beat ist komplett -> Aktion ausführen break; case MIDI_STOP: //MiDi Clocks wurden gestoppt midistate = statestop; break; case MIDI_CLOCK: if(midistate > statestop) { midiclocks++; if(midiclocks > 23) { beatcomplete = 1; //Ein Beat ist komplett -> Aktion ausführen beatcounter++; //Beats hochzählen, werden bei der Taktauswahl wieder zurückgesetzt midiclocks = 0; //Ein neuer Zählzyklus beginnt } } break; case MIDI_CONTINUE: midistate = staterun; //Die Metronomausgabe wird fortgesetzt break; } } } //Metronomtakt Hauptschlag Metronomsound void play_metro1 (void) { uint16_t i = 0; for(i=0;i<metro1_wav_len;i++) { OCR0A = pgm_read_byte (&metro1_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Nebenschlag Metronomsound void play_metro2 (void) { uint16_t i = 0; for(i=0;i<metro2_wav_len;i++) { OCR0A = pgm_read_byte (&metro2_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Hauptschlag ABLETON Metronom Sound void play_able1 (void) { uint16_t i = 0; for(i=0;i<able1_wav_len;i++) { OCR0A = pgm_read_byte (&able1_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Nebenschlag ABLETON Metronom Sound void play_able2 (void) { uint16_t i = 0; for(i=0;i<able2_wav_len;i++) { OCR0A = pgm_read_byte (&able2_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Hauptschlag Trommelsound void play_drum1 (void) { uint16_t i = 0; for(i=0;i<drum1_wav_len;i++) { OCR0A = pgm_read_byte (&drum1_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Nebenschlag Trommelsound void play_drum2 (void) { uint16_t i = 0; for(i=0;i<drum1_wav_len;i++) { OCR0A = pgm_read_byte (&drum2_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Hauptschlag Beckensound void play_ride_high (void) { uint16_t i = 0; for(i=0;i<ride_high_wav_len;i++) { OCR0A = pgm_read_byte (&ride_high_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //Metronomtakt Nebenschlag Beckensound void play_ride_low (void) { uint16_t i = 0; for(i=0;i<ride_low_wav_len;i++) { OCR0A = pgm_read_byte (&ride_low_wav[i]); _delay_us(90); } OCR0A = 0x7F; } //LED und Soundausgabe je nach eingestelltem Wunschsound void setoutput (uint8_t takt) { ledcount = ledlen; switch(takt) { case 1: //Erster Takt = Start Sound + LED 1 LED0; if(sel_sound == sound1){play_metro1();} if(sel_sound == sound2){play_able1();} if(sel_sound == sound3){play_drum1();} //Parken! //if(sel_sound == sound3){play_ride_high();} break; case 2: //Zweiter Takt = anderer Sound + LED 2 LED1; if(sel_sound == sound1){play_metro2();} if(sel_sound == sound2){play_able2();} if(sel_sound == sound3){play_drum2();} //if(sel_sound == sound3){play_ride_low();} break; case 3: //Dritter Takt = anderer Sound + LED 3 LED2; if(sel_sound == sound1){play_metro2();} if(sel_sound == sound2){play_able2();} if(sel_sound == sound3){play_drum2();} //if(sel_sound == sound3){play_ride_low();} break; case 4: //Vierter Takt = anderer Sound + LED 4 LED3; if(sel_sound == sound1){play_metro2();} if(sel_sound == sound2){play_able2();} if(sel_sound == sound3){play_drum2();} //if(sel_sound == sound3){play_ride_low();} break; default: //Fehler es wurde einungültiger Wert übergeben beatcounter = 0; } } //Taktmassabfrage und Verwaltung der Ausgabe void sel_takt ( void ) { //Jeder dritte Takt if(sel_clock0 == 0) { if(beatcounter == 1){setoutput(beatcounter);} if(beatcounter > 2){beatcounter = 0;} } //Jeder vierte Takt if(sel_clock1 == 0) { if(beatcounter == 1){setoutput(beatcounter);} if(beatcounter > 3){beatcounter = 0;} } //Jeder Takt if(sel_clock2 == 0) { if(beatcounter > 1){beatcounter = 0;} //Fehler beim Umschalten abfangen if(beatcounter == 1) { setoutput(beatcounter); beatcounter = 0; } } //2/4 Takt if(sel_clock3 == 0) { if(beatcounter == 1){setoutput(beatcounter);} if(beatcounter > 1) { setoutput(beatcounter); beatcounter = 0; } } //3/4 Takt if(sel_clock4 == 0) { if(beatcounter == 1){setoutput(beatcounter);} if(beatcounter == 2){setoutput(beatcounter);} if(beatcounter > 2) { setoutput(beatcounter); beatcounter = 0; } } //4/4 Takt if(sel_clock5 == 0) { if(beatcounter == 1){setoutput(beatcounter);} if(beatcounter == 2){setoutput(beatcounter);} if(beatcounter == 3){setoutput(beatcounter);} if(beatcounter > 3) { setoutput(beatcounter); beatcounter = 0; } } //Alla Breve Takt 2/2 = Halbe Geschwindigkeit if(sel_clock6 == 63) { if(beatcounter == 1){setoutput(beatcounter);} //if(beatcounter == 2){setoutput(beatcounter);} if(beatcounter == 3){setoutput(beatcounter);} if(beatcounter > 3) { //setoutput(beatcounter); beatcounter = 0; } } } //Test Taster ist gedrueckt = Testausgabe void testausgabe ( void ) { beatcounter = 1; while (test_switch == 0) { sel_takt(); //Ausgabe starten beatcounter++; //Der Takt wird hochgezählt LED_MIDI; //MiDi Datenempfang Status LED - Hier für Testzwecke! midiled = midiledlen; _delay_ms(425); } beatcounter = 0; } int main(void) { //uint8_t i = 0; // Input/Output Ports initialization // Port B initialization // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0); // State: Bit7=T Bit6=T Bit5=P Bit4=P Bit3=P Bit2=P Bit1=P Bit0=P PORTB=(0<<PORTB7) | (0<<PORTB6) | (1<<PORTB5) | (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0); // Port C initialization // Function: Bit6=In Bit5=In Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out DDRC=(0<<DDC6) | (0<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0); // State: Bit6=T Bit5=T Bit4=T Bit3=0 Bit2=0 Bit1=0 Bit0=0 PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0); // Port D initialization // Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0); // State: Bit7=T Bit6=0 Bit5=P Bit4=P Bit3=P Bit2=T Bit1=T Bit0=T PORTD=(0<<PORTD7) | (0<<PORTD6) | (1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0); // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 20000,000 kHz // Mode: Fast PWM top=0xFF // OC0A output: Non-Inverted PWM // OC0B output: Disconnected // Timer Period: 0,0128 ms // Output Pulse(s): // OC0A Period: 0,0128 ms Width: 0 us TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00); TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00); TCNT0=0x00; OCR0A=0x7F; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer1 Stopped // Mode: Normal top=0xFFFF // OC1A output: Disconnected // OC1B output: Disconnected // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10); TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10); TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: 312,500 kHz // Mode: Normal top=0xFF // OC2A output: Disconnected // OC2B output: Disconnected // Timer Period: 0,8192 ms ASSR=(0<<EXCLK) | (0<<AS2); TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20); TCCR2B=(0<<WGM22) | (1<<CS22) | (0<<CS21) | (0<<CS20); TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0); // Timer/Counter 1 Interrupt(s) initialization TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1); // Timer/Counter 2 Interrupt(s) initialization TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (1<<TOIE2); // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00); EIMSK=(0<<INT1) | (0<<INT0); PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0); // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: On // USART Transmitter: Off // USART0 Mode: Asynchronous // USART Baud Rate: 31250 UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0); UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80); UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0); UBRR0H=0x00; UBRR0L=0x27; // Analog Comparator initialization // Analog Comparator: Off // The Analog Comparator's positive input is // connected to the AIN0 pin // The Analog Comparator's negative input is // connected to the AIN1 pin ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0); ADCSRB=(0<<ACME); // Digital input buffer on AIN0: On // Digital input buffer on AIN1: On DIDR1=(0<<AIN0D) | (0<<AIN1D); // ADC initialization // ADC disabled ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0); // SPI initialization // SPI disabled SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0); // TWI initialization // TWI disabled TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE); // Globally enable interrupts sei(); //Main Loop while (1) { //Der Test Taster ist gedrückt = Probeausgabe if (test_switch == 0) { testausgabe(); } //Ein neuer Metronomtakt muss ausgegeben werden if ((midistate > 0) && (beatcomplete > 0 )) { sel_takt(); beatcomplete = 0; } } }
Anzeige oder sowas ist hier nicht mit drin!







Zitieren

Lesezeichen