|
|
View previous topic :: View next topic |
Author |
Message |
vira
Joined: 12 Feb 2007 Posts: 5
|
Help with SPI... |
Posted: Tue Mar 13, 2007 8:31 am |
|
|
Hi,
sorry to bother but i need help, im trying to use ADC MCP3551 but i just recently started to try SPI, i used 16F877A's internal ADC at first and succeeded but had to change to MCP3551 instead becoz i realised i need a higher bit ADC... now my problem is i dunno how to get the reading from MCP3551 through SPI... im a total newbie on SPI so please bear with me if i sound ridiculous to u ...
before i go on to the code, i want to ask if i really need to control CS if i wanted to use continuous conversion mode?
below is the code that i have written:
u cant skip the void part since its not relevant to the problem.
Code: |
#define (__PCM__)
#include <16f877.h>
#device *=16
#include <stdlib.h>
#include <math.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay (clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define SPI_MODE_0_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_0_1 (SPI_L_TO_H)
#define SPI_MODE_1_0 (SPI_H_TO_L)
#define SPI_MODE_1_1 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
#byte PORTB=6
#byte PORTC=7
#bit SDI=PORTC.4
#bit CS=PORTC.5
#byte PORTD=8
void seg7()
{
}
void dotseg()
{
}
void dig7()
{
}
void display()
{
}
int32 value;
int byte0, byte1, byte2, byte3;
void read3551()
do
{
CS=0; //drop CS
delay_cycles(1);
CS=1;
delay_cycles(1);
CS=0; //At this point conversion has been triggered.
delay_us(1);
while (SDI==1) //wait for conversion to complete
{
CS=1;
delay_cycles(1);
CS=0;
}
byte2=spi_read(0); //Now read data
byte1=spi_read(0);
byte0=spi_read(0);
byte3=0;
CS=1;
count=make32(byte0,byte1,byte2,byte3);
}while(1);
main()
{
set_tris_b(0); //output for seg7()
set_tris_c(0b10010000); //C3=SCK, C4=SDI, C5=CS, C6=xmit, C7=rcv
set_tris_d(0b00000000); //output for dig7()
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_2(T2_DIV_BY_1,128,8);
setup_spi(SPI_MASTER|SPI_MODE_1_1|SPI_CLK_DIV_4);
do
{
read3551();
display(); //display count value (0 to 4194304)
}while(1);
}
|
basically seg7(), dotseg(), dig7() and display() are for displaying purposes, thats why i purposely removed it becoz its quite long and like i said earlier its not relevant to the problem. and theres no problem with the code if ur wondering since it works fine when i was using internal ADC.
im using 7 7segment LED so i need to drive it like that, it'll display the value of count from 0 to 250,0000. this will be done later becoz i want to be able to get 0 to 419,4304(22-bit) first.
on to the code, am i missing anything important? is that the right way to get 22-bit?...
another thing is i am getting a signal coming out from pin RE1, the signal is similar to SCK and SDO(from ADC). i dunno why and ive disabled PORTE, but i might need to use PORTE later so maybe i should just ask as well...
im really running out of time rite now, this is the last thing that i need to do to finish my final year project...
I'll provide more information on the project if u guys think its neccessary..
thanks in advance...
vira |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Guest
|
|
Posted: Tue Mar 13, 2007 7:11 pm |
|
|
Nope, im not das... ive read that thread before but dunt really understands it, so i took a bit of here and there and assembled something that i understands ....
by the way i forgot to tell that i actually got some reading from the code but its nowhere near 0 to 4194304, if i aint mistaken its 0 to 19000... |
|
|
vira
Joined: 12 Feb 2007 Posts: 5
|
|
Posted: Tue Mar 13, 2007 7:14 pm |
|
|
not exactly 19000 but somewhere 19xxx.... cant remember the exact value ... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 13, 2007 10:00 pm |
|
|
Quote: |
byte2=spi_read(0); // D23-D16 MSB
byte1=spi_read(0); // D15-D8
byte0=spi_read(0); // D7 - D0 LSB
byte3=0;
CS=1;
count=make32(byte0,byte1,byte2,byte3);
|
The MCP3551 data sheet says the MSB comes out first.
Quote: |
From Bit 20 to bit 0, the output code is given
MSb first (MSb is bit 20 and LSB is Bit 0).
|
The CCS manual says the make32() function has up to 4 parameters.
It says:
Quote: | i32 = MAKE32(var1, var2, var3, var4)
The msb is first.
|
So it looks to me like you have the bytes in the wrong order
in your make32() statement. You ought to have them in
this order:
Code: | make32(byte3,byte2,byte1,byte0); |
There are other issues with the overflow bits, OVL and OVH, that
I didn't really look at. Also, I don't know what your reference
voltage is. That will affect the output value. |
|
|
|
|
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
|