|
|
View previous topic :: View next topic |
Author |
Message |
madeiras
Joined: 12 Feb 2008 Posts: 14
|
External adc 1110 with pic18f4550 |
Posted: Sun Aug 31, 2008 12:45 pm |
|
|
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
|
|
Posted: Sun Aug 31, 2008 1:08 pm |
|
|
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.
Think you meant single |, your code is a logical OR |
|
|
madeiras
Joined: 12 Feb 2008 Posts: 14
|
Re: External adc 1110 with pic18f4550 |
Posted: Sun Aug 31, 2008 4:04 pm |
|
|
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
|
|
Posted: Sun Aug 31, 2008 4:19 pm |
|
|
If you want help, you need to post a link to the ADC data sheet. |
|
|
madeiras
Joined: 12 Feb 2008 Posts: 14
|
|
Posted: Sun Aug 31, 2008 4:24 pm |
|
|
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
|
|
Posted: Sun Aug 31, 2008 4:40 pm |
|
|
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
|
|
Posted: Sun Aug 31, 2008 4:58 pm |
|
|
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
|
|
Posted: Sun Aug 31, 2008 5:06 pm |
|
|
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.
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
|
|
Posted: Sun Aug 31, 2008 5:20 pm |
|
|
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
|
|
Posted: Mon Sep 01, 2008 12:01 am |
|
|
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
|
|
Posted: Mon Sep 01, 2008 7:55 am |
|
|
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
|
|
Posted: Mon Sep 01, 2008 8:46 am |
|
|
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
|
|
Posted: Mon Sep 01, 2008 11:31 am |
|
|
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
|
|
Posted: Mon Sep 01, 2008 12:03 pm |
|
|
Do a search on Google for:
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
|
|
Posted: Tue Sep 02, 2008 6:52 am |
|
|
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! |
|
|
|
|
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
|