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.

[SOLVED] LPC23xx ADC programming

Status
Not open for further replies.

bikashh

Full Member level 5
Joined
Nov 28, 2009
Messages
264
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
india
Activity points
3,132
Dear Friends, i am trying to configure my LPC2368 ADC but getting zero output for all value. For testing purpose i am feeding voltage(0 to 3.3v) to ADC from a voltage divider. Please let me know for any correction in the below code.The mode i am using is software controlled.thanks in advance.

void ADCInit(void)
{
/* Enable CLOCK into ADC controller */
PCONP |= (1 << 12); /* all the related pins are set to ADC inputs, AD0.0~7 */
PINSEL0 = PINSEL0 & 0xFFFF7FFF; //ADC0 p0.23,bit 15(0),14(1)-> 1111 1111 1111 1111 0111 1111 1111 1111
AD0CR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */
( ((Fpclk /4000000UL) - 1) << 8 ) | /* CLKDIV = Fpclk / 1000000 - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0; A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
AD0INTEN = 0x01; /* Enable AD0 interrupt*/
}

int ADC0Read(void)
{
DWORD ADC_Data=0;
DWORD ADCReg=0;
AD0CR &= 0xFFFFFF00; /* switch channel,start A/D convert */

AD0CR |= (1 << 24) | (1 << 0);
do
{
ADCReg = AD0DR0; // Read A/D Data Register
} while ((ADCReg & 0x80000000) == 0); // Wait for end of A/D Conversion
AD0CR = 0x00000000;
ADC_Data = (( ADCReg & 0x0000FFC0 ) >> 6);
return (ADC_Data); /* return A/D conversion value */
}

/*MAIN PROGRAM*/
main( )
{
int result=0;
Init_UART0(9600);
InitTimer();
uart0Puts("Initialized OK \n\r");
ADCInit();
while(1)
{
result = ADC0Read();
uart0Puts("ADC OUTPUT->");
uart0Puts((char*)itoa(result));
uart0Puts("\n\r");
delay_ms(2000);
}
}
 

Code:
#include "LPC23xx.h"
#define  LED1       0x02000000          // P3.25(0000 00x0 0000 0000 0000 0000 0000 0000)
#define  LED2       0x04000000          // P3.26(0000 0x00 0000 0000 0000 0000 0000 0000)
#define  LED1_ON()  FIO3CLR = LED1          // LED1 Pin = 0 (ON LED) http://www.etteam.com
#define  LED1_OFF() FIO3SET = LED1       // LED1 Pin = 1 (OFF LED)
#define  LED2_ON()  FIO3CLR = LED2       // LED2 Pin = 0 (ON LED)
#define  LED2_OFF() FIO3SET = LED2       // LED2 Pin = 1 (OFF LED)

void delay_ms(long int ms);
void delay_us();



int main(void)
{
  unsigned short table_sine[64]={
  0x07FF, 0x08C8, 0x098E, 0x0A51,
  0x0B0F, 0x0BC4, 0x0C71, 0x0D12,
  0x0DA7, 0x0E2E, 0x0EA5, 0x0F0D,
  0x0F63, 0x0FA6, 0x0FD7, 0x0FF5,
  0x0FFF, 0x0FF5, 0x0FD7, 0x0FA6,
  0x0F63, 0x0F0D, 0x0EA5, 0x0E2E,
  0x0DA7, 0x0D12, 0x0C71, 0x0BC4,
  0x0B0F, 0x0A51, 0x098E, 0x08C8,
  0x07FF, 0x0736, 0x0670, 0x05AD,
  0x04EF, 0x043A, 0x038D, 0x02EC,
  0x0257, 0x01D0, 0x0159, 0x00F1,
  0x009B, 0x0058, 0x0027, 0x0009,
  0x0000, 0x0009, 0x0027, 0x0058,
  0x009B, 0x00F1, 0x0159, 0x01D0,
  0x0257, 0x02EC, 0x038D, 0x043A,
  0x04EF, 0x05AD, 0x0670, 0x0736};


  int i,j,k,l;
  int count;
  unsigned int value,value1,value2;


PCONP &=0xFFF81FFF;              //Set up power/clock control bit manual
PCONP |=0x00081000;
PCLKSEL0 = 0x03000000;    // Set bit 25:24='11' for the periphiral clock of ADC. This is fastest conversion.
AD0CR = 0x012B0001;    // bit 31:28=0, EDGE-bit 27=0, Start-bit 26:24=001, 23:22=00, 21=1, 20=0, 16=0, CLKDIV(4)=0x04, SEL=0x01   
PINSEL1 = 0x00004000;

PINSEL7  &= 0xFFC3FFFF;    // P3[26:25] = GPIO Function(xxxx xxxx xx00 00xx xxxx xxxx xxxx xxxx)
PINMODE7 &= 0xFFC3FFFF;   // Enable Puul-Up on P3[26:25]
FIO3DIR  |= LED1;      // Set GPIO-3[26:25] = Output(xxxx x11x xxxx xxxx xxxx xxxx xxxx xxxx)
FIO3DIR  |= LED2;

// Config DAC
PCLKSEL0  |=0x00400000;  //Enable peripheral clock DAC
PINSEL1  |=0x00200000;  //Set P0.23 Turn to ADC
PINMODE1  |=0x00200000;

// Set port 4 as input for put botton switch P4.28 and P4.29.
PINSEL9 = 0x00000000;
LED1_ON();  /*http://etteam.com*/
LED2_ON(); 
k=0;
l=0;
while(1)
{
  do
  {
   value=AD0DR0;
  }
  while((value & 0x80000000) == 0);
  value=(value>>6) & 0x03FF;
  for (j=0;j<=value;j++)
  {
  delay_us();
  }
 DACR = (table_sine[i]<<4);
 i++;
 i &= 0x3F;

 if(((FIO4PIN & 0x10000000) == 0)&&(k==0))
 {
 LED1_OFF();
 delay_ms(200);
 LED1_ON();
 value1=value;
 k=1;
 }
 else if (((FIO4PIN & 0x10000000)==0)&&(k==1)&&(l==0))
 {
 LED2_OFF();
 delay_ms(200);
 LED2_ON();
 value2=value;
 l==1;
 }
 else if ((FIO4PIN & 0x20000000) == 0)
 {
 LED1_OFF();
 LED2_OFF();
 delay_ms(200);
 LED1_ON();
 LED2_ON();

 while(1)
 {
 
 for (count=0;count<=5;count++)
 {
  for (i=0;i<=63;i++)
  {
   DACR = (table_sine[i]<<4);
    for (j=0;j<=value1;j++)
    {
    delay_us();
    }
  }
 }

 for (count=0;count<=5;count++)
 {
  for (i=0;i<=63;i++)
  {
   DACR = (table_sine[i]<<4);
    for (j=0;j<=value2;j++)
    {
    delay_us();
    }
  }
 }
 }
 }
}
}

void delay_ms(long int ms)
{
long int i,j;
for(i=0;i<ms;i++)
for(j=0;j<3999;j++);
}

void delay_us()
{
return;
}
 
do i need to convert the binary result into decimal

thanks for the reply
 

you have to if you are displaying on LCD, or else you can do in a simple way if printing on uart1....

Read_AdcData(&data[0]);
value = data[0];
printf("output=%d\n",value);
 

dear sir,
from the above code
value=(value>>6) & 0x03FF;

I am confused about what type of data the final "value" contains

thanks for the reply
 

read the data sheet. they have told why we do &0x3fff. the data is shifted because the data register stores data from 6th bit to 15 but we need data from 0th bit..

check the sample code you get when you install keil......
 
yes i got it.
suppose Vref=3.3v and i get 1111111111 as a output

first i'll have to convert 1111111111 to decimal and
than Vref /decimal value will give result in mv.

eg.3.3/1023=0.00322v

if i am wrong please correct me.

thanks
 

dear sir,
i've written a program according to my understanding please check

while((AD0DR0 & 0x80000000)==0); //wait till DONE flag is set
ADC_Data = ( regVal >> 6 ) & 0x3FF; //extract data
for(i=10;i<=0;)
{
binary_data = (ADC_Data1 = (ADC_Data%10));
ADC_Data = ADC_Data1;
i--;
}
binary_data[11]='\0';
 

dear sir,
i've written a program according to my understanding please check

Code C - [expand]
1
2
3
4
5
6
7
8
9
while((AD0DR0 & 0x80000000)==0); //wait till DONE flag is set
ADC_Data = ( regVal >> 6 ) & 0x3FF; //extract data
for(i=10;i<=0;)
{
binary_data[i] = (ADC_Data1 = (ADC_Data%10));
ADC_Data = ADC_Data1;
i--;
}
binary_data[11]='\0';


What are you trying to do in your code?

If I understand correctly you want to convert the result which is 0-1023 to a BCD format, for example 512 to 0,5,1,2 each in one position of binary_data, is this what you want?
Why do you use so many digits, i see binary_data[11] so you have an array of 12 char (i assume).

Alex

---------- Post added at 13:22 ---------- Previous post was at 13:11 ----------

for(i=10;i<=0;) is wrong, you have to write the starting value i=10, then the condition in order to continue if true i<=0 and the increment/decrement expression i++ or i--

also the null is not always defined as '\0', you can always use the value 0 which is the same thing, binary_data[11]=0;

Alex
 

dear sir,
LPC2368 ADC is having 10 bit resolution for a Vref=3.3v,Step size=0.00322v
so for example, for 3v input, the decimal value would be 3/0.00322 = 931
but in the register "AD0DR0"( bit 6 to bit 15)the equivalent value would be 11 1010 0011.
in the above code i am trying to extract this binary result


in the above code->correct
for(i=10;i>=0;)

thanks for the reply
 

Try this, it should work


Code C - [expand]
1
2
3
4
5
6
for(i=0;i<=9;i++)
{
    binary_data[i] = ((ADC_Data>>(9-i)) & 1)+48  // move the bit you want to bit0, use and with 1 to read only that and add 48 to convert 0 to '0' and 1 to '1'
    
}
binary_data[10]=0;



this stores bit9 of the result to binary_data[0]
this stores bit8 of the result to binary_data[1]
...
this stores bit0 of the result to binary_data[9]
and binary_data[10] will be nul
The result will be stored as ascii char representation '0' or '1' and not 0 or 1 because 0 will be nul in that case

Alex

---------- Post added at 14:08 ---------- Previous post was at 14:03 ----------

bikashh; said:
in the above code->correct
for(i=10;i>=0;)

I have never tried to use "for" this way but even if the compiler is ok with it what is the point of using a "for" when you are actually implementing a "while" loop, just write a "while" if this is what you want.

Alex
 
dear friend thanks a lot for the logic and it worked also now i am able to see the binary data on terminal. but its giving same output for all the input voltages(0-3.3v)

thanks again
 

Can you post your code?

Alex

---------- Post added at 15:58 ---------- Previous post was at 15:45 ----------

I have tried this code in the keil debugger and works fine


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
volatile unsigned int i,ADC_Data;
volatile unsigned char binary_data[11];
 
/*   
    P0.23:  AD0.0 (A/D converter 0 input 0), pull-up resistor enabled   
*/
    PINSEL1=0x00004000;
 
/******************************************************************************
                                ADC0
*******************************************************************************
   ADC operational
   ADC clk: 3,75 MHz  (calculated with peripheral clock: 15MHz)
   ADC rate: 340,9091 Ksamples/sec
   manual mode, 11 clocks / 10 bit accuracy
   Start conversion now.
   Channel 0 enabled, no interrupt
   Channel 1 dissabled, no interrupt
   Channel 2 dissabled, no interrupt
   Channel 3 dissabled, no interrupt
   Channel 4 dissabled, no interrupt
   Channel 5 dissabled, no interrupt
   Channel 6 dissabled, no interrupt
   Channel 7 dissabled, no interrupt
*/
 
PCONP |= 0x1000;      /* Enable peripheral clock for ADC (default is disabled) */
AD0CR=0x01200301;     /* binary: 00000001_00100000_00000011_00000001 */
AD0INTEN=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
 
while((AD0DR0 & 0x80000000)==0); //wait till DONE flag is set
ADC_Data = ( AD0DR0 >> 6 ) & 0x3FF; //extract data
 
for(i=0;i<=9;i++)
{
    binary_data[i] = ((ADC_Data>>(9-i)) & 1)+48;  // move the bit you want to bit0, use and with 1 to read only that and add 48 to convert 0 to '0' and 1 to '1'
    
}
binary_data[10]=0;
 
   while(1)
  {
  
  
   }
 
}



Alex
 

below is my code

void ADCInit(void)
{
/* Enable CLOCK into ADC controller */
PCONP |= (1 << 12);

/* all the related pins are set to ADC inputs, AD0.0~7 */


PINSEL1 &= ~0x003FC000; /* P0.23~26, A0.0~3, function 01 */
PINSEL1 |= 0x00004000; //select AD0.0


AD0CR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */
( ( 12000000 / 1000000 - 1 ) << 8 ) | /* CLKDIV = Fpclk / 1000000 - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
}


void ADC0Read( char channelNum )
{

DWORD regVal, ADC_Data;//, ADC_Data1;
int i;
unsigned char binary_data[12];
AD0CR &= 0xFFFFFFFE;
AD0CR |= (1 << 24) | (1 << channelNum);
/* switch channel,start A/D convert */
for(i=0;i<13;i++)
{binary_data='\0';}

while((AD0DR0 & 0x80000000)==0);
AD0CR &= 0xF8FFFFFF; /* stop ADC now */
ADC_Data = ( regVal >> 6 ) & 0x3FF;

for(i=0;i<=9;i++)
{
binary_data = ((ADC_Data>>(9-i)) & 1)+48; // move the bit you want to bit0, use and with 1 to read only that and add 48 to convert 0 to '0' and 1 to '1'
}
binary_data[10]=0;

uart0Puts("ADC BINARY DATA");
uart0Puts((char*)binary_data); /* return A/D conversion value */
uart0Puts("\n\r");
}

main()
{
Init_UART0(9600);
InitTimer();
while(1)
{
ADC0Read(0);
delay_ms(2000);
}

}
 

You forgot to initalize the ADC

main()
{
Init_UART0(9600);
ADCInit(); // <<<< this line was missing
InitTimer();

while(1)
{
ADC0Read(0);
delay_ms(2000);
}

Alex
 
Last edited:

Yes there is a function but in your code you never call it, the bold line was added by me/

your code was this and there was no ADCInit();
Code:
]
main()
{
Init_UART0(9600);
InitTimer();
while(1)
{
ADC0Read(0);
delay_ms(2000);
}

Alex
 

dear friend,
Yes i include ADCinit() in my program but the result is still the same.

thankyou
 

It did work fine when I tried in uvision, have you tried with a debugger?
If you are trying with a real circuit check that the power supply and reference voltage are correct.

The code I have tried is this

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <LPC23xx.H>
 
void ADCInit(void)
{
/* Enable CLOCK into ADC controller */
PCONP |= (1 << 12);
 
/* all the related pins are set to ADC inputs, AD0.0~7 */
 
 
PINSEL1 &= ~0x003FC000; /* P0.23~26, A0.0~3, function 01 */
PINSEL1 |= 0x00004000; //select AD0.0
 
 
AD0CR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */
( ( 12000000 / 1000000 - 1 ) << 8 ) | /* CLKDIV = Fpclk / 1000000 - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */
( 0 << 22 ) | /* TEST1:0 = 00 */
( 0 << 24 ) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
}
 
 
void ADC0Read( char channelNum )
{
 
volatile unsigned int regVal, ADC_Data;//, ADC_Data1;
int i;
volatile unsigned char binary_data[12];
AD0CR &= 0xFFFFFFFE;
AD0CR |= (1 << 24) | (1 << channelNum);
/* switch channel,start A/D convert */
for(i=0;i<13;i++)
{binary_data[i]='\0';}
 
while((AD0DR0 & 0x80000000)==0);
AD0CR &= 0xF8FFFFFF; /* stop ADC now */
ADC_Data = ( regVal >> 6 ) & 0x3FF;
 
for(i=0;i<=9;i++)
{
binary_data[i] = ((ADC_Data>>(9-i)) & 1)+48; // move the bit you want to bit0, use and with 1 to read only that and add 48 to convert 0 to '0' and 1 to '1'
}
binary_data[10]=0;
 
//uart0Puts("ADC BINARY DATA");
//uart0Puts((char*)binary_data); /* return A/D conversion value */
//uart0Puts("\n\r");
}
 
main()
{
//Init_UART0(9600);
ADCInit();
//InitTimer();
while(1)
{
ADC0Read(0);
//delay_ms(2000);
}
 
}



Alex
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top