Please help to find error in the code.

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Please help to find error in the code.

2,530件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sat Jun 04 11:00:17 MST 2011
I wrote this program myself to read an analog value at AD_0 pin. I am trying to implement it without using interrupt first. And print the output using console print.The compiler doesnt give any error while building. But while debugging, the program doesnt enter the 'if' condition at 36th line or even its 'else' condition. Please help me to find where the error is. Here is the code:
/*
===============================================================================
 Name        : main.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : Reading aalog value without using interrupt.
               AD0 as analog input. MCU - LPC1114
=================n==============================================================
*/

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>


__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include <stdio.h>
#include <string.h>
#include "consoleprint.h"

// AD0 as analog input.

int main(void) {
    
    LPC_SYSCON->SYSAHBCLKCTRL |= 1<<13; //Enabled clock for ADC
    LPC_IOCON->R_PIO0_11 = 0x12; //Selected ADC function for PIN 0_11 & Disabled digital input.
    LPC_ADC->CR = 0xF01; //Enabled ADC_0 and set clk division to 16.
    LPC_ADC->CR |= 1<<24; //Start conversion.
    uint32_t voltage; //Final analog voltage reading.
while (1){
    if (LPC_ADC->DR[0] & (1<<31)) //Checking whether conversion is completed.
    {
        voltage = (((LPC_ADC->DR[0]>>5) & 0x3FF) * 33)/10240; //Converting digital reading to analog value.
        printf("%s \n",&voltage); //Console printing the final value.
    }
    else printf("nothing to display \n");
}
}



[B]Edit: [/B]It executes the ELSE condition now. But still does not enter the IF condition. I have tried removing the 'console printing' and setting a breakpoint inside the IF condition.
0 件の賞賛
返信
17 返答(返信)

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Tue Jun 07 02:48:01 MST 2011
I am not trying to be sarcastic here. But pull up enabled mode is the default mode for that IOCON reg, not any random possible combination. Mentioning to disable pullup wouldnt hurt much if it will affect the accuracy of the result.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Jun 07 02:07:15 MST 2011
Reading user manuals means also reading between the lines and understanding it. So this manual told us that pull-up function has no effect in AD-mode.
Now what can we expect and what should we do?
We can expect to see no pull-up function in AD mode and therefore we should not try to select it. This function is made for digital mode and should work there as expected, but no one guarantees correct AD function with pull-up. 414 pages are not enough to describe all possible (senseless) configurations, barely enough to describe basic functions.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Mon Jun 06 09:51:45 MST 2011
But in AD Mode pull up resistors seem to have effect. When the IOCON value is set  to 0x52(pull up enabled) and the AD_0 pin grounded, the AD_0 Data register gives a value around 8. And when pull ups disabled (IOCON=0x42) and AD pin grounded, AD_0 Data register will show the correct value- '0'. I am just curious about this odd behavior. Isnt the pull resistor supposed to have no effect???
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sun Jun 05 23:44:07 MST 2011
Yes, in AD mode they have no effect, so setting them is nonsense.

An yes, 0x42 is correct setting for AD0 :)
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sun Jun 05 21:56:59 MST 2011

Quote:
If A/D mode is selected, Hysteresis and Pin mode settings have no effect.


So does it matter if I enable the pull up???? I changed the IOCON value to 0x42. Is that right???
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sun Jun 05 10:39:51 MST 2011
Don't know which user manual you are reading, my user manual describes reset value is 0xd0 :mad:

Also it describes:

Quote:

[B]7.3.4 A/D-mode[/B]
In A/D-mode, the digital receiver is disconnected to obtain an accurate input voltage for analog-to-digital conversions. This mode can be selected in those IOCON registers that control pins with an analog function. If A/D mode is selected, Hysteresis and Pin mode settings have no effect. For pins without analog functions, the A/D-mode setting has no effect.



So who is using 0x12 :confused:
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sun Jun 05 10:06:41 MST 2011

Quote: Zero
Then why do you use a pull-up?



That was the default value.I left it like that. Then why isnt AD0 pull upped when it is floating?:confused:
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sun Jun 05 09:53:22 MST 2011
OOh... its my bad.  :cool:
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Jun 04 14:27:08 MST 2011

Quote:

Why isnt that mentioned in the ADC section of the user manual???

Don't know which user manual you are reading (frying pan?), my user manual describes that in chapter Chapter 19 LPC111x/LPC11Cxx ADC:


Quote:

[B][COLOR=Black]19.2 Basic configuration[/COLOR][/B]
The ADC is configured using the following registers:
1. Pins: The ADC pin functions are configured in the IOCONFIG register block (Section 7.4).
2. Power and peripheral clock: In the SYSAHBCLKCTRL register, set bit 13 (Table 20).
[B][COLOR=Red]Power to the ADC at run-time is controlled through the PDRUNCFG register (Table 41).[/COLOR][/B]

Also NXP adc sample shows it:

/*****************************************************************************
** Function name:        ADCInit
**
** Descriptions:        initialize ADC channel
**
** parameters:            ADC clock rate
** Returned value:        None
** 
*****************************************************************************/
void ADCInit( uint32_t ADC_Clk )
{
  uint32_t i;

  /* Disable Power down bit to the ADC block. */  
  LPC_SYSCON->PDRUNCFG &= ~(0x1<<4);

  /* Enable AHB clock to the ADC. */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);

  for ( i = 0; i < ADC_NUM; i++ )
  {
    ADCValue = 0x0;
  }
  /* Unlike some other pings, for ADC test, all the pins need
  to set to analog mode. Bit 7 needs to be cleared according 
  to design team. */
  LPC_IOCON->R_PIO0_11 &= ~0x8F; /*  ADC I/O config */
  LPC_IOCON->R_PIO0_11 |= 0x02;  /* ADC IN0 */
  LPC_IOCON->R_PIO1_0  &= ~0x8F;    
  LPC_IOCON->R_PIO1_0  |= 0x02;  /* ADC IN1 */
  LPC_IOCON->R_PIO1_1  &= ~0x8F;    
  LPC_IOCON->R_PIO1_1  |= 0x02;  /* ADC IN2 */
  LPC_IOCON->R_PIO1_2 &= ~0x8F;    
  LPC_IOCON->R_PIO1_2 |= 0x02; /* ADC IN3 */
#ifdef __SWD_DISABLED
  LPC_IOCON->SWDIO_PIO1_3   &= ~0x8F;    
  LPC_IOCON->SWDIO_PIO1_3   |= 0x02;  /* ADC IN4 */
#endif
  LPC_IOCON->R_PIO0_11   = 0x02;    // Select AD0 pin function
  LPC_IOCON->R_PIO1_0    = 0x02;    // Select AD1 pin function
  LPC_IOCON->R_PIO1_1    = 0x02;    // Select AD2 pin function
  LPC_IOCON->R_PIO1_2    = 0x02;    // Select AD3 pin function
//  LPC_IOCON->ARM_SWDIO_PIO1_3    = 0x02;    // Select AD4 pin function
  LPC_IOCON->PIO1_4    = 0x01;    // Select AD5 pin function
  LPC_IOCON->PIO1_10   = 0x01;    // Select AD6 pin function
  LPC_IOCON->PIO1_11   = 0x01;    // Select AD7 pin function

  LPC_ADC->CR = ((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/ADC_Clk-1)<<8;

  /* If POLLING, no need to do the following */
#if CONFIG_ADC_ENABLE_ADC_IRQHANDLER==1
  NVIC_EnableIRQ(ADC_IRQn);
  LPC_ADC->INTEN = 0x1FF;        /* Enable all interrupts */
#endif
  return;
}
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Jun 04 13:54:06 MST 2011

Quote:

When I connect the AD0 pin to ground, it still gives a value of 8.

Then why do you use a pull-up?

 LPC_IOCON->R_PIO0_11 = 0x12; //Selected ADC function for PIN 0_11 & Disabled digital input.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sat Jun 04 13:02:24 MST 2011
How can I make it to print the actual voltage at the AD0 pin? In other words, how can I handle decimal no: with it?
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sat Jun 04 12:56:00 MST 2011
I edited that line to the following to print the data in the ADC_DATA[0] register.
 voltage = ((LPC_ADC->DR[0]>>6) & 0x3FF); 


It is working fine now... Thanks to all.

When I connect the AD0 pin to ground, it still gives a value of 8.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larryvc on Sat Jun 04 12:32:32 MST 2011
Integer math rounds down and the values you are getting divided by 10240 probably = 0.  You need to scale the value in this line of code.

       
voltage = (((LPC_ADC->DR[0]>>5) & 0x3FF) * 33)/10240; //Converting 
digital reading to analog value.

The code below is returning between 32424 and 33706 with just my finger on the pin.

 
voltage = (((LPC_ADC->DR[0]>>5) & 0x3FF) * 33)


Divide that by 10240 and I get 3.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Sat Jun 04 12:19:55 MST 2011
That worked, Zero... Why isnt that mentioned in the ADC section of the user manual???

I am still not getting the right output. It is just printing '0' whatever the input is at AD_0 pin.
Here is my updated code:

/*
===============================================================================
 Name        : main.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : Reading analog value without using interrupt.
               AD0 as analog input. MCU - LPC1114
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>


__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include <stdio.h>
#include <string.h>
#include "consoleprint.h"

// AD0 as analog input.

int main(void) {
    
    LPC_SYSCON->SYSAHBCLKCTRL |= 1<<13; //Enabled clock for ADC
    LPC_SYSCON->PDRUNCFG &= ~(1<<4); //Disable power down for ADC
    LPC_IOCON->R_PIO0_11 = 0x12; //Selected ADC function for PIN 0_11 & Disabled digital input.
    LPC_ADC->CR = 0xF01; //Enabled ADC_0 and set clk division to 16.
    LPC_ADC->CR |= 1<<24; //Start conversion.
    uint32_t voltage; //Final analog voltage reading.
    
while (1){
    if (LPC_ADC->DR[0] & (1<<31)) //Checking whether conversion is completed.
    {
        voltage = (((LPC_ADC->DR[0]>>5) & 0x3FF) * 33)/10240; //Converting digital reading to analog value.
        printf("%d \n",voltage); //Console printing the final value.
        LPC_ADC->CR |= 1<<24; //Start conversion.
    }
    
}
}

0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larryvc on Sat Jun 04 12:05:47 MST 2011
For your program, if you are using semihosting you don't need string.h or consoleprint.h.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larryvc on Sat Jun 04 11:47:37 MST 2011
And what does this do?

       
printf("%s \n",&voltage); //Console printing the final value.


The final value of what?

Also maybe %d instead of %s.
0 件の賞賛
返信

2,439件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat Jun 04 11:38:41 MST 2011
Perhaps debugger is confused that you are trying to work with ADC in Power Down :eek:

First I would suggest to disable power down:

    LPC_SYSCON->PDRUNCFG &= ~(0x1 << 4);    //disable Power down ADC
0 件の賞賛
返信