kodi.sudar
Member level 5
- Joined
- Dec 21, 2009
- Messages
- 92
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,286
- Location
- india
- Activity points
- 1,849
You should post your code so we can see what you are doing.
Also provide the clock info.
A schematic would also be nice
/************************************************************************************
Code created using the ARMwizard, visit http://alexan.edaboard.eu
************************************************************************************/
#include <LPC213x.h>
int main(void)
{
/*
P0.0: PORT0.0 (General purpose I/O) Input
P0.1: PORT0.1 (General purpose I/O) Input
P0.2: PORT0.2 (General purpose I/open-drain O) Input
P0.3: PORT0.3 (General purpose I/open-drain O) Input
P0.4: PORT0.4 (General purpose I/O) Input
P0.5: PORT0.5 (General purpose I/O) Input
P0.6: PORT0.6 (General purpose I/O) Input
P0.7: PWM2 (Pulse Width Modulator output 2)
P0.8: PORT0.8 (General purpose I/O) Input
P0.9: PORT0.9 (General purpose I/O) Input
P0.10: PORT0.10 (General purpose I/O) Input
P0.11: PORT0.11 (General purpose I/O) Input
P0.12: PORT0.12 (General purpose I/O) Input
P0.13: PORT0.13 (General purpose I/O) Input
P0.14: PORT0.14 (General purpose I/O) Input
P0.15: PORT0.15 (General purpose I/O) Input
P0.16: PORT0.16 (General purpose I/O) Input
P0.17: PORT0.17 (General purpose I/O) Input
P0.18: PORT0.18 (General purpose I/O) Input
P0.19: PORT0.19 (General purpose I/O) Input
P0.20: PORT0.20 (General purpose I/O) Input
P0.21: PORT0.21 (General purpose I/O) Input
P0.22: PORT0.22 (General purpose I/O) Input
P0.23: PORT0.23 (General purpose I/O) Input
P0.25: PORT0.25 (General purpose I/O) Input
P0.26: PORT0.26 (General purpose I/O) Input
P0.27: PORT0.27 (General purpose I/O) Input
P0.28: PORT0.28 (General purpose I/O) Input
P0.29: PORT0.29 (General purpose I/O) Input
P0.30: PORT0.30 (General purpose I/O) Input
P0.31: PORT0.31 (General purpose O) Output
P1.16: PORT1.16 (General purpose I/O) Input
P1.17: PORT1.17 (General purpose I/O) Input
P1.18: PORT1.18 (General purpose I/O) Input
P1.19: PORT1.19 (General purpose I/O) Input
P1.20: PORT1.20 (General purpose I/O) Input
P1.21: PORT1.21 (General purpose I/O) Input
P1.22: PORT1.22 (General purpose I/O) Input
P1.23: PORT1.23 (General purpose I/O) Input
P1.24: PORT1.24 (General purpose I/O) Input
P1.25: POR11.25 (General purpose I/O) Input
P1.26: PORT1.26 (General purpose I/O) Input
P1.27: PORT1.27 (General purpose I/O) Input
P1.28: PORT1.28 (General purpose I/O) Input
P1.29: PORT1.29 (General purpose I/O) Input
P1.30: PORT1.30 (General purpose I/O) Input
P1.31: PORT1.31 (General purpose I/O) Input
*/
PINSEL0 = 0x00008000; /* binary: 00000000_00000000_10000000_00000000 */
IO0DIR = 0x80000000; /* binary: 10000000_00000000_00000000_00000000 */
PINSEL1 = 0x00000000; /* binary: 00000000_00000000_00000000_00000000 */
PINSEL2 = 0x00000000; /* binary: 00000000_00000000_00000000_00000000 */
IO1DIR = 0x00000000; /* binary: 00000000_00000000_00000000_00000000 */
/******************************************************************************
PWM
*******************************************************************************
Counter Disabled, Counter Reset=0, PWM mode enabled
Counter clk: 500 Hz, Counts every: 2 ms (calculated with peripheral clock: 3MHz)
MCR0.0 : reset, on compare match
MCR0.1 : reset, on compare match
MCR0.2 : reset, on compare match
PWM frequency: 50 Hz
PWM1: Single edge, set by MR0, reset by MR1, output disabled
PWM2: Double edge, set by MR1, reset by MR2, output enabled
PWM3: Single edge, set by MR0, reset by MR3, output disabled
PWM4: Single edge, set by MR0, reset by MR4, output disabled
PWM5: Single edge, set by MR0, reset by MR5, output disabled
PWM6: Single edge, set by MR0, reset by MR6, output disabled
*/
PCONP = (PCONP & 0x001817BE) | (1UL<<5); /* Enable peripheral clock for PWM0 (default is enabled) */
PWMTC = 0x00000000; /* decimal 0 */
PWMPR = 0x0000176F; /* decimal 5999 */
PWMMCR = 0x00000092; /* binary: 00000000_00000000_00000000_10010010 */
PWMMR0 = 0x0000000A; /* decimal 10 */
PWMMR1 = 0x00000001; /* decimal 1 */
PWMMR2 = 0x00000003; /* decimal 3 */
PWMMR3 = 0x00000000; /* decimal 0 */
PWMMR4 = 0x00000000; /* decimal 0 */
PWMMR5 = 0x00000000; /* decimal 0 */
PWMMR6 = 0x00000000; /* decimal 0 */
PWMPCR = 0x00000404; /* binary: 00000000_00000000_00000100_00000100 */
PWMTCR = 0x08; /* binary: 00001000 */
while(1)
{
}
}
/******************************************************************************
PWM
*******************************************************************************
Counter Enabled, Counter Reset=0, PWM mode enabled
Counter clk: 51,1945 KHz, Counts every: 19,53 us (calculated with peripheral clock: 15MHz)
MCR0.0 : reset, on compare match
PWM frequency: 50,0435 Hz
PWM1: Single edge, set by MR0, reset by MR1, output disabled
PWM2: Single edge, set by MR0, reset by MR2, output enabled
PWM3: Single edge, set by MR0, reset by MR3, output disabled
PWM4: Single edge, set by MR0, reset by MR4, output disabled
PWM5: Single edge, set by MR0, reset by MR5, output disabled
PWM6: Single edge, set by MR0, reset by MR6, output disabled
*/
PCONP = (PCONP & 0x001817BE) | (1UL<<5); /* Enable peripheral clock for PWM0 (default is enabled) */
PWMTC = 0x00000000; /* decimal 0 */
PWMPR = 0x00000124; /* decimal 292 */
PWMMCR = 0x00000002; /* binary: 00000000_00000000_00000000_00000010 */
PWMMR0 = 0x000003FF; /* decimal 1023 */
PWMMR1 = 0x00000000; /* decimal 0 */
PWMMR2 = 0x00000034; /* decimal 52 gives about 1ms pulse*/
PWMMR3 = 0x00000000; /* decimal 0 */
PWMMR4 = 0x00000000; /* decimal 0 */
PWMMR5 = 0x00000000; /* decimal 0 */
PWMMR6 = 0x00000000; /* decimal 0 */
PWMPCR = 0x00000400; /* binary: 00000000_00000000_00000100_00000000 */
PWMTCR = 0x09; /* binary: 00001001 */
You have used peripheral clock: 3MHz , what is the core clock frequency?
The problem I see is that you are using a 20ms PWM with a 30% duty which is 6ms but usually servos need a pulse between 1-2ms
Anyway, this is an example with 60MHz cpu clock and 1/4 for PCLK
Code:/****************************************************************************** PWM ******************************************************************************* Counter Enabled, Counter Reset=0, PWM mode enabled Counter clk: 51,1945 KHz, Counts every: 19,53 us (calculated with peripheral clock: 15MHz) MCR0.0 : reset, on compare match PWM frequency: 50,0435 Hz PWM1: Single edge, set by MR0, reset by MR1, output disabled PWM2: Single edge, set by MR0, reset by MR2, output enabled PWM3: Single edge, set by MR0, reset by MR3, output disabled PWM4: Single edge, set by MR0, reset by MR4, output disabled PWM5: Single edge, set by MR0, reset by MR5, output disabled PWM6: Single edge, set by MR0, reset by MR6, output disabled */ PCONP = (PCONP & 0x001817BE) | (1UL<<5); /* Enable peripheral clock for PWM0 (default is enabled) */ PWMTC = 0x00000000; /* decimal 0 */ PWMPR = 0x00000124; /* decimal 292 */ PWMMCR = 0x00000002; /* binary: 00000000_00000000_00000000_00000010 */ PWMMR0 = 0x000003FF; /* decimal 1023 */ PWMMR1 = 0x00000000; /* decimal 0 */ PWMMR2 = 0x00000034; /* decimal 52 gives about 1ms pulse*/ PWMMR3 = 0x00000000; /* decimal 0 */ PWMMR4 = 0x00000000; /* decimal 0 */ PWMMR5 = 0x00000000; /* decimal 0 */ PWMMR6 = 0x00000000; /* decimal 0 */ PWMPCR = 0x00000400; /* binary: 00000000_00000000_00000100_00000000 */ PWMTCR = 0x09; /* binary: 00001001 */
The usable range to get 1ms-2ms pulses is about 52-102 (PWMMR2 value) but you can increase the usable range using higher PWMMR0 values (and lower PWMPR to maintain the 500HZ PWM period)
I'm not sure what you mean by speed control, the servo rotates to different position according to a pulse width between 1ms and 2ms.
What kind of servo do you have, what are the specs?
You can use multiple PWM channels , I don't see a problem in that.
But my code did that.
Post your code and tell me what is the core frequency and what divider you have for the PCLK
#include <LPC213x.h>
void adc_ini();
void adc_data();
void pwm();
void motor();
unsigned long val,adc_val;
float y,s,v,m;
unsigned long angle,b;
int main(void)
{
while(1)
{
adc_ini();
adc_data();
pwm();
//motor();
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 */
/* 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;
}
}
void adc_ini(void)
{
/******************************************************************************
ADC0
*******************************************************************************
ADC operational
ADC clk: 3 MHz (calculated with peripheral clock: 3MHz)
ADC rate: 272.7273 Ksamples/sec
Manual mode, 11 clocks / 10 bit accuracy
Start conversion now.
*/
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)
{
//AD0CR |= 0x01000000; /* Start A/D Conversion */
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 pwm(void)
{
/******************************************************************************
PWM
*******************************************************************************
Counter Enabled, Counter Reset=0, PWM mode enabled
Counter clk: 50 KHz, Counts every: 20 us (calculated with peripheral clock: 3MHz)
MCR0.0 : reset, on compare match
PWM frequency: 50 Hz
*/
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 */
PWMPCR = 0x00001400; /* binary: 00000000_00000000_00010100_00000000 */
PWMTCR = 0x09; /* binary: 00001001 */
motor();
}
void motor(void)
{
if(angle > 10)
{
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
}
}
PWMMR2 = 0x0000004C;
PWMMR4 = 0x0000004A;
for the third time, what is you core clock frequency and what is your pclk divider?
- - - Updated - - -
The code inside a while loop is constantly repeated, what is the reason for having the ADC initialization, pwm initialization and port initialization repeated over and over again thousands of times?
- - - Updated - - -
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
I have no idea what you mean, all I see is a constantly repeated code which includes the initialization.I am repeating the code inside the while loop only then it process the adc data in real time or else it just convert the data only at one instance .
I doubt that your clock is 12MHz, are you not using the PLL?
What is your crystal frequency and what is your PSEL and MSEL value in PLLCFG?
I have no idea what you mean, all I see is a constantly repeated code which includes the initialization.
You also didn't comment on what I said about PWMMR, your code will never work unless you fix that.
If the crystal frequency is 12MHz then that is not the same as the core clock.
The default values in startup.s result to 60MHz core clock , have you changed them?
If you use a wrong core clock then all calculation will be wrong and frequencies will be 5 times slower
On-chip integrated oscillator operates with external crystal in range of 1 MHz to 25 MHz.
The oscillator output frequency is called foscand the ARM processor clock frequency is
referred to as CCLK for purposes of rate equations, etc. foscand CCLK are the same
value unless the PLL is running and connected. Refer to Section 6.19.2 “PLL”for
additional information.
If the crystal frequency is 12MHz then that is not the same as the core clock.
The default values in startup.s result to 60MHz core clock , have you changed them?
If you use a wrong core clock then all calculation will be wrong and frequencies will be 5 times slower
On-chip integrated oscillator operates with external crystal in range of 1 MHz to 25 MHz.
The oscillator output frequency is called foscand the ARM processor clock frequency is
referred to as CCLK for purposes of rate equations, etc. foscand CCLK are the same
value unless the PLL is running and connected. Refer to Section 6.19.2 “PLL”for
additional information.
FOSC the frequency from the crystal oscillator/external oscillator
CCLK the PLL output frequency (also the processor clock frequency)
M PLL Multiplier value from the MSEL bits in the PLLCFG register
CCLK = M × FOSC
When you create a new uvision project then the default PLL settings are
View attachment 85199
The core frequency is calculated using the following equation (refer to section 4.8.9 PLL frequency calculation in the LPC213x user manual)
MSEL=5 and the crystal is 12MHz so CCLK = 5 * 12MHz =60MHz
Why do you want to run the mcu at a low frequency?
A faster clock will execute the code faster and the timers can be set accordingly.
- - - Updated - - -
Actually I have never disabled the PLL so you have to check the datasheet.
Why do you want to run the mcu at a low frequency?
A faster clock will execute the code faster and the timers can be set accordingly.
- - - Updated - - -
Actually I have never disabled the PLL so you have to check the datasheet.
#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)
{
}
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?