- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I am using CY8CKIT-050 Development Board for my project purposes. I intend to generate a PSFB PWM signals from the PSFB block such that the phase shift is like a sine wave. To explain it in another way, I want my phase shift to gradually increase from 0 to maximum value and then reduce to 0 within 10 ms (half wave of a 50 Hz sine wave). It is similar to a sinusoidal PWM where the ON time of PWM increases from 0 to maximum and then reduces to 0 in 10 ms. The only difference here is that I need my phase shift to change the way a sinusoidal PWM changes.
My PWM signal is 10 kHz i.e. 10^(-4)s. My phase shift to increase from 0 and then return back to zero in 10 ms. So there would be 100 PWM signals (.01s/.0001s). From this information I came up with the sine table as given below after having a look at this article 'http://microcontrollerslab.com/spwm-generation-using-pic16f877a-microcontroller/'.
uint8 sine_table[101] = {255, 254, 253, 252, 251, 250, 248, 246, 244, 242, 239, 237, 233, 230,
227, 223, 219, 215, 210, 206, 201, 196, 191, 185, 180, 174, 168, 162,
156, 149, 143, 136, 129, 122, 115, 108, 101, 93, 86, 78, 71, 63, 55, 47,
39, 31, 23, 16, 8, 0, 0, 8, 16, 23, 31, 39, 47, 55, 63, 71, 78, 86, 93,
101, 108, 115, 122, 129, 136, 143, 149, 156, 162, 168, 174, 180, 185, 191,
196, 201, 206, 210, 215, 219, 223, 227, 230, 233, 237, 239, 242, 244, 246,
248, 250, 251, 252, 253, 254, 255};
I have included my code along with this post. Please have a look at it and do point me in the right direction so that I can sort out this issue at the earliest.
Thanks in advance.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The PSFB component is not included with your project.
Your error is caused by running your infinite loop at max speed. I would suggest you to setup and start a 100Hz timer. At that interrupt you change the WriteCompare() value. Use 100 points for the sine table, not 101.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had already added PSFB component in the dependency list of the project . I believe this is what you were trying to say when you said 'The PSFB component is not included with your project'.
Thanks to you now I understand what was going wrong. Like you said I should have included a timer which generates an interupt on overflow and then increment the counter of the lookup sine table. But I believe the timer should be a 10 kHz one right? Because I need to increment my phase after every 10 kHz. So I should be changing the WriteCompare() value on every 10 kHz interrupt. Isn't it so?
As you suggested I used 100 points for sine table.
I have updated the code and attached along with this post. Please have a look at it and do give me your valuable suggestions and feedbacks.
Thanks a lot for offering me a helping hand.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
Please ignore the above attached bundle. I made a couple of changes from the above code and I have attached the latest bundle along with this post. I verified the waveforms in an oscilloscope. I found that the ON time for the PWM signals were only 4 us out of 100 us (approximating 106.4 us) which is considerably very small and I wouldn't receive much of an overlap. How do I increase the ON time to say 40 us?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
Could you please have a look at the attached screenshot of my lookup table? In that it is shown that sine_table has data type uint8 while the elements have data type unsigned char. And along with the values in each location of the array there are other values displayed too. Such as '\377' for 355, '\375' for 253, '\374' for 252 and so on. This goes on for all the elements. This looks like ASCII characters. Is there something wring with my array initialization?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In this project I don't have any tasks running other than phase updating. I just need to update the phase shift every 10 kHz. For that, as Bob suggested, I introduced a Timer component which gives me an interrupt every 100 us i.e. 100 kHz and then I increment my counter for lookup sine table on every interrupt.
My knowledge on DMA is very limited. Could you please point me to the right sample project which employs DMA similar to my application?
Thanks for offering your advice.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need a full sine (100 points) within 20ms which comes to 5000Hz. This is manageable with a PSoC5. What is your output PWM frequency?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So you want to have only two single pulses of the desired length for each of the 100 points, not a series of (for instance) 1000 pulses (@10MHz) for each of the 100 points.
Yes, you even might use only 25 points for the sin table and calculate, using some addition, the index for the quadrant. But that will save you just 75 bytes in flash, not worth the effort.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Still I do not see the PSFB component in your project.
You did not clear Timer_1's interrupt cause. You need to call Timer_1_ReadStatusRegister() which will clear the sticky bits, see datasheet.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Or are there other bits that need to be cleared? " See datasheet.
I do not need to see the (yet missing) component, obviously I can give some hints without it ;-))
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ASCII values are always <= 255. What you see is the representation in octal.
255Dec = FFHex = 377Oct
So you are a candidate for solving the riddle
"Why is for the average American child Halloween exactly equal to Christmas?" (Published first by Isaak Asimow)
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
uint8 is a typedef for unsigned char, so you did not define your table as integer which would be 16 bit wide.
Bob
Riddle solution: 31Oct = 25Dec
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
As you suggested I cleared the sticky bits. And now I have got PWM signals from PSFB with varying phase shift. But my issue is that the ON time for the PWM is very low (4%). I need to increase it close to 50%. Could you please suggest me ways to achieve it?
Have a look at my obtained waveforms. These are the EPWM1A (yellow) and EPWM2B (green) signals.
Riddle: Oh yeah. Now I get it. This is ingenious. If it wasn't for your hint I would still be lost. There's another one too. You would have heard of it. 'There are 10 types of people in the world. Those who understand binary and those who don't.'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to change the compare value accordingly to the period, use something like Period>>1. Read the API description thoroughly regarding when the next period value is taken and when the next compare value is applied.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I came up with the lookup table from the period. My period for 10 kHz is 255. And the lookup table was obtained by multiplying 255 (period) with sin(angle) for each points.
sin(0)*255
sin(1.8)*255
sin(3.6)*255
and so on till
sin(180)*255
How will the compare value affect the ON time of the PWM signals? It is the ON time of each PWM signal that I need to considerably increase from 4% (4 us) to close to 50% (50 us).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Read the PWM datasheet (which is the base of the PSFB) and see how the compare value is related to the on-time.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have used PWM blocks before. And I know how compare value works with on-time for PWM block. For instance if the compare mode is selected as 'Less than' and you give a compare value of say '200' then the output goes high when the counter goes below 200. I understand how on time is controlled for a PWM block. But when it comes to PSFB I don't know how compare value affects the on-time in PSFB. I tried linking working of PWM to obtain PSFB but I am still at a loss.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I noticed something when I changed the clock given to PSFB from 48 MHz (Bus Clock) to 4.8 MHz. The frequency remained the same i.e. 10 kHz which is the desired frequency while the ON time increased to a considerable value. How is that possible?
I have still not understood how compare value affects the Phase Shift. For instance if I take into account the picture attached along with the post, when the pwm signal width increases the time for which EPWM2B overlaps EPWM1A increases. Similarly the time for which EPWM2A overlaps EPWM1B also increases. I assume the PWMs are left aligned i.e. for the width to increase the right side of the PWM has to move while the left end remains fixed. If this is the case, then what happens if I give 255 as compare value? pwm signal would be high the whole time and so EPWM2B and EPWM2A will have a duty cycle of almost 75%.
I am at a loss on how compare value changes individual PWMs. Please help me out here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I cannot say much to the PSFB component, I am not used to it.
"I am at a loss on how compare value changes individual PWMs." This I can explain 😉
Three different parameters control a PWM
- The input clock
- The period value
- The compare value
The input clock is divided by the period value giving the PWM's output frequency
This is done (usually) by loading a counter with the period value and counting down with every clock cycle. When the counter reaches zero it gets reloaded with the period value.
The PWM output is connected to the comparator which compares the period counter with the period value. So while the compare value is not yet reached by the counter, the PWM output is zero, when the compare value is larger than the counter (which is decremented) the PWM output logic high.
So you manage the pulse width of a PWM by changing the compare value.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
Thanks for taking the pain to explain me the working of PWM. But my problem was I am not able to understand how compare values change the individual PWMs of PSFB (sorry for not making it clear at first). I am not able to relate PWM block to the working of PSFB. If the compare value is kept constant I can predict how the PWM signals would be like. But the issue arises when I have to change compare values as I am supposed to do in my current project. The frequency and ON time keeps changing of EPWM2B and EPWM2A.
I combed through every pages of PSFB datasheet. But nowhere is it mentioned the effects of a changing compare value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So I am at ends of my wits and cannot help you any further.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
Thank you Bob for giving me suggestions so far. It helped me a lot. And the best part is I was able to get the desired output with a slight change in the logic applied. Thanks for your help Bob. It definitely extended my knowledge in Cypress.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are always welcome!
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I have another query. You would be able to help me out. I have 4 digital output pins. Say Pin1, Pin2, Pin3 and Pin4 are the required pins. My requirement is to use these pins to fire up a SCR bridge. I just need to give a single pulse to turn it on. I need not give a continuous pulse. But where I have the issue is that at t=0s my Pin1 and Pin4 should be switched ON while Pin2 and Pin3 are OFF. The pins Pin1 and Pin4 should go low after that initial surge. Then when t=10ms I need to switch ON Pin2 and Pin3 for a small time while Pin1 and Pin4 are low. This must go on in a loop. Could you tell me how I can achieve it? I can use a timer for 10ms and then when it gives an interrupt I need to give pulse to the pins which weren't ON in the last cycle.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How long is the required pulse width? The minimum width has some impact on the program design.
When you use 4 consecutive pins of a single port it will be easier. You can write all 4 pins with a single write instruction. This can be done in a timer interrupt handler. You can use something like
static uint8 Pattern = 0b0110;
and in the interrupt handler
SCR_Write(Pattern ^= 0b1111);
Get your logic analyzer ready 😉
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I want a width of 1ms i.e. from t=0 to t=1ms I want SCR1A and SCR2B pins to be high while the other two are low and from t=10ms to t=11ms I want SCR1B and SCR2A to be high while the other two pins are low. I have mapped these four pins to P0_0, P0_1, P0_2 and P0_3.
Now how should I go about it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Setup a PWM with two interrupts, one at the rising edge and one at the falling. At the rising edge handler use the code I scetched in my former post, at the falling edge simply reset the pins to zero.
Define "Pattern" to have 4 pins which you assign to port 0. A simple Pattern_Write(Value) will set all pins as required.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Bob for the detailed expression. But won't there be another issue? For instance at the first rising edge I set Pin1 and Pin 4 while Pin2 and Pin3 are zero. Then at the falling edge Pin1 and Pin4 are reset to zero. But when the next 10ms interrupt comes I need to set Pin2 and Pin3 while the other two are zero. Then at the falling edge these same pins should be reset. So its the alternate pins that I have to set every 10ms. How do I bring in the toggling effect? I haven't seen of '^' operator before. Could you please give me a brief on it and whether that same operator would help me toggle the pins?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ohhh... I didn't know '^' represented XOR. Use of XOR is a masterstroke. I never thought of it. Thanks a lot Bob. I will try that out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I updated my PSoC Creator IDE to version 4.0. When I open the firmware attached to AN76496 I am receiving a lot of errors such that the version of different components used in the schematic is outdated. So I had to remove all those and then replace it with the latest one. But there is one error related to PSFB component that I haven't been able to resolve. I am not able to include the latest PWM component in place of the old one.
As you can see I am not able to select PWM component. Could you please let me know how I will be able to replace it with the latest one?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
vijayr,
Attached is Cypress PSFB project workspace (AN76439) updated and recompiled witn Creator 4.0. Import PSFB from it.