At 10:27 AM 10/12/99 +1000, you wrote: >I am looking at a project involving 4 MIDI interfaces (both in & out). MIDI >is a 31250bps NRZ comms scheme. As well as the I\O there are quite a few >other things going on such as routing of the messages, ADCing of knobs and a >possible USB interface down the track. I can't foresee any problems with 4 >outputs, you could simply have them synchronised. You'd need a couple of >extra instructions to get the 4 bits as a nibble, but if you had one nibble >of a port as in and the other as out you could simply write to the whole >port without effecting input. I can't foresee any problems with this. In the >case that other port pins were used as ouputs you would need to read, AND, >OR and write, still not too bad. 31250bps = 32us\bit, on a 20MHz (5MIPS) PIC >that's 160 instructions\bit. Unlesss the reciever latched the data on the >rising edge of the clock, I can't see any problems, I should really be able >to be as much as 20 instructions late in writing the data with no problems, >as long as I don't lose time. > > The main problem is 4 channels of MIDI in. In theory I think it should just >about be possible. The main problem is keeping the timing. >I could either poll the 4 inputs or have interrupt on falling edges (Stop >bit -> start bit). > This is quite a problem. This may or may not work, but as I see it your biggest problem is 4 start bits coming in at 4 different times asynchronously. I would set up your Timer0 to give you a beat of Tbit/4, so 40 instructions. This will give you fairly decent resolution in your bit timing. Then I would use interrupt on change for your 4 serial lines to catch the start bits. What you want to do is catch each start bit, turn off the int on change, and delay one to two Timer0 beats to catch the approximate middle of the bit. The two interrupts could communicate via some global variable, that would say how many more beats to sample the first bit. So basically what's happening is that Timer0 interrupt is marking off exactly 1/4 bits, the int on change catches the start bit of each bit and signals the Timer0 interrupt to sample at appropriate times. Any other processing will be done in the down times when interrupts are not being serviced. Where this gets sticky is the 4 instruction cycle latency. With a 40 instruction beat, that kills 10% of you CPU right off the bat, pllus whatever you use in the Timer0. There may not be enough to go around. Another suggestion might be to byte buffer your serial ins with shift registers. You would need a clock at 31250 KHz and a shift register for each line you want to buffer. The start bit generates an interrupt and your micro enables the proper shift register. You setup your timer0 interrupt to wake up at least every byte time (which is now 160*8 ~= 1200 instructions) to pull in the data. This is sort of a roll your own UART. Good luck! -Erik Reikess