Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[Moved] LPC2138 PWM to control servo motor

Status
Not open for further replies.
I have tried with a timer toggling the output at 1KHz with the PLL on (60MHz, 1/4 PCLK), when I turned if off I git 1/5 of the frequency (200Hz)

Use this code and measure the frequency in P0.22
Code:
#include <LPC213x.h>


int main(void)
{
/*
   
    P0.22:  MAT0.0 (Match output for Timer 0 channel 0)
  
*/


    PINSEL0 = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    IO0DIR = 0x80000000;     /* binary: 10000000_00000000_00000000_00000000 */
    PINSEL1 = 0x00003000;     /* binary: 00000000_00000000_00110000_00000000 */
    PINSEL2 = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    IO1DIR = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */

/******************************************************************************
                             Timer0 (32bit)
*******************************************************************************
   Counter Enabled,    Counter Reset=0
   Timer mode: count on rising edge of PCLK
   Counter clk: 4 KHz, Counts every: 250 us  (calculated with peripheral clock: 15MHz)
   MCR0.0 : reset, on compare match
   MAT0.0 : On compare match Toggle bit/output
*/

    PCONP = (PCONP & 0x001817BE) | (1UL<<1);    /* Enable peripheral clock for Timer0 (default is enabled) */

    T0CTCR = 0x00;     /* binary: 00000000 */
    T0TC = 0x00000000;     /* decimal 0 */
    T0PR = 0x00000EA5;     /* decimal 3749 */
    T0MCR = 0x0002;     /* binary: 00000000_00000010 */
    T0MR0 = 0x00000001;     /* decimal 1 */
    T0MR1 = 0x00000000;     /* decimal 0 */
    T0MR2 = 0x00000000;     /* decimal 0 */
    T0MR3 = 0x00000000;     /* decimal 0 */
    T0CCR = 0x0000;     /* binary: 00000000_00000000 */
    T0EMR = 0x0031;     /* binary: 00000000_00110001 */
    T0TCR = 0x01;     /* binary: 00000001 */

   while(1)
  {
  
  
   }

}

Yes the frequency is around 200 hz .

- - - Updated - - -

I have tried with a timer toggling the output at 1KHz with the PLL on (60MHz, 1/4 PCLK), when I turned if off I git 1/5 of the frequency (200Hz)

Use this code and measure the frequency in P0.22
Code:
#include <LPC213x.h>


int main(void)
{
/*
   
    P0.22:  MAT0.0 (Match output for Timer 0 channel 0)
  
*/


    PINSEL0 = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    IO0DIR = 0x80000000;     /* binary: 10000000_00000000_00000000_00000000 */
    PINSEL1 = 0x00003000;     /* binary: 00000000_00000000_00110000_00000000 */
    PINSEL2 = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    IO1DIR = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */

/******************************************************************************
                             Timer0 (32bit)
*******************************************************************************
   Counter Enabled,    Counter Reset=0
   Timer mode: count on rising edge of PCLK
   Counter clk: 4 KHz, Counts every: 250 us  (calculated with peripheral clock: 15MHz)
   MCR0.0 : reset, on compare match
   MAT0.0 : On compare match Toggle bit/output
*/

    PCONP = (PCONP & 0x001817BE) | (1UL<<1);    /* Enable peripheral clock for Timer0 (default is enabled) */

    T0CTCR = 0x00;     /* binary: 00000000 */
    T0TC = 0x00000000;     /* decimal 0 */
    T0PR = 0x00000EA5;     /* decimal 3749 */
    T0MCR = 0x0002;     /* binary: 00000000_00000010 */
    T0MR0 = 0x00000001;     /* decimal 1 */
    T0MR1 = 0x00000000;     /* decimal 0 */
    T0MR2 = 0x00000000;     /* decimal 0 */
    T0MR3 = 0x00000000;     /* decimal 0 */
    T0CCR = 0x0000;     /* binary: 00000000_00000000 */
    T0EMR = 0x0031;     /* binary: 00000000_00110001 */
    T0TCR = 0x01;     /* binary: 00000001 */

   while(1)
  {
  
  
   }

}

But for me i am getting 200hz even after turning on PLL in startup.s am i making any mistakes ?
 

Around 200Hz?
Are you using real hardware or simulation?
Have you changed the crystal to 12MHz from the default 10Mhz in the LPC2138 properties in proteus?

If you get 200Hz from the PIN then the core does indeed run at 12MHz

- - - Updated - - -

Do you save the startup after the change and recompile?
 

Around 200Hz?
Are you using real hardware or simulation?
Have you changed the crystal to 12MHz from the default 10Mhz in the LPC2138 properties in proteus?

If you get 200Hz from the PIN then the core does indeed run at 12MHz

- - - Updated - - -

Do you save the startup after the change and recompile?
Yes i saved the startup.s and recompiled it several times.
 

The latest uvision 4.6 cant open the file, I get an error "Can't open project fie timer.uvproj"

- - - Updated - - -

I have opened the startup.s file you have included in a text editor, the PLL is not enabled

Code:
[COLOR="#FF0000"]PLL_SETUP       EQU     0[/COLOR]
PLLCFG_Val      EQU     0x00000024

when you check the PLL checkbox in the wizard this becomes 1
 

The latest uvision 4.6 cant open the file, I get an error "Can't open project fie timer.uvproj"

- - - Updated - - -

I have opened the startup.s file you have included in a text editor, the PLL is not enabled

Code:
[COLOR="#FF0000"]PLL_SETUP       EQU     0[/COLOR]
PLLCFG_Val      EQU     0x00000024

when you check the PLL checkbox in the wizard this becomes 1

For me it is showing deselected .
startup.png
 

Also note that while the PWM is running you can't change the PWMMR values just by
Code:
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;

Read the datasheet, it explains what you have to do in order for the new value to be applied, read about PWMLER[/QUOTE]

I tried changing the PWMLER values it works but it fails to follow the conditions

Code:
#include <LPC213x.h>
#include <math.h>





void input();
void adc_ini();
void adc_data();
void calculation();
void pwm();
void motor();

unsigned long val,adc_val;
float y,s,v,m;
float angle,b;


int main(void)
{
		input();
		pwm();
		
	
			while(1)
				{
	
							adc_ini();
							adc_data();
							calculation();

							
				}

}
		



void input(void)
{
	
    PINSEL0 = 0x00028000;     /* binary: 00000000_00000010_10000000_00000000 */
    IO0DIR = 0x80000000;     /* binary: 10000000_00000000_00000000_00000000 */
    PINSEL1 = 0x01000000;     /* binary: 00000001_00000000_00000000_00000000 */
    PINSEL2 = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    IO1DIR = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */

}	


void adc_ini(void)
{

    PCONP = (PCONP & 0x001817BE) | (1UL<<12);      /* Enable peripheral clock for ADC0 (default is enabled) */
		AD0INTEN = 0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    AD0CR = 0x01200002;     /* binary: 00000001_00100000_00000000_00000010 */

}



void adc_data(void)
{
					while((AD0DR & 0x80000000)==0); //until bit 31 is high (DONE)
					val = AD0DR; //read a/d data register
					adc_val = ((val >> 6) & 0x3FF);    // Extract AD result
 } 
 
 




void calculation(void)
{
								/* angle calculation */
		
		m=(3.3/1023);/*3.3/1023 for adc conversion*/
		y=1.65;/*offset voltage */	
		s=0.8;/*sensitivity 800mv/g*/
		b=57.295;/* pi/180 for radian to degree conversion */
							
								/* formula tetha= arcsin( (vout - voffset)/sensitivity) */ 
	
		v=asin(((adc_val*m)-y)/s);
		angle=v*b;
		
                motor(); 
	
}



void pwm(void)
 {

                PCONP = (PCONP & 0x001817BE) | (1UL<<5);      /* Enable peripheral clock for PWM0 (default is enabled) */
                PWMTC = 0x00000000;     /* decimal 0 */
                PWMPR = 0x0000003B;     /* decimal 59 */
                PWMMCR = 0x00000002;     /* binary: 00000000_00000000_00000000_00000010 */
                PWMMR0 = 0x000003E8;     /* decimal 1000 */
		PWMMR2 = 0x0000004B;    
		PWMMR4 = 0x0000004B;   
		PWMPCR = 0x00001400;     /* binary: 00000000_00000000_00010100_00000000 */
                PWMTCR  = 0x09;     /* binary: 00001001 */
}



void motor(void)
{
      if(8.0>= angle <18.0)
	  {
			PWMLER = 0x0000014;
			PWMMR2 = 0x0000004C;     
			PWMMR4 = 0x0000004A;     
		}
		else
		{
			PWMLER = 0x0000014;
			PWMMR2 = 0x0000004B;     
			PWMMR4 = 0x0000004B; 	
		}
}
I changed PWMLER setting but even if the condition fails the following lines are getting executed
Code:
                if(8.0>= angle <18.0)
	           {
			PWMLER = 0x0000014;
			PWMMR2 = 0x0000004C;     
			PWMMR4 = 0x0000004A;     
		   }
 
Last edited by a moderator:

For me it is showing deselected .
View attachment 85214

But is is deselected, you said that the frequency doesn't change when you enable the PLL and I asked you to attach the code and in that PLL was not enabled, you were supposed to have it enabled in the project you have provided.

- - - Updated - - -

if(8.0>= angle <18.0)

That condition doesn't seem right to me or at least is not clear enough, use

Code:
if ((angle<=8.0) && (angle<18.0))
although it doesn't make sense, if angle is less than 8 is there any chance that it will not be less than 18 too?

Also set the PWMLER after writing the new PWMMR values
 
But is is deselected, you said that the frequency doesn't change when you enable the PLL and I asked you to attach the code and in that PLL was not enabled, you were supposed to have it enabled in the project you have provided.

- - - Updated - - -

i executed the code which you have uploaded , i tried both by enabling PLL and by disabling. PFA snapshot of that

startup1.png

- - - Updated - - -

That condition doesn't seem right to me or at least is not clear enough, use

Code:
if ((angle<=8.0) && (angle<18.0))
although it doesn't make sense, if angle is less than 8 is there any chance that it will not be less than 18 too?

Also set the PWMLER after writing the new PWMMR values

sorry the angle should be between the range of 8.0 and 18.
it should be greater than 8 and less than 18
 

Getting the same frequency with PLL on or off doesn't make sense, I'm not sure what you are doing wrong but works fine for me.
 

Getting the same frequency with PLL on or off doesn't make sense, I'm not sure what you are doing wrong but works fine for me.


even i an trying to find out the problem. are you changing the clock frequency while creating new project ?

- - - Updated - - -

But is is deselected, you said that the frequency doesn't change when you enable the PLL and I asked you to attach the code and in that PLL was not enabled, you were supposed to have it enabled in the project you have provided.

- - - Updated - - -

i executed the code which you have uploaded , i tried both by enabling PLL and by disabling. PFA snapshot of that

View attachment 85220

- - - Updated - - -



sorry the angle should be between the range of 8.0 and 18.
it should be greater than 8 and less than 18

The condition works well when i set the condition using adc value
Code:
if ((adc_val>=0x0000022B) && (adc_val<0x0000024D))
	  {
			PWMMR2 = 0x0000004C;     
			PWMMR4 = 0x0000004A;
			PWMLER = 0x0000014;
but it fails to work when i assign using angle which is calculated using formula.
Code:
      if ((angle >= 7.996409) && (angle < 18.20971))
	  {
			PWMMR2 = 0x0000004C;     
			PWMMR4 = 0x0000004A;
			PWMLER = 0x0000014;

		}
Is there any thing wrong with the above condition ?
It works great in keil when i executed and checked by step one line ,But it fails to work in proteus simulation .
 
Last edited:

The pll settings for a new project are like the ones I showed in post #16 , they give 60MHz, how can you be getting a different frequency?
 

The pll settings for a new project are like the ones I showed in post #16 , they give 60MHz, how can you be getting a different frequency?
yes that is what i am thinking . let me check with the setting again.

- - - Updated - - -

yes that is what i am thinking . let me check with the setting again.
Can you zip your file and upload it ?
 

This is a project using the default startup that gives 60MHz

still its confusing . i dont find any change in proteus output . PFA snapshot pll deselect.pngpll deselect.pngpll select.pngpll select.png

- - - Updated - - -

The condition works well when i set the condition using adc value
Code:

if ((adc_val>=0x0000022B) && (adc_val<0x0000024D))
{
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
PWMLER = 0x0000014;

but it fails to work when i assign using angle which is calculated using formula.
Code:

if ((angle >= 7.996409) && (angle < 18.20971))
{
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
PWMLER = 0x0000014;

}

Is there any thing wrong with the above condition ?
It works great in keil when i executed and checked by step one line ,But it fails to work in proteus simulation .
 

still its confusing . i dont find any change in proteus output

Are you sure you are using the correct AXF/HEX file in the simulator?
Have you tried using my AXF file from the zip file, it should give 1ms

- - - Updated - - -

It works great in keil when i executed and checked by step one line ,But it fails to work in proteus simulation .

This may be related to a wrong AXF/HEX file or there is a problem with you proteus
 

Are you sure you are using the correct AXF/HEX file in the simulator?
Have you tried using my AXF file from the zip file, it should give 1ms

- - - Updated - - -



This may be related to a wrong AXF/HEX file or there is a problem with you proteus


Your hex file works well it gives the correct output.
Will the output changes due to AXF file ?
 

The AXF and HEX were generated with the same compile, the result will be the same.
Maybe you should consider updating your uvision to the latest version
 

The AXF and HEX were generated with the same compile, the result will be the same.
Maybe you should consider updating your uvision to the latest version

I tried using your main.c as well as startup.s file by changing pll but gives the same output. but your hex file gives different output. Let me try with newer version of keil.

- - - Updated - - -

I tried using your main.c as well as startup.s file by changing pll but gives the same output. but your hex file gives different output. Let me try with newer version of keil.

Now it is working i tried to run the keil in administrator mode. . . I can see the change in the signal because the PLL setting.
Thanks
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top