- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello!
I have an application that is taking timing info from a UART and updating the frequency and duty cycle using a PWM block. I want to be able to MUX a signal to output pins. Ideally, I'd like to scale it so that I can vary the number of channels I'm MUXing it to (either in software or hardware) so I could have a desired number of outputs (ie 3, 7, 13, etc rather than just 2, 4, 8, or 16) but this is less important.
I was wondering what the best approach would be? I thought about using the interrupt on the PWM to create a signal that toggles everytime the PWM toggles (using the interrupt on terminal counter, I think it was) and use that as a clock for a counter (though the counters are only 4 bit, so if I wanted to use a desired number of outputs, such as 7, I assume I'd have to have some sort of software comparison to the MUX signals to reset the counter if the count is over 7 or something to that effect?
The other possibility, I guess, is to create my own UDB block that's custom for my application but I'm not sure if I'd be able to vary the number of outputs at that point.
Anyway, if anyone has any suggestions as to the best way to approach this application (or a way, or feedback on my previous thought process), I'd appreciate it. Thanks!
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Addendum:
I made a new project for the PSoC5. That device has a different PWM block. Digital/Functions/PWM looks suitable.
Configure it for Fixed Function. Set the width to get the duty cycle resolution that you need.
Note that this PWM peripheral has a down counter unlike the up counter in the PSoC4 TCPWM. That changes how the compare value maps to duty cycle. Set the compare value to 0 to get 100% duty cycle. Set the compare value to the period value to get minimum duty cycle.
Use the tc output to clock the Channel counter.
Zero the kill and reset inputs.
Ought to work for you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[EDIT] Re-reading your post, I think I misunderstood what you're looking to do. What I have below would combine multiple PWM signals into a single output, not split it out to multiple outputs.
Would something like this maybe do what you're looking for?
You could use the Kill_PWM_Select Control Register to disable/enable the PWM signals you want to mux, the outputs go into an OR gate to combine the signals of any active PWM. You could also make sure the PWMs are synced by enabling and using the "Trigger" input. Note that I haven't tested this or anything, just something I thought might work given your description of what you're trying to do.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand you correctly, you want to be dealing these PWM pulses out like playing cards. In that case, this'll work:
It'll handle 1-8 channels as shown. You set the highest channel number by configuring the value of the constant "5" in the little block at the lower-right.
The widths of the demultiplexer, the counter, the digital comparator, and the constant block ("5") are configurable. If you widen them all to 4 bits, you can have 1-16 channels. You'll use more UDB resources in that case.
Is that what you're looking for?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It looks like I might not have explained it very clearly. I'm actually wanting to output the PWM signal to one output pin at a time, rather than to have multiple PWM's combined into one GPIO pin.
That actually looks what I'm looking to accomplish! I'm hoping to try this out this weekend and ensure it works. Thanks a lot for the suggestion!
Out of curiosity, what PWM model is that? The model I'm looking at looks like the version KTrenholm is using. Is that a custom PWM or just an older revision of that part?
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I implemented the design on a PSoC 4 BLE (CyBLE-214-009 in particular) since that’s what I have handy. Should work the same in the PSoC 5, though.
The PWM is the library block Digital/Functions/PWM (TCPWM mode) . That’s one of the dedicated TCPWM peripherals operating in PWM mode. It’s a quite competent PWM and, because it’s a dedicated block, consumes no UDB resources.
Project attached.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Addendum:
I made a new project for the PSoC5. That device has a different PWM block. Digital/Functions/PWM looks suitable.
Configure it for Fixed Function. Set the width to get the duty cycle resolution that you need.
Note that this PWM peripheral has a down counter unlike the up counter in the PSoC4 TCPWM. That changes how the compare value maps to duty cycle. Set the compare value to 0 to get 100% duty cycle. Set the compare value to the period value to get minimum duty cycle.
Use the tc output to clock the Channel counter.
Zero the kill and reset inputs.
Ought to work for you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the help! It looks like this got me where I need to get. Turns out the PWM module you posted here is V2.1 and it got imported into my project as incompatible so I could use it, unfortunately.
I currently have it working as shown below:
What's interesting is the clock/interrupt line doesn't appear to be doing anything (LED3 isn't toggling at all but it must be working if the counter is counting, right?) so it doesn't look like I need this at all, from what I can see (I do have an interrupt setup and I'm reading the register that clears this). It doesn't really make sense to me why it works without a clock signal though so this must be working despite the fact I'm not seeing the LED toggle, right? Regardless, it seems to work anyway.
It looks like I just need to change that constant to (NumChannels - 1) and it seems to work as expected (it's setup above just to work as a single channel, even if it does have two LEDs hooked up). Is there a way to be able to programatically change the constant or is there another variable I can setup to change this (or another component that would be better suited for this? A register or something to that effect?).
Thanks for all the help! Let me know whenever you get the chance. Sorry for the delay!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you are only running one channel, you don't know whether the counter is counting or not. But I presume that you've run this with two channels at some point to verify the counter's functionality.
I'd recommend using the tc (Terminal Count) output on the PWM to clock the counter. That output runs all the time giving a short pulse just before the next PWM cycle.
The interrupt output can be disabled in firmware which would freeze the channel counter. Seems like an opportunity for confusion to me.
To be able to change the channel counter range, go get a Control Register component from the library and drag it onto your schematic. Configure the Control Register's width to the counter's width and set it for a bus output. Connect that to the MaxChannel comparator's b input in lieu of the constant block. Write to the Control Register to change the number of channels.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's perfect, that got it up and working! Thanks for all your help (and sorry for the delays. I'm working two jobs right now so my hours for my second job are all over the place). Have a good day!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Happy to be of help. Enjoy!