I'm not finding any examples of pwm usage on this chip. Can someone help me out with the initializations that need to happen? I can figure out the math and everything for frequency, I just need to know how to set the config registers.
This is for a class project. We're hoping to be able to use MQX with all of its bells and whistles, but it doesn't have a PWM driver. I'm open to trying another OS, but we do need a *relatively* easy way to access the ethernet-related functions (and thus at minimum, need a tcp/ip stack integrated). The PWM will be used to interface with some servo motors, and thus we will need to be able to change the frequency dynamically during runtime.
I am in possession of a 52233DEMO board to develop on. In the end, we will have to solder a chip onto a pcb of our own. I'm a bit of a newbie working with micros, but have experience with programming in general.
Any help is much appreciated!
-Ben
Solved! Go to Solution.
If it helps, I have a skeleton source code project that shows PWM usage for both analog output (thru a low-pass filter) and servo control, at the bottom of the page: http://www.cpustick.com/downloads.htm
In the zip file, you want to look at the file sources/pin.[ch]. Unfortunately, the same file supports about a dozen different MCUs, so you want to ignore everything that is not #if MCF52233. I'm not sure how you want to use the PWMs, but you can see the way I use them for "analog_output" and "servo_output".
Alternately, you could load StickOS (download at the page) and you can control your PWM pins trivially via a stored program on the MCU that you can write just by telnet'ing to port 1234 of the MCU... Like:
Welcome to StickOS for Freescale MCF52233 v1.72!
Copyright (c) 2008-2009; all rights reserved.
http://www.cpustick.com
support@cpustick.com
(checksum 0x6af3)
> list
10 dim pot as pin an0 for analog input
20 dim servo as pin dtin2 for servo output
30 rem adjust our servo pulse width based on the position of the pot
40 rem 0mV -> 1ms pulse; 3300mV -> 2ms pulse
50 while 1 do
60 let servo = 100+pot*100/3300
70 sleep 500 ms
80 endwhile
end
> run
<Ctrl-C>
STOP at line 70!
>
Interesting. I'll take a look at this and see if I can get something to work.
In regards to how we're using the servos:
The micro will need to trigger a motor to swing its arm 170degrees once, then wait for a sensor input edge at which point it will sent the motor's arm back to 10 degrees. So basically, the micro will need to toggle the period of the pwm signal between a "cocked" arm state and an "extended" arm state.
CFinit is pretty cool (as well as super helpful with PWM clock adjustments!).
However, it is not enough to just copy the initializations into our code. I'm not familiar with what libraries inherent in Codewarrior for Coldfire have all the definitions in them. For example, the following is generated in the pwm_init function (just enabling pwm1 and setting it up for one of the waves that I want):
MCF_PWM_PWMPER1 = MCF_PWM_PWMPER_PERIOD(0xf);
MCF_PWM_PWMDTY1 = MCF_PWM_PWMDTY_DUTY(0x4);
MCF_PWM_PWMPOL = MCF_PWM_PWMPOL_PPOL1;
MCF_PWM_PWMCLK = MCF_PWM_PWMCLK_PCLK1;
MCF_PWM_PWMPRCLK = MCF_PWM_PWMPRCLK_PCKA(0x7);
MCF_PWM_PWMCAE = 0;
MCF_PWM_PWMCTL = 0;
MCF_PWM_PWMSCLA = MCF_PWM_PWMSCLA_SCALEA(0x12);
MCF_PWM_PWMSCLB = 0;
MCF_PWM_PWME = MCF_PWM_PWME_PWME1;
MCF_PWM_PWMSDN = 0;
but none of those symbols are defined if I try to use them from within an MQX project. Is anyone able to tell me what to #include or how exactly to get those things defined so that they function?
I'm trying to dig myself to find anything that will help, but I have limited experience, so I'm having a hard time.
bhorst wrote:...
but none of those symbols are defined if I try to use them from within an MQX project. Is anyone able to tell me what to #include or how exactly to get those things defined so that they function?
Personally, I prefer to not use the supplied header files. It doesn't take that long to right your own register definitions. This allows me to pick names I like for the macros. It also removes dependency on the vendor-supplied header file and makes it easy to switch compilers.
You should check the header files with register definitions that come with your toolchain. The macros you are looking for could still be there, only named slightly differently. Or you'll have define your own macros.
I had looked up the internal registers and such, but I was unsure of exactly how to code it up. I've had one class with microcontrollers, but the registers were always already set up for us. We just had to use them and assign the correct values to them.
Late last night, after digging around, I found what I was looking for and got something to work. For any other newbies that come across this thread:
I generated a codewarrior project with the initializations that I wanted
I grabbed the functions that related to the peripheral that I actually needed the init for (pwm in my case)
Also check the pin assignment functions (I didn't do this at first, and the pwm was probably functioning, but it was not assigned to a pin!)
If one just copies that into another project, you'll be missing some symbols, running a search in the "include" folder should find them
Copy those into either another header file to include with your project or put the ones you need at the top of your .c file.
I ended up with something like this:
//set up the pwm, enable pwm1
MCF_PWM_PWMPER1 = MCF_PWM_PWMPER_PERIOD(0xf);
MCF_PWM_PWMDTY1 = MCF_PWM_PWMDTY_DUTY(0x4);
MCF_PWM_PWMPOL = MCF_PWM_PWMPOL_PPOL1;
MCF_PWM_PWMCLK = MCF_PWM_PWMCLK_PCLK1;
MCF_PWM_PWMPRCLK = MCF_PWM_PWMPRCLK_PCKA(0x7);
MCF_PWM_PWMCAE = 0;
MCF_PWM_PWMCTL = 0;
MCF_PWM_PWMSCLA = MCF_PWM_PWMSCLA_SCALEA(0x12);
MCF_PWM_PWMSCLB = 0;
MCF_PWM_PWME = MCF_PWM_PWME_PWME1;
MCF_PWM_PWMSDN = 0;
//make sure it is assigned to an output pin!
MCF_GPIO_DDRTA = 0;
MCF_GPIO_PTAPAR = MCF_GPIO_PTAPAR_PTAPAR0(0x3);
**Then later in the code (under an if statement that kept track of the potentiometer AtD conversion)
MCF_PWM_PWMDTY1 = MCF_PWM_PWMDTY_DUTY(0xd);
This sets up PWM1 output on GPT0 (which is measurable on J1 pin 13 on my DEMO board) to output a low duty cycle square wave that changes to a higher duty cycle when the potentiometer is turned past a certain point. (later on in the project, it will be toggled by something else, but this was a good experiment to start with)
I included the mcf5223_pwm.h file and a few lines of the mcf5223_gpio.h file in a header of my own to get everything to compile and function correctly.
Thanks to scifi for the tips!
@scifi: I understand that writing my own register definitions would be a much better solution. If I had ever done that before, I certainly would have. My healthy respect for my own ability to screw it up and the fact that I'm simply not comfortable doing that as a first attempt kept me from doing it myself. Now that I have something working that I can toy with, I will probably do some refactoring and in the future will be able to write the definitions. Also, I do not even know what you mean when you say "toolchain." thanks again