
Simple little project using the switches on the front of the AVR to simulate a MIDI keyboard. The USART TX pin was connected to pin 15 of the gameport on the computer, and ground to pin 4 of the gameport. I used an application named MIDI-OX to dump live MIDI data, and map the input to the Microsoft GS Wavetable Synth.
Useful sites/documentationMIDI and the AVRGameport Pinout MIDI Interface on Wikipedia MIDI Interface at BadIdeas NOTE: On the STK500, the AVR ATMEGA8515 is set to 3.686Mhz by default. We need a baud rate of 31250 bps (or very close) to comply with MIDI standard. Unfortunately, a 3.686Mhz clock misses this value by far, as the UBBR ends up being near 6.5, when the UBBR can only be an integer. Rounding this up or down results in a very inaccurate baud speed, and therefore complete corruption occurs. I set the fuse bit SUT_CKSEL to Int. RC osc 8Mhz to get an 8Mhz clock. I ended up with a whole number for UBBR when using this speed, which is perfect! This code is pretty poor. It polls the switch inputs, but I couldn't be bothered to use interrupt driven code, lazy me. Also, the getkey function locks up when you press down multiple switches. #include <avr/io.h>
#define F_CPU 8000000UL //Define crystal/RC osc frequency
#include <util/delay.h>
void init_io(void);
void init_usart(unsigned int baud);
void txbyte(unsigned char data);
unsigned char rxbyte(void);
unsigned char retkey(unsigned char input);
int main(void)
{
init_io();
init_usart(15);
unsigned char prev = 0;
unsigned char cur = 0;
while(1) //Infinite loop
{
cur = PINA; //Get switch input
if (cur < 255) //If a switch is pressed
{
if (prev != cur) //If the input isn't the same as previously
{
txbyte(144); //NOTE_ON
txbyte(retkey(255-cur)); //NOTE
txbyte(100); //VELOCITY
}
}
prev = cur;
}
}
unsigned char retkey(unsigned char input)
{
//Designed to make the relationship between each input switch linear
//Will not work if you hold down multiple switches, only one at a time
unsigned char sec = 1;
unsigned char j = 50;
for(unsigned char i=1; sec>0; i=i*2)
{
sec = input - i;
j++;
}
return j;
}
void txbyte(unsigned char data)
{
while ( !( UCSRA & (1<<UDRE)) ); //Wait for empty slot to send data
UDR = data; //Send it
}
unsigned char rxbyte (void)
{
while ( !(UCSRA & (1<<RXC)) ); //Wait until there is a byte to be read from RX buffer
return UDR; //Get it
}
void init_io(void)
{
DDRA = 0;
PORTA = 255;
//Port A is the input
}
void init_usart(unsigned int baud)
{
// Setup serial I/O for communication
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
|
Online SoundCloud Downloader, NEW!Download tracks posted on SoundCloud for free in high-quality MP3! SoundScrape.netUseful eBay Links |