PWM
SailerMan
Posts: 337
Bean helped me with this code and I am not sure that I am using it Right.
It seems that no matter which channel I select, the same PWM happens on all 4 output pins. RB.0-RB.3
Thanks for any help.
Regards,
Eric
·I set in my program PWM_Values(0)=128
·I get a 50% Duty PWM on RB.0-RB.3
[noparse][[/noparse]edit] This Code Works Now... [noparse]:)[/noparse]
Post Edited By Moderator (Bean (Hitt Consulting)) : 11/3/2006 1:13:50 PM GMT
It seems that no matter which channel I select, the same PWM happens on all 4 output pins. RB.0-RB.3
Thanks for any help.
Regards,
Eric
·I set in my program PWM_Values(0)=128
·I get a 50% Duty PWM on RB.0-RB.3
[noparse][[/noparse]edit] This Code Works Now... [noparse]:)[/noparse]
PWM_Count VAR BYTE PWM_Values VAR BYTE (4) INTERRUPT ASM ' ** Setup variables MOV __PARAM1,#4 ' (2) Number of bits per port MOV __PARAM2,#1 ' (2) OR Mask for turning a bit ON MOV __PARAM3,#254 ' (2) AND Mask for turning a bit OFF INC PWM_Count ' (1) Adjust the PWM count ' If the PWM value for each channel is ' less than PWM_Count then it should ' be high, othewise it should be low MOV __PARAM4,PWM_Count ' (2) Make copy of PWM_Count in global memory MOV FSR,#PWM_Values ' (2) Set FSR to address of 1st element of PWM values :NEXT_BIT CJA IND,__PARAM4,@:MAKE_HIGH_B ' (5/7) If this element is above PWM_Count ' Then jump to MAKE_HIGH_B AND RB,__PARAM3 ' (2) Value is below or equal to PWM_Count so ' make it low. JMP @:DONE_BIT_B ' (4) Jump over MAKE_HIGH code :MAKE_HIGH_B OR RB,__PARAM2 ' (2) Value is above PWM_Count so make it HIGH NOP ' (1) Waste time NOP ' (1) Waste time :DONE_BIT_B STC ' (1) Need to shift a 1 into AND mask value RL __PARAM3 ' (1) Shift AND mask value CLC ' (1) Need to shift a 0 into OR mask value RL __PARAM2 ' (1) Shift OR mask value INC FSR ' (1) Point to next array element DJNZ __PARAM1,@:NEXT_BIT ' (3/5) Repeat until done ENDASM ReturnInt
Post Edited By Moderator (Bean (Hitt Consulting)) : 11/3/2006 1:13:50 PM GMT
Comments
Now I see it, I forgot to put "INC FSR" just before the "DJNZ __PARAM1,@:NEXT_BIT".
That should fix it.
Sorry about that...
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
Here it is. Now this is NOT·very effecient code, but it does show what's going on...
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
It's a good way to learn!!
Thanks for everything.
One thing to keep in mind is that the assembly in the first post was machine generated by the SX/B compiler. Machine generated assembly code is harder for humans to read since it doesn't make human comprehension a priority. I have gone through with a plain old text editor and done a search and replace to convert the unfriendly variable names with human friendly versions. There are two things to notice here:
1 - Just changing variables names to something with meaning makes assembly code easier to read.
2 - ALWAYS use good variables names (such as "PwmCount") and not weak variable names (such as "Count" or "Cnt" or "C" to make the code easier to comprehend at a glance.
Here's the easier to read version:
BTW, you can make this even easier to read by copying it into the SX-Key IDE or any text editor that uses a non-proportional font. That will makes the comments line up correctly.
Thanks, PeterM
Thanks
crgwbr
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life
I would assume all code posted in the forums is public domain unless otherwise noted.
It takes 256 interrupts to get 1 pulse of PWM. So you need to know how many pulses per second you want. Then just multiply that by 256 to get the interrupt rate.
For example a LED needs to be updated at least 50 or 60 times a second so you don't see the flicker. So I would probably use 100 for the PWM update rate. That means the interrupt must occur 25,600 times a second. The faster the interrupt rate, the less processor time your main program gets, so don't over do it.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life
·
I'm still learning about PWM.
I've learn alot from Bean's code.
Just incase you are using serial or time sensitive subroutines, you really need to remember to take your ISR time into account!!
Thanks bean for answering the question. It's your code.·
Post Edited (SailerMan) : 11/9/2006 6:45:01 PM GMT
Thanks
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life
But the prescaler divides the RTCC so an interupt will happen less frequently.
ISR just stands for Interupt Service Routine.... And if it takes longer to run your ISR than the time between ISR calls (Real Time Clock Counter (RTCC) Ticks) there will be no time left over for the balance of your program. I divided my Interupt call with Setting Option to $80.
I hope that made sense and I hope I am correct in this thinking.
So I decided to only call the ISR as often as I needed to run my program and left as much processing power for the balance of the program which is where the Serial in/out takes place.
If you want your interrupt to occur 25600 times a second just do:
INTERRUPT 25600
' Your code here
RETURNINT
The SX/B compiler will automatically enable interrupts and set the prescaler and the RETURNINT value for you.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·
What! How did I miss that.
So to set an interrupt to 60 Hertz I would just type INTERRUPT 120?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - PLJack - - -
Perfection in design is not achieved when there is nothing left to add.
It is achieved when there is nothing left to take away.
Post Edited (PLJack) : 11/11/2006 12:14:35 AM GMT
So for 60 Hz the clock must be 60*65536 or less, so that is about 3.9MHz.
Otherwise you will have to use a multiple and use a counter in the interrupt.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
"People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
·