|
|
View previous topic :: View next topic |
Author |
Message |
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
MAX1134 16bit Ad - read error |
Posted: Wed May 31, 2006 6:21 am |
|
|
Hi there,
I've hooked up this ic from maxim dallas-Max1134, http://pdfserv.maxim-ic.com/en/ds/MAX1134-MAX1135.pdf , with a 18F8722 running at 40mhz using H4 fuse.
I'm using the typical application circuit presented on datasheet,page 17,pin SHDN tied on logic high,no SSTRB connected.The max1134 is set up in bipolar mode,internal clock,short aquisition mode-M1=0 and M0=0.
I've placed an external microchip voltage reference at pin 1,MCP1525-2.5V.
I've managed to send control byte,0xA5(0b10100101)-bits 0 to 2 represents 3 I/O pins located on the ic- and measured the 3 pins-they read ok,so i know the max received the correct control byte.
But i read 0 as for the max1134_value.Can anybody suggest what went wrong here?Thank you in advance.
Best regards
Here are the driver and test program:
//max1134.c
//Maxim-Dallas 16bit AD,SPI,150kbps
//http://pdfserv.maxim-ic.com/en/ds/MAX1134-MAX1135.pdf
//----------------------------------------------------------------------------
// SPI I/O
//
#ifndef __SPI_IO__
#define SPI_SI PIN_A0 // SPI In pin
#define SPI_SO PIN_A1 // SPI Out pin
#define SPI_SCK PIN_A2 // SPI Out Clock pin
#define CS_MAX PIN_A3
#define RST_MAX PIN_A4
#define SHDN_MAX PIN_A5
#endif
//
// Shift one Byte out on the falling edge of the clock.
//----------------------------------------------------------------------------
void write_SPI_(BYTE Shift)
{
BYTE BitCnt = 8;
//--- Shifts out
do {
//--- Clock low
output_low(SPI_SCK);
//--- Bit = 1
if(Shift & 0x80)
output_high(SPI_SO);
//--- Bit = 0
else
output_low(SPI_SO);
Shift <<= 1;
//--- Clock high
output_high(SPI_SCK);
} while (--BitCnt);
}
//
// Read one Byte in data on the rising edge of the clock.
//----------------------------------------------------------------------------
int16 read_SPI_()
{
int16 Shift;
BYTE BitCnt = 16;
//--- Shift in
do {
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
Shift <<= 1;
//--- Bit = 0
if(!input(SPI_SI))
Shift &= ~1;
//--- Bit = 1
else
Shift |= 1;
} while (--BitCnt);
return (Shift);
}
//----------------------------------------------------------------------------
//main.c
#include <18F8722.H>
#include <string.h>
#include <STDLIB.H>
#fuses H4, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=40000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#include <max1134.c>
int16 vector[250];
int i;
int16 max1134_value=0,max_LSB=0,max_MSB=0;
void main()
{
SETUP_ADC(ADC_OFF);
setup_adc_ports( NO_ANALOGS );
SET_TRIS_A(0x01); // oooo oooi
printf("MAX1134 interface \n\r"); // RS232 test
output_low(RST_MAX);
delay_ms(100);
output_high(RST_MAX);
while (1)
{
output_low(CS_MAX);
delay_us(10);
write_SPI_(0xA5);
max1134_value=read_SPI_();
output_high(CS_MAX);
printf("MAX val=%lu \r\n",max1134_value );
delay_ms(500);
}
} |
|
|
Ttelmah Guest
|
|
Posted: Wed May 31, 2006 8:28 am |
|
|
There are some slight 'dangers' about the way you are doing the mask logic, which may be causing a problem. This comes down to the default CCS data 'size', being a byte. I'd wonder if the statement:
Shift &= ~1;
Will actually just turn off the low bit, or whether in fact it will mask the high byte as well. You'd have to look at the assembler to be sure.
Personally, if using this format, I'd explicitly declare the value as a 'long' (1L), or use a full length bit mask, such as:
Shift &= 0xFFFEL;
Why not use the internal 'shift' operator?.
The single line:
shift_left(&Shift,2,input(SPI_SI));
Does the whole operation of reading the bit, and shifting it into the required output word, a lot simpler than testing/masking/shifting as you do.
The same operator can be used for the output, with:
Output_bit(SPI_SO,shift_left(&Shift,2,0));
Now, I think you will find, that the actual data is not available till SCLK _drops_. As such, the core problem is then probably that you are not dropping the clock till the start of the read routine, and the data is not then ready to be read.
Code: |
void write_SPI_(BYTE Shift) {
BYTE BitCnt = 8;
//--- Shifts out
do {
Output_low(SPI_SCK);
Output_bit(SPI_SO,shift_left(&Shift,2,0));
//--- Clock high
output_high(SPI_SCK);
} while (--BitCnt);
//Now ensure clock goes low
Output_low(SPI_SCK);
}
int16 read_SPI_() {
int16 Shift;
BYTE BitCnt = 16;
//--- Shift in
do {
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
shift_left(&Shift,2,input(SPI_SI));
} while (--BitCnt);
output_low(SPI_SCK);
return (Shift);
}
//Now only the 'core' bit of main
while (1) {
output_low(SPI_SCK);
//Clock should be _low_ before the chip is selected
output_low(CS_MAX);
//I don't think a delay is needed delay_us(10);
write_SPI_(0xA5);
max1134_value=read_SPI_();
output_high(CS_MAX);
printf("MAX val=%lu \r\n",max1134_value );
delay_ms(500);
}
|
Best Wishes |
|
|
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
|
Posted: Thu Jun 01, 2006 2:19 am |
|
|
Hey Ttelmah,
Thankx for all the help so far !
I tried to run the new routines you suggested but no luck by now.
*)When tried to read max1134_value=read_SPI_() the result was 61440 (0xF000).i used the innitial void write_SPI_(BYTE Shift) routine.
**)also when write_SPI_(0xA5) the pic was stuck ,no P0,P1,P2 initialized .all i saw at terminal was the "MAX1134 interface" message.
Any idea why?with the first void write_SPI_(BYTE Shift) function i can send the control byte ok.I measure the P0,P1,P2 ok and i assume the control byte was sent correctly.
Best regards |
|
|
Ttelmah Guest
|
|
Posted: Thu Jun 01, 2006 4:34 am |
|
|
Now I run into the question of whether the CCS routines really work as documented, when included inside another routine. In the past, there have been a few problems of this sort, where some of the routines work if you send the result to a variable, but not if you use them as I am trying.
I'd suggest trying just modifying your routines then. Set the clock low at the start, before the CS, and drop it before leaving the send byte routine. Also change the mask to force the use of an int16. On their own, these may well make it work.
Best Wishes |
|
|
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
|
Posted: Fri Jun 02, 2006 2:29 am |
|
|
Hey,
Just wanna jump outta window here .I didn't get any result with this chip so far.It's sooooooo strange.I can initialize it though,send the control byte.
Can you figure it out what's wrong with the read routine ???
#include <18F8722.H>
#include <string.h>
#include <STDLIB.H>
#fuses H4, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=40000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define SPI_SI PIN_A0 // SPI In pin
#define SPI_SO PIN_A1 // SPI Out pin
#define SPI_SCK PIN_A2 // SPI Out Clock pin
#define CS_MAX PIN_A3
#define RST_MAX PIN_A4
#define SHDN_MAX PIN_A5
int16 vector[250];
int i;
int16 max1134_value=0;
int16 read_SPI_old()
{
int16 Shift;
BYTE BitCnt = 16;
//--- Shift in
do {
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
Shift <<= 1;
if(!input(SPI_SI))
Shift &= ~1; //--- Bit = 0
else
Shift |= 1; //--- Bit = 1
} while (--BitCnt);
output_low(SPI_SCK);
return (Shift);
}
int16 read_SPI_() {
int16 Shift;
BYTE BitCnt = 16;
//--- Shift in
do {
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
shift_left(&Shift,2,input(SPI_SI));
} while (--BitCnt);
output_low(SPI_SCK);
return (Shift);
}
void write_SPI_(BYTE Shift)
{
BYTE BitCnt = 8;
//--- Shifts out
do {
output_low(SPI_SCK); //--- Clock low
if(Shift & 0x80)
output_high(SPI_SO); //--- Bit = 1
else
output_low(SPI_SO); //--- Bit = 0
Shift <<= 1;
output_high(SPI_SCK); //--- Clock high
} while (--BitCnt);
Output_low(SPI_SCK);
}
void main()
{
float value;
SETUP_ADC(ADC_OFF);
setup_adc_ports( NO_ANALOGS );
SET_TRIS_A(0x01); // oooo oooi
output_low(RST_MAX);
delay_ms(100);
output_high(RST_MAX);
printf("MAX1134 interface \n\r");
while (1) {
output_low(SPI_SCK);
//Clock should be _low_ before the chip is selected
output_low(CS_MAX);
write_SPI_(0xA5); //send control byte
max1134_value=read_SPI_(); //
output_high(CS_MAX);
printf("MAX val=%lu \r\n",max1134_value );
delay_ms(500);
}
} |
|
|
Guest
|
|
Posted: Fri Jun 02, 2006 3:33 am |
|
|
Your not having a problem here are you ?
#define RST_MAX PIN_A4
#define SHDN_MAX PIN_A5
Also, a lot of devices are limited in there speed. Yuo may be going too fast ? |
|
|
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
|
Posted: Fri Jun 02, 2006 8:22 am |
|
|
Anonymous wrote: | Your not having a problem here are you ?
#define RST_MAX PIN_A4
#define SHDN_MAX PIN_A5
Also, a lot of devices are limited in there speed. Yuo may be going too fast ? |
Hey guest,
The reset of the chip works fine.the SHDN pin on the max1134 is tied on vcc.Pin A5 on pic is unused.
In the meanwhile i connected it to the SSTRB pin of the max1134 to see when the data wil be available for reading.
Here's another test program.
Once again i mention that i read perfectly the P0,P1,P2 i/o pins of the chip,so i guess the control byte kicked in.
I tried to run it at 10mhz and same effect.
So,could anybody Help please??I promise i'll buy you a COLD 6pack coke to anybody that'll help me !!!!
BEST REGARDS to all that replied so far!!!!!
#include <18F8722.H>
#include <string.h>
#include <STDLIB.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=10000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define SPI_SI PIN_A0 // SPI In pin
#define SPI_SO PIN_A1 // SPI Out pin
#define SPI_SCK PIN_A2 // SPI Out Clock pin
#define CS_MAX PIN_A3
#define RST_MAX PIN_A4
#define SSTRB PIN_A5
int16 vector[250];
int i;
int16 Shift=0,Shift_W=0xA3;
void main()
{
SETUP_ADC(ADC_OFF);
setup_adc_ports( NO_ANALOGS );
SET_TRIS_A(0x21); // ooio oooi
output_low(RST_MAX);
delay_ms(100);
output_high(RST_MAX);
printf("MAX1134 interface \n\r");
delay_ms(500);
while (1) {
Shift_W=0xA5;
Shift=0;
output_low(SPI_SCK);//Clock should be _low_ before the chip is selected
output_low(CS_MAX);
///////////////////////////////////////////////
//write cbyte
for (i=0;i<8;i++)
{
output_low(SPI_SCK); //--- Clock low
if(Shift_W & 0x80)
output_high(SPI_SO); //--- Bit = 1
else
output_low(SPI_SO); //--- Bit = 0
Shift_W <<= 1;
output_high(SPI_SCK); //--- Clock high
}
Output_low(SPI_SCK); //clock low must be here
//////////////////////////////////////////////
//
while(!input(SSTRB)){;} // wait for SSTRB to get high (internal conversion gets ready)
//delay_us(5);
for (i=0;i<16;i++)
{
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
Shift <<= 1;
if(!input(SPI_SI))
Shift &= ~1; //--- Bit = 0
else
Shift |= 1; //--- Bit = 1
}
output_low(SPI_SCK);
//////////////////////////////////////////////
output_high(CS_MAX);
printf("MAX val=%lu \r\n",Shift );
delay_ms(100);
}
} |
|
|
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
|
Posted: Fri Jun 02, 2006 10:55 am |
|
|
I've found one more thing....
If i do a
for (i=0;i<8;i++) //instead of i<16
{
//--- Clock Low, high
output_low(SPI_SCK);
output_high(SPI_SCK);
Shift <<= 1;
if(!input(SPI_SI))
Shift &= ~1; //--- Bit = 0
else
Shift |= 1; //--- Bit = 1
}
i get a value of 128 (0x80) with the input of the chip floating and if i put the chip's input to GND i read 224 (0xE0)
here's what i found in max1134 datasheet
Quote: | Operating Modes and Serial Interfaces
The MAX1134/MAX1135 are fully compatible with
MICROWIRE and SPI/QSPI devices. MICROWIRE and
SPI/QSPI both transmit a byte and receive a byte at the
same time. The simplest software interface requires
only three 8-bit transfers to perform a conversion (one
8-bit transfer to configure the ADC, and two more 8-bit
transfers to clock out the 16-bit conversion result). |
Quote: | The output data format is straight binary for unipolar
conversions and two’s complement in bipolar mode.
The MSB is shifted out of the MAX1134/MAX1135 first
in both modes. |
Can somebody explain the result from ad?
Best regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 02, 2006 2:23 pm |
|
|
You're not following the data sheet. You've selected the "internal clock"
mode. If you look in the MAX1134 data sheet, on page 11, at Figure 5,
it shows the timing diagram for that mode. It shows \CS goes low when
the Control byte is sent, and then it goes high. Then it should be taken
low again when the data is read. You're not doing that. You have
it low continuously, during the entire operation. |
|
|
vibrasys
Joined: 20 Nov 2005 Posts: 16 Location: the Netherlands
|
|
Posted: Sat Jun 03, 2006 4:50 am |
|
|
Hey PCM Programmer
Tried your advice and same effect.
Regards |
|
|
|
|
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
|