Help with Parallel to Serial Input
mynet43
Posts: 644
I'm designing a circuit board that requires more I/O pins than are available from the Propeller.
I have no problem adding output ports. I added 32 outputs using 74HC595 shift registers and 5 GPIO lines.
The problem is adding input ports. I'd like to use some kind of 8 or 16 bit parallel to serial chip to allow more input signals, but I'm not sure which chip to use or the best control interface. I'd like to be able to monitor these input lines in a way similar to the Propeller input lines.
Any help you can provide will be really appreciated.
Thank you,
Jim
I have no problem adding output ports. I added 32 outputs using 74HC595 shift registers and 5 GPIO lines.
The problem is adding input ports. I'd like to use some kind of 8 or 16 bit parallel to serial chip to allow more input signals, but I'm not sure which chip to use or the best control interface. I'd like to be able to monitor these input lines in a way similar to the Propeller input lines.
Any help you can provide will be really appreciated.
Thank you,
Jim
Comments
Do you have any experience with a driver or how best to make this look like propeller I/O inputs? I.e monitor them for change of state?
Jim
There might be more objects for using the 165. I just entered 74HC165 in the search window of the OBEX. The search might not have found them all.
I haven't used either of these objects myself.
Duane
The HC595 driver has to be very high speed, since I'm emulating I/O ports. I already have an assembly language driver I wrote for that.
By the way, I'll probably use the HCT165's, because I'm using them at 5V and controlling them with the 3.3V from the Prop. I've run into problems before trying to do this with the HC's.
It's beginning to look like I may have to dedicate a cog to monitoring the 165 chips. Does anyone have a better suggestion for this? I hate to use a cog for nothing but this.
Thank you for the help and support.
Jim
Hope that helps.
PS - also works with a '165.
I like the idea of using the same clock. The only problem with this is that the output (595's) is called only when needed, and I'm cascading 4 of the 595's to get 32 bits out. The 165 needs to be running continuously.
Sariel. Thanks for the code. It looks very straightforward. A couple of questions.
1. Did you tie all four of the latch pins together when you were getting 32 bits?
2. Is the waitcnt command necessary? It seems like spin is so slow that this wouldn't be an issue.
This is great code, it looks like it will be easy to put it in assembly.
It looks like I will probably interleave the 595 and 165 routines. I'll have the 165 running continuously, but interrupt it when a 595 access command is issued.
If anyone has some other suggestions or sample code. Let me know.
Thank you all for the help.
Jim
Yes. The latch pins were tied and the clock pins were all tied to the same I/O's. Ins and outs of each chip are connected accordingly (in of one to out of other, main output connected to the I/O of your choice on the prop.
The data sheet I have has a really crappy timing diagram, but after looking at it, I suppose those could be removed since there is a delay of like 20ns from load to clock pulse. Might be something I should look into when I go to update this project. I am not an assembly guru by any means, so I don't know how that would affect it if you were to port it over to PASM
Good luck, and glad to help out.
I use the code to control the brightness of 120 LEDs. I don't think there is anything in the code that isn't common sense but I'll post it if you'd like me to.
It sounds like you already of the 595 stuff figured out.
Duane
I like your idea of shifting out the data lines together. My code works fine, but it would obviously be faster if I shifted all 4 data lines out in parallel. Of course this would use three more prop pins.
I would like to look at your code if it's convenient.
Thank you for the help.
Jim
This code is pretty rough. The parent object is very large and cumbersome. I don't have a demo for this object. The parent object uses special hardware including an eight bit parallel ADC to capture video.
I use the attached object to display a gray-scale image that the video capture cog places in a 120 byte array.
The brightness of each LED is determined by the effective duty cycle of the object. I don't have a frequency parameter with the PWM. The period is just however long it takes to read the 120 bytes from the array 254 times(I plan to change this so the cycle loops 255 time instead of 254).
As the driver is currently written the count down (periodCount) never reaches zero since the djnz causes the loop to exit without using the zero value within the loop. This makes LEDs with brightness values of zero and one both turn on for the same amount of time(1/254 of total time). I plan to change the driver so the LEDs with brightness values of zero stay off the entire cycle.
I realized after I finished writing the driver, I probably had plenty of time to use only one data line for all 16 shift register chips. I haven't computed the frequency of the PWM produced by this driver.
I can change the location of the 120 byte buffer on the fly. This is useful to switch from displaying a grey-scale image of the video capture to displaying scrolling text or graphics.
Here's the guts of the PASM code:
I'd be very surprised if there isn't a faster way of doing this but the driver, as it is now, is plenty fast for my current needs.
There should also be a way of using a rdlong instead of rdbyte to speed things up but I'm sure using a rdlong would make the code more complicated.
The name of the file was a result of my seeing the cool patterns scroll across the LED array (with a date code postfix).
Duane
LedCoolness110519a.spin
Thanks for sharing the code. I really like the way it's so compact, by using the wc and the muxc instructions. I need more practice with this.
You're right, I think you could speed it up if you needed to, by doing a rdlong of the 4 value bytes, then making an inner loop that uses local variables. This would eliminate three of the rdbytes, which should speed it up quite a bit.
Also, an easy way to get to the zero you're looking for would be to use a value of one less than periodCount within the loop, and just use periodCount for the djnz. This would make the upper limit 254, but that's probably OK.
mov periodCount, #$FF
mov valueCount, periodCount
sub valueCount, #1 ' use this as the cmp value in the loop and decrement it again just before the djnz
I'll copy the code and stare at it some more. I think it will help.
Thanks again!
Jim
You are welcome.
If I were to use a rdlong, I'd still want to read from four separate places within the buffer.
It would be much too hard to try to arrange the four groups of bytes in the array into an array of longs.
I have other methods that scroll text and graphics into and out of the array area.
There is probably some nice alogrithm to do just what I want. I'm just can't think of it myself. As I mentioned before, the code is already plenty fast for my needs. It's just hard not to think about ways of making it faster.
Yes, that's what I'll need to do. I can just chang "#$FF" to "#$100" to have it loop 255 times. I'll probably add a way of dynamicly changing the number of times to loop as a way of dimming the display. If I increased the times to loop to $200, it should cut the brightness in half.
I think I've been off on my hex to decimal conversions. The loop had been executing 255 times. I want it to execute 256 times. Don't you love the way you have to start counting at zero with computers?
Duane