Mick Kunstelj wrote: >Hi Microchip! > >I think I have an idea that could do mega cool things for your PIC range >(84 in particular) > >Simply, add a hardware shift register on chip which is programmed via a >register. > >For clarification, firstly lets assume an 8 bit shift register: > >Now, the speed of the shifting is controlled by a divider connected to >the main clock, and is set by a register. Also, a bit indicates if the >input to the register comes from an external source, a simple MSB->LSB or >just filled with zeros. Keep in mind that the PIC actually has many potential shift registers (every one of the 36 RAM locations, plus any special function registers that you're not using) controlled by software, using the RRF and RLF instructions. Probably only a heavy-multitasking type application would absolutely require dedicated hardware shift registers. The advanced timers and SSP hardware in the 16C64 and 16C74 devices could also probably be used to implement many of these applications mentioned by Mick. > >What is the use, you may ask? > >Well, with such a system, you could quite easily make PWM, by setting the >bits on as the duty cycle, choosing the required divider for frequency >and using MSBLSB wrap around. The result? You've got a good PWM which >can be tied to a motor control or low pass filtered to make audio. True, but the resolution of the PWM would only be 9 steps (the number of 1 bits in the register controlling the average output level, there could be 0 to 8 1 bits present. If you want 9-step analog control (well, actually 8-step) I would suggest using a simple D/A converter of 3 resistors tied to 3 output pins (resistors would have a ratio of 1:2:4, such as 75K:150K:300K which are standard values). Of course, the usual lack of I/O pins in an 84 design might preclude this. Another possible PWM approach (as 'hands-off" from the PIC as possible for high speed operation) could be to use two external binary counters of N bits each driven by the same clock (derived from the PIC clock). The MSBs of these counters would be X-ored together to form the PWM signal. Now if the counters are running perfectly in phase, the X-or output never goes high. If one counter is 2^N /2 counts ahead of the other, the output is always high. And of course, intermediate amounts of lead would cause intermediate duty cycles on the X-or output. So how to make the counters run with a known phase relation to each other? The most direct way would be to connect the reset pins of both to seperate outputs from the PIC. Then use a software timing loop to delay the reset of one counter to however mayn cycles you need ahead of the other one. This will generate a "glitch" whenever the duty cycle is changed. More advanced software could synchronize to Counter #1, then reset #2 at exactly the right time. The beauty of this method, although it does require $0.50 or so worth of hardware outside the PIC, is that once the count is set, the PIC does not need to do anything to generate the PWM. One nice PIC feature to have in a future version would be a way to make the MSB of the RTCC drive an external pin. Then the RTCC could serve as one of the counters in the example above. > >Another usage of the shift register could be an Inter-PIC communication >system, simply fill the register with data a let it blast out. Also, a PCM >system effectively on chip. Potential pitfall here is that another pin would need to be used to synchronize exactly when the data starts to come out, unless the register could be forced to stop when a 1 comes out of the top bit. Then "asynchronous" data could be received by having the sender hold the line at 0, send a dummy 1 as a start bit, then the other 8 data bits. The two shift registers would still have to have exactly the same clock regardless, so it would need to be directly the X1 clock unless some provision is made for ensuring that all the prescalers in both chips are sysnchronized. > >Now, I mentioned that the shift register could also take information >externally. Well, here is something that might interest people.... > >Hook up a sigma-delta converter (two op amps), and you get a 1 bit output >stream which could be fed into the PIC. Result? An A/D! If you are >wondering, such a system requires a higher bandwidth. For instance, if >you want to read in an analogue signal at the nyquist rate at 8 bits of >accuracy, your sample rate becomes 8*nyquist, accepting digital input. >By putting in a simple software digital decimation filter, this means >you've got an 8 BIT A/D converter!!!! No flash circuitry, no successive >approximation, real simple, good accuracy, and it works. > > >[ COOOL HUH!?!?!?! ] > >Now, to take the example further, and to where I think MICROCHIP should >take it to: > >Give the PICS two such shift registers, a hook them up so one shift >register can either get information from intself, and external pin, a >zero or the other shift register. > >This would give the PIC the option of either two shift registers, or one >16 bit shift register. > The C flag makes chaining RAM locations into long software shift registers almost zero cost (one instruction per byte): sr24 ;Shift a bit left into a 24 bit shift register. rlf regl,1 ;Bit in C goes into LBS of regl. rlf regm,1 rlf regh,1 ;Bit from MSB of regh output to C. >The 16 bit register could mean that you have a PWM, a PCM system, a 16 >bit D/A or alternately a 16 bit A/D. > >Also means that you could blit out information, then read in information >as the register is simultaneuosly filled with incoming information. Again, do-able with software. > >For a low complexity, low cost addition, it's pretty neato. Maybe low cost, but not zero cost. If my application doesn't require this hardware, I don't want to pay for it in every chip I buy anyway. > Now to put my money where my mouth is... If you need to in or out information in the background, I present this little interrupt-driven 9 (or 8N + 1) bit shift register. Typically the interrupt would be called by the RTCC, or the external interrupt pin, depending on whether you want internal or external clocking. Many variations are possible. 9-bit version uses 2 RAM locations: cysav and ssrg. srint ;Make sure this is at the interrupt vector location (0004h in a 16C84) ;INSERT CODE HERE TO CLEAR INTERRUPT REQUEST. OTHERWISE.... bcf INTCON,x ;Optional: For 'Asynchronous' operation, this 2 instr will stop shifting once the ninth bit ; becomes 1. btfsc cysav,7 ;Skip if bit 8 (MSB of SR) is 0. retfie ;Return now. Don't shift. ;Save the C flag from the interrupted program, as the shifting process below will disturb ; it. rlf cysav,1 ;This RAM variable saves C from the interrupted program, (in ; bit 0) and also contains the 9th bit of the SR (in bit 7). :Input: Copy value from PORT_X,inpin to C. ; If the input routine below is not implemented, then data will 'loop' through the SR. If it ; is implemeted, then the data read from the input pin will be shifted into bit 0. clrc btfsc PORT_X,inpin setc ;Shift: Shift the data left one. Expand the register in multiples of 8 bits by adding ; more rlf's with additional unique RAM locations. rlf ssrg,1 ;Output: Put the bit output (the new value of the 9th bit in the SR) out to PORT_X,outpin. skpnc ;Is data 1? bsf PORT_X,outpin ;Yes, output 1. skpc ;Is data 0? bcf PORT_X,outpin ;Yes, output 0. ; This routine does not 'glitch' outpin if a series of ones or zeros are being output. If ; 'glitches' are acceptable in your application, the faster routine below may be used: bcf PORT_X,outpin ;Assume we're outputting 0. skpnc ;Really 0? bsf PORT_X,outpin ;No, output 1. ;Recovery: Put away the ninth bit for next time. Get the interrupted program's C back. rrf cysav,1 ;SR bit into bit 7. Old C out of bit 0. retfie ;Return. With all the bells and whistles, this is 14 instructions (17 cycles, allowing 2 to process the interrupt. So maximum shifting rate is 58 KHz with a 4 MHz X1 clock. Of course, this doesn't allow the main program any time to do anything. So if you want to pound data into a T1 line out of your PIC, this isn't going to cut it. Disclaimer: All code examples are untested and may contain minor or major bugs. Use this information at your own risk. I do NOT work for Microchip or have any association with them other than as a customer. -Mike