PWM DutyCycle in PIC

Status
Not open for further replies.

magester1

New Member
Hi there. I'd like to ask for some help with a piece of code I'm trying to write.
I'm using MPLAB, and PIC 16F628A. Although this I could use for other things (not only PWM) that range from 0 to 100%.

Within the main program, I need to set the Dutycycle from 0% to 100% depending on some readings, to make things easy, it would be 0 for 0% all the way to 255 for 100%.
I'm using counters which increment at a fixed time length (with TMR0), as readings.
So I would have my first variable -which is a constant actually in the rest of the program- that determines the max value. I'll call it MAX, it would be a single byte and would normally be initialized at 80-100 or 180-200 (it may vary some more, but I don't think that makes much of a difference anyway).
Then a second variable, which goes from 0 to MAX. I'll call it DCycle since it determines the dutycycle.

a)I'm used to working with C so I first thought of a simple: (255/MAX)*DCycle. That would give me a value between 0 and 255.
b)Then I thought of a table. to which I pass the value of DCycle. However, since DCycle's max number isn't always the same, the last values of the table wouldn't always work.

So, I'm stuck here. Should I try approach a)? and start writing division and multiplication rutines. If so, I'd like some help there, since I think those rutines could be less complex than what I've found, given that I'm not doing it for ANY value, just for my readings which are kind of limited and I'm working with 8-bit numbers only.
Or b)? and do something about those values depending on MAX. I'm not sure if that can be done though. I would certainly need some guidance in that case

Any other approach is welcomed, I just didn't think of anything else.

Thanks to all who took the time to read this.
I apologize if this was already discussed in some thread, I looked for it but couldn't find anything.

By the way, note that I'm not that experienced in programming with Assembler.
 
Hi, Magester

Your project is not so clear to me ...

do you want to always get a 0-100% PWM output for an input value you will previously give the max value ???

That could look like a programmable PWM RC Controller ...

the simplest way is to use calculations ...

You could calculate your retrieve table @ power up but the 628 has limited RAM ... so you don't avoid calculations.

No hope nor to store the table in the program zone ... with a 628 ...

Alain
 
If you want just one PWM channel then the 16F628 has this in hardware, for two channels the 16F876 has two - check my tutorial for how to use it for a skid steer robot. Far easer than doing it in software.
 
I guess I should explain it different then.
I'm already familiar with how the PWM in the 628 works, I've used it and everything.
What I'm trying to do actually has nothing to do with it, it's more about percentages.

I'll try with a little example, maybe it's better.
Lets say a take a reading which I store at my first variable, the one I called MAX. It could be the time a button is pressed, it doesn't matter. So MAX is initialized at the beginning of my program (that's what would make it a constant for the rest, since I set it's value only once) with a value of, lets say, 200.
MAX = 200 (decimal)
Later on, during the main program, I have another variable, DCycle, which is updated regularly, and con go from 0 up to the value of MAX.
So, it could be DCycle = 0, = 23, anything until DCycle = MAX.
Now, I want to convert that value.
Being 100% (DCycle = MAX) a 255 decimal and 0% a 0, stored in some other variable, lets say RESULT (to make it simple).
So it'd be like, if DCycle = MAX then RESULT = 255
if DCycle = MAX/2 then RESULT = 127
Of course, I can't write all those ifs. Not the best solution, wouldn't you agree?

If I had to do it in C (at least the one I'm used to, which isn't for Microcontrollers) it would be as simple as:
RESULT = (255/MAX)*DCycle
However, it doesn't look that simple in Assembler. That's where I need help.
 
I think its the same duty cycle you need to calculate.

MAX=200
Then DCycle max=200

[DCycle/255] X 100 = Percentage
 
Last edited:
Ok, Majester ... got it

You simply have to use the 8bits x 8bits multiplication and 16bits / 8bits division routines you can find in Microchip Application notes ... no need to write it yourself.

just Download AN 00617 and its asm zipped files from microchip site ...

**broken link removed**

Alain

PS. What new in B.A. ??? ( 27 years I went there ... thing must have changed somewhat .)
 
Last edited:

All right then. I'll take a look at those.
By the way, is that the best way of doing it? Or is there any other maybe less complex?

I'm afraid I can't tell you much about B.A. I'm 18 years old so I have no idea how it was 27 years ago. And I've been living there for less than a year now. I moved there to start studing Electronic Engeneering...
 
Hi, Majester

You won't find anything simpler ... than those SMALL multiplication and division. Working with 16bits variables is something very usual ( especially for scaling purposes )... so, do not hesitate to "jump in".

For B.A. ... 27 Years ago, there were soldiers @ each crossroads of the town and they did not hesitate to point their loaded guns at you if you just seemed suspect ( and it was just the end of that awful epoch ... )

Talking politics was more than risky ...

... few months later, your elders endly could vote for democracy ... and President Alfonsin.

Have a "mate" for me ...

Alain
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…