Hi, The trouble with a clocked shift register running at the base bitrate (I presume you meant 31250Hz, not KHz), would be that the clock at the other end isn't necessarily exactly in sync with yours. If you happen to sample a start-bit right on the rising/falling edge, then even the slightest discrepancy in clock rates will cause incorrect data to be read on subsequent bits. In order to receive serial data with any degree of reliability it's necessary to sample the port at 3 times the base bitrate. When you detect the first edge of a start bit, you start to sample the data every 3rd tick, *starting immediately at the next tick*. This means that you can be confident that you're sampling the data anywhere between 1/3 and 2/3 through each bit. So, as long as the clocks don't shift by 1/3 of a bit over the course of the 10 (or however many) bits per word, you're safe. Trouble is, you have to consider the worst case scenario here... with 4 *independant* channels, you'd have to run the timer at 12 x 31250 = 375KHz... ie. 13.3 instructions per tick (on a 20Mhz/5MIPS PIC) in order to receive data reliably. That isn't going to be enough, given interrupt latency, etc... You're either going to need hardware UARTS, or a faster chip. You could use a Scenix SX (they actually have an application note on their website which deals with running 8 independant software UARTS), but unfortunately I don't think they have the ADC capabilities you'd be looking for. Hope this helps, Ben ----- Original Message ----- From: Erik Reikes To: Sent: Monday, October 11, 1999 6:08 PM Subject: Re: 4 x Serial I\O > 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