Har ingen länk då jag byggt den själv utifrån microchips solutions-bibliotek. Finns ett exempel där som spelar en midi-not vid knapptryck. hittar 17 inte schemat, men är simpelt.
Gjorde helt enkelt om det exemplet lite. Behöll 1 knapp till reset, och satte en jumper på RB4 för bootloadiing.
Sen satte jag RX + TX till motsvarande midisignaler på en DB15-kontakt och även GND och +5 på motsvarande kablar för att ta ström från USB.
D+ och D- på picen till usb-porten, och en kondensator till GND från vusb. Har även en pullup från Ra2 av någon anledning ^^. ska kolla koden och se om jag kan hitta varför, har projektet ivägstädat i någon backup just nu. (tror dock det var någon powersensefunktion på picdem som även kan ha tänkts funnits i bootloadern)
I övrigt så städade jag bort allt som hörde till diverse demokort, och sparade enbart koden till picdem. Modifierade den för en 18F2550 (den är normalt baserad på 18F4550, men de är kompatibla, bara lite LED-kod för PORTD som behöver bort).
Den viktiga biten i den koden är ProcessIO, där läser jag från RX/RC7. Om data finns ledig, så läser jag det antal bytes ett specifikt midimeddelande utgör, packar om till ett 32-bitars usb-midipaket och skickar via usb till datorn. MidiOX är fantastiskt för att debugga och bygga detta. Dessutom så innehåller exemplet en bootloader, så när du uppdaterat koden är det bara trycka ner reset och kortsluta jumpern på RB4 och ladda på ny firmware via programmet microchip skickade med. resetta, starta om midiOX och kör.
Kod: Markera allt
void ProcessIO(void)
{
// User Application USB tasks
if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
if(!USBHandleBusy(USBRxHandle))
{
//We have received a MIDI packet from the host, process it and then
// prepare to receive the next packet
//INSERT MIDI PROCESSING CODE HERE
//Get ready for next packet (this will overwrite the old data)
USBRxHandle = USBRxOnePacket(MIDI_EP,(BYTE*)&ReceivedDataBuffer,64);
}
if(DataRdyUSART()==1)
{
data1=ReadUSART();
while (!DataRdyUSART());
data2=ReadUSART();
while (!DataRdyUSART());
data3=ReadUSART();
midiData.Val = 0; //must set all unused values to 0 so go ahead
// and set them all to 0
midiData.CableNumber = 0;
if(data1==0x90)
{
midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON;
}else{
if(data1==0x80)
{
midiData.CodeIndexNumber = MIDI_CIN_NOTE_OFF;
}else{
midiData.CodeIndexNumber = MIDI_CIN_POLY_KEY_PRESS;
}
}
midiData.DATA_0 = data1;
midiData.DATA_1 = data2;
midiData.DATA_2 = data3;
USBTxHandle = USBTxOnePacket(MIDI_EP,(BYTE*)&midiData,4);
}
}//end ProcessIO
Min kod i ProcessIO, som du ser där så hanterar det inga meddelanden skickade från datorn, utan bara den andra vägen. Pga att jag har en ganska dum keyboard.

Men det är ganska enkelt att bygga vidare på. Övriga ändringar i koden är väl mest städning, och initiering av serieport.
Initierar picens serieport till midi i mainfunktionen med:
Kod: Markera allt
TRISCbits.TRISC7=1; //Make UART RX pin input
OpenUSART (USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 383);
i
i usb_descriptors.c kan du ändra namnet på din device som står i windows också.
Hoppas det här hjälper dig lite på vägen.
Edit: Det kan även behövas en optokopplare mellan miditillbehör och datorn, i detta fallet behövdes det inte, då jag dels ger keyboarden sin ström direkt från usb-porten, och gameportsignalen är TTL-kompatibel. För att undersöka detta gjorde jag först ett program till picen som loggade serieportssignalerna till en display istället för usb, och jämförde datan med protokollet.