CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

External adc 1110 with pic18f4550
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

External adc 1110 with pic18f4550
PostPosted: Sun Aug 31, 2008 12:45 pm     Reply with quote

I have a problem. The external adc only reads the first value and shows in lcd, and the next ones are zero. I'm using spi. The code is below:

Code:
unsigned char valorADC;
unsigned char RB2;
unsigned char RB3;     
unsigned char MSB;
unsigned char controlo;

unsigned char SPI_adc_externo(unsigned char controlo)
{
   setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);
   //setup_spi(SPI_master | SPI_H_TO_L | SPI_CLK_DIV_4);
   
   delay_ms(50);
   output_low(CS_ADC);
   delay_ms(50);
   spi_write(controlo);
   //delay_ms(50);
   RB2=spi_read();         /*guarda os 1ºs 8 bits*/
   //delay_ms(50);
   RB3=spi_read();         /*guarda os 2ºs 8 bits*/ // adc recebe o byte respectivo para o pin a ler
   //delay_us(25);
   RB3=RB3>>6;
   MSB=RB2;
   MSB=MSB<<2;
   delay_ms(50);
   output_high(CS_ADC);                                                         
   return (MSB||RB3);
}

void show_adc_lcd(unsigned char valorADC)
{
//-------------- teste para ver o valor recebido do adc ----------------*/
   lcd_linha(2);
   sprintf(string,"Valor %x",valorADC);
   lcd_string();
   delay_ms(2000);
   lcd_clear();
//----------------------------------------------------------------------*/


}

void controlo_adc_externo()
{

// controlo do adc, quando C/S=0, Dout activo
     
// unsigned char valor_recebido;
     
      unsigned char ch0, ch1,ch2,ch3,ch4,ch5,ch6,ch7;
      ch0=0x8E;
      ch1=0xCE;
      ch2=0x9E;
      ch3=0xDE;
      ch4=0xAE;
      ch5=0xEE;
      ch6=0xBE;
      ch7=0xFE;
     
      //*
      controlo=ch0;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      //*/
      controlo=ch1;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
      //*
      controlo=ch2;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      controlo=ch3;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      controlo=ch4;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      controlo=ch5;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      controlo=ch6;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
     
      controlo=ch7;
      valorADC=SPI_adc_externo(controlo);
      delay_ms(1000);
      show_adc_lcd(valorADC);
      delay_ms(100);
       
}




I need some help with this. I need boot, internal and external adc working, thanks!!
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sun Aug 31, 2008 1:08 pm     Reply with quote

Quote:
Code:
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);


You only need to do this once, not every time you read the ADC. Wont do any harm though.

Quote:
Code:
return (MSB||RB3);


Think you meant single |, your code is a logical OR
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

Re: External adc 1110 with pic18f4550
PostPosted: Sun Aug 31, 2008 4:04 pm     Reply with quote

Tk´s for the help, but the problem still remains,
i don´t know to solve it, i´ve tried many different things but the LCD only display 1 ADC channel, the other channels values are zero always. and the circuit is well done:S
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 4:19 pm     Reply with quote

If you want help, you need to post a link to the ADC data sheet.
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 4:24 pm     Reply with quote

PCM programmer wrote:
If you want help, you need to post a link to the ADC data sheet.


http://pdfserv.maxim-ic.com/en/ds/1676.pdf

here it is, max1110, 8 channel Analog inputs! Tk´s
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 4:40 pm     Reply with quote

Quote:
setup_spi(SPI_MASTER|SPI_H_TO_L | SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);

You have setup the SPI to use Mode 3. But the MAX1110 data sheet
shows that it uses Mode 0. This is clearly shown in Figure 7 (on page 12)
of the MAX1110 data sheet. Here is a drawing of the SPI modes:
http://www.totalphase.com/support/kb/10045/#modes
Here are the #defines for the SPI modes. Use Mode 0:
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)


Quote:
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);

You are using an SPI clock divisor of 4. Even if you are using a low
crystal frequency of 4 MHz, this divisor would give you a SCLK frequency
of 1 MHz. But on page 3 of the MAX1110 data sheet, it says the
maximum SCLK frequency is 500 KHz. You didn't say what your
crystal frequency is, but it's certain that you need to increase the divisor
value in the setup_spi() statement.


Quote:
delay_ms(50);
output_low(CS_ADC);
delay_ms(50);
spi_write(controlo);
//delay_ms(50);
RB2=spi_read(); /*guarda os 1ºs 8 bits*/
//delay_ms(50);
RB3=spi_read(); /*guarda os 2ºs 8 bits*/ // adc recebe o byte respectivo para o pin a ler
//delay_us(25);
RB3=RB3>>6;
MSB=RB2;
MSB=MSB<<2;
delay_ms(50);
output_high(CS_ADC);
return (MSB||RB3);

This code will not generate the SCLK signal. To fix it, you need to
add a 0 parameter to the spi_read() statements. Example:
Code:
RB2=spi_read(0);

RB3=spi_read(0); 
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 4:58 pm     Reply with quote

the crystal on the pic is 20MHz, and it`s really slave or master for the external adc?since i have one external rtc also master!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 5:06 pm     Reply with quote

Quote:
the crystal on the pic is 20MHz,

You need to use a divisor of 64. It will give an SCLK frequency of
20 MHz / 64 = 312.5 KHz.
Code:
SPI_CLK_DIV_64


Quote:
and it`s really slave or master for the external adc
Figure 5 (on page 11) of the MAX1110 data sheet shows that it
receives the clock (SCLK) from an external device. That means
the PIC is the master.

Quote:
since i have one external rtc also master!

Disconnect the RTC, and make the PIC work with the MAX1110 only.
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Sun Aug 31, 2008 5:20 pm     Reply with quote

One more thing, if you can say: The max1110 ADC has 8 bits, so to a input 0-5 volt, i want to show in LCD the result of the convertion from 0 to 256(number of state exits in a 8 bit ADC), being 0v - 0 and 5volt - 256, but i can´t do that, i don´t know if is printf %u,%x,etc
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 12:01 am     Reply with quote

Quote:
i have one external rtc also master!
Very unlikely. Never saw any RTC chip that acts as SPI master.

Quote:
i want to show in LCD the result ... being 0v - 0 and 5volt - 256, but i can´t do that, i don´t know if is printf %u,%x,etc


You hardly won't see 256 from a 8-Bit ADC.
Code:
printf("%f4.2 V",(5.0f/255)*valorADC);
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 7:55 am     Reply with quote

The external adc max1110 is working, but the values are not what I expect! I'm testing for 0v, he give me value 96, and for 5v he give me 225! For lcd I'm using printf("value %c",valorADC);
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 8:46 am     Reply with quote

I think, you should try to understand the C printf format syntax before using it with your ADC problem.
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 11:31 am     Reply with quote

I've done everything. I don't understand the problem. If somebody have a code with max1110 for pic18f4550, please post here! Thanks!

PS: I´m using internal clock MAX1110, so i don´t know if the problem is that... I´m new on this technology so i tk´s you all for help me!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 12:03 pm     Reply with quote

Do a search on Google for:
Quote:
max1110 int char

This will typically find you some code. Here is a link:
http://www.le.ac.uk/eg/mjp9/pes2ohp_a4.pdf
This is for an Atmel project, but it's similar.

Look at the schematic on page 64 of that document. It shows the
connections to the MAX1110. It shows the power and ground and
other signal connections. Do you have them done the same way ?
For example, the \SHDN and REFIN pins must be connected to +5v.
Make sure you have the same connections as that schematic.

Also, post your current program to setup the SPI and to read the ADC.
We have given you many suggestions, but there is some doubt if you
have really done all of them.
madeiras



Joined: 12 Feb 2008
Posts: 14

View user's profile Send private message

PostPosted: Tue Sep 02, 2008 6:52 am     Reply with quote

Here is the code:
Code:


#include <18F4550.h>
#DEVICE ADC=8 // resolução ADC
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
  ...

unsigned char valorADC;
//byte valorADC;
unsigned char RB2;
unsigned char RB3;     
unsigned char MSB;
unsigned char controlo;

...

#define CS_ADC PIN_D2

/****************************** MAX1110 *********************************/
////                                                                 ////
////   ADC MAX192  CODE                ////
////                                                                 ////
////                                                                 ////
////  Pinos:                                                         ////
////                  MAX192             18F4550                     ////
////                  C/S                D2                          ////
////                  DOUT               SDI                         ////
////                  DIN                SDO                         ////
////                  SCLK               SCK                         ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////

//unsigned char SPI_adc_externo(unsigned char controlo)
unsigned char SPI_adc_externo(unsigned char controlo)
{
   
   setup_spi(SPI_MASTER|SPI_L_TO_H |SPI_XMIT_L_TO_H|SPI_CLK_DIV_64); //mode 0
   //setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4); //mode 3
   delay_ms(25);
   output_low(CS_ADC);
   //delay_ms(50);
   spi_write(controlo);
   //delay_ms(50);
   RB2=spi_read(0);         /*guarda os 1ºs 8 bits*/
   delay_ms(25);
   RB3=spi_read(0);         /*guarda os 2ºs 8 bits*/ // adc recebe o byte respectivo para o pin a ler
   delay_ms(25);
   RB3=RB3>>6;
   MSB=RB2;
   MSB=MSB<<2;
   //delay_ms(50);
   output_high(CS_ADC);                                                         
   return (MSB|RB3);
}

void show_adc_lcd(unsigned char valorADC,unsigned char canal)
{
//-------------- teste para ver o valor recebido do adc ----------------*/
   lcd_linha(1);
   sprintf(string,"Canal %u",canal);
   lcd_string();
   lcd_linha(2);
   //sprintf(string,"Valor %c",valorADC);
   sprintf(string,"%f V",(5.0f/255)*valorADC);
   lcd_string();
   delay_ms(2000);
   lcd_clear();
//----------------------------------------------------------------------*/


}

void controlo_adc_externo()
{
                                                       
       
      unsigned char ch0, ch1,ch2,ch3,ch4,ch5,ch6,ch7;
      ch0=0x8E;
      ch1=0xCE;
      ch2=0x9E;
      ch3=0xDE;
      ch4=0xAE;
      ch5=0xEE;
      ch6=0xBE;
      ch7=0xFE;
                 
      valorADC=SPI_adc_externo(ch0);
      delay_ms(1000);
      show_adc_lcd(valorADC,1);
      delay_ms(100);
     
     
      valorADC=SPI_adc_externo(ch1);
      delay_ms(1000);
      show_adc_lcd(valorADC,2);
      delay_ms(100);
           
      valorADC=SPI_adc_externo(ch2);
      delay_ms(1000);
      show_adc_lcd(valorADC,3);
      delay_ms(100);
           
      valorADC=SPI_adc_externo(ch3);
      delay_ms(1000);
      show_adc_lcd(valorADC,4);
      delay_ms(100);
     
      valorADC=SPI_adc_externo(ch4);
      delay_ms(1000);
      show_adc_lcd(valorADC,5);
      delay_ms(100);
           
      valorADC=SPI_adc_externo(ch5);
      delay_ms(1000);
      show_adc_lcd(valorADC,6);
      delay_ms(100);
           
      valorADC=SPI_adc_externo(ch6);
      delay_ms(1000);
      show_adc_lcd(valorADC,7);
      delay_ms(100);
     
      valorADC=SPI_adc_externo(ch7);
      delay_ms(1000);
      show_adc_lcd(valorADC,8);
      delay_ms(100);
     
     
}
/*----------------------------------------------------------------------------*/

...

void main(){
 
   int i;
   
   
   
   //menu
   lcd_setup();
   def_time_ds1305( 15, 32, 0, 3, 7, 8);
   //acerta_relogio();
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(AN0_TO_AN7|VSS_VDD);
   //setup_spi(SPI_MASTER|SPI_L_TO_H |SPI_XMIT_L_TO_H|SPI_CLK_DIV_64); //mode 0
   
   do{
     
      lcd_clear();
      controlo_adc_externo();
     
     while ( input(PIN_A4) )
     {
               delay_ms( 1000 );
               for (i=0;i<8;++i)
                  {
                  lcd_clear();
                  lcd_linha(1);
                  sprintf(string,"canal %u",i);
                  lcd_string();
                  //delay_ms(1000);
                 
                  set_adc_channel( i );
                  value = read_adc();
                  delay_us(10);                                                 //a small delay is required after setting the channel and before read
                  value=read_adc(ADC_START_AND_READ );                          //starts the conversion and reads the result and store it in value
                 
                  lcd_linha(2);
                  sprintf(string,"Value %lu",value);
                  lcd_string();     
                  delay_ms(1000);
                  }                                                             //the next read_adc call will read channel 0
       
      }

      /*----------------------------------------------------------------------*/
     
      lcd_linha(2);
     
      /*-----------segundo, minuto, hora,  mês, dia do Mês, ano---------------*/
     
      read_clk_ds1305(sec,hora,mes,dia,ano,min);
     
      /*-------------------TESTE FIM DE PROGRAMA CORRIDO----------------------*/
      //value=PIN_B5;
      //output_high(PIN_A4);
      //delay_ms(250);
      //output_low(PIN_A4);
      //delay_ms(250);
      /*----------------------------------------------------------------------*/
     
   }while(true);
}


i´ve made a code for atmel 8928253 for max1110 that work´s, here it is:
(i´ve made similiar to pic but i can´t read the correct values of the ADC. I´m using control byte of max1110 as 1XXX1110 -> internal adc clock, Vref=5Volt)

here is the atmel code that work´s:

Code:
#include<at898252.h>
#include <spi.h>

sbit enable_max1110=P1^2; //CS

unsigned char ler_max1110(unsigned char canal)
{
   unsigned char RB2;
    unsigned char RB3;     
   unsigned char MSB;
   
   SPCR=0x52;            // SPI enable, master, MSB 1º, CPOL=0, CPHA=0,e clock rate=10

   enable_max1110=0;      /*chip select*/
   SPI(canal);      /*channel reading*/
   RB2=SPI(0x00);         /* 1ºs 8 bits*/
   RB3=SPI(0x00);         /* 2ºs 8 bits*/
   RB3=RB3>>6;
   MSB=RB2;
   MSB=MSB<<2;       
   enable_max1110=1;
   return (MSB|RB3);  //reading value of adc
}



i tk´s you all for the help so far!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group