|
|
View previous topic :: View next topic |
Author |
Message |
dipen
Joined: 18 Feb 2004 Posts: 5
|
spi_question |
Posted: Tue Mar 09, 2004 2:26 pm |
|
|
Im trying to use the MCP6s26 PGA multiplexer with a 877 from microchip to recieve 6 analog signals. my program starts out by defining the channels and the channel register like:
#define channel0 b'00000000' //as channel 0
#define channel1 b'00000001'// as channel 1...etc
#define PrgChannel b'01000001' // as channel register
according to the data sheet i need to write to the channel register before i select the channel,yet when i try:
spi_write (PrgChannel);
value = spi_read (channel0);
i get character syntax errors
i think i can only recall a defined statment with:
#ifdef PrgChannel
(and then some statement)
.
.
but that doesnt seem very practicle. If anyone has used this device or has more knowledge on how to use the spi bus i would greatly appreciate your help. _________________ nick |
|
|
plehman
Joined: 18 Feb 2004 Posts: 12
|
|
Posted: Tue Mar 09, 2004 9:46 pm |
|
|
Not quite sure what a character syntax error is, but the definitions you made for the channels in binary look a little off. I was under the impression that binary numbers were written like 0b11010101 instead of b'11010101', but it may be correct. when I tried to compile one of my projects with that type of define, I got a "Character constant constructed incorrectly" error.
Also, I don't think that you are correctly writing to the Channel Register. I would think that to set the channel, you would need to actually do something like the following:
Code: |
output_low(CHIP_SELECT);
spi_write(0x41); // Data Sheet Instruction for Write to Channel Register
spi_write(channel0); // Write Binary Value corresponding to channel
spi_write(0x41);
value = spi_read(channel1);
...etc...
output_high(CHIP_SELECT);
|
Then if that doesn't get you closer, check to make sure that the MSSP on the '877 is configured for the correct SPI Mode (0 - 3), which detail the clock polarity and on what edges data is transmitted or sampled.
Hope that helps. |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Tue Mar 09, 2004 9:52 pm |
|
|
Since you didn't post any of your code, I'll make the assumption that you are using the basic spi set up commands. Try searching on "spi" in this forum and reviewing the recent posts. Especially the mysterious right shift post. My guess is that you are another victim of CCS's breaking the spi routines a couple of years ago. The basic spi setup does not support the majority of the spi devices in mode 0,0 or 1,1. |
|
|
dipen
Joined: 18 Feb 2004 Posts: 5
|
|
Posted: Wed Mar 10, 2004 8:20 pm |
|
|
thanks for both of your help _________________ nick |
|
|
dipen
Joined: 18 Feb 2004 Posts: 5
|
another question |
Posted: Wed Mar 17, 2004 8:41 pm |
|
|
I'm still having problems swtiching channels and completing an ADC on each channel of the PGA
my code goes like:
void main() {
int16 v[41];
setup_spi(spi_master |0x4000 |spi_clk_div_16); // MODE 0, 0
do {
OUTPUT_low(PIN_C1); // chip select
set_adc_channel(0); //set up ad on channel a0
spi_write(0x41); //initiallizing write to channel register
spi_write(0x00); //set mux\pga channel 1 here
v[0] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[1]);
spi_write(0x41); //initiallizing write to channel register
spi_write(0x01); //set mux\pga channel 2 here
v[1] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[2]);
spi_write(0x41); //initiallizing write to channel register
spi_write(0x02); //set mux\pga channel 3 here
v[3] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[3]);
only the 1st channel is read, so its not switching channels of the Pga. Ive even tried to spi_read(0); in between writing to the channel and reading the adc value. That doesnt work. Please help. _________________ nick |
|
|
Ttelmah Guest
|
Re: another question |
Posted: Thu Mar 18, 2004 3:18 am |
|
|
dipen wrote: | I'm still having problems swtiching channels and completing an ADC on each channel of the PGA
my code goes like:
void main() {
int16 v[41];
setup_spi(spi_master |0x4000 |spi_clk_div_16); // MODE 0, 0
do {
OUTPUT_low(PIN_C1); // chip select
set_adc_channel(0); //set up ad on channel a0
spi_write(0x41); //initiallizing write to channel register
spi_write(0x00); //set mux\pga channel 1 here
v[0] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[1]);
spi_write(0x41); //initiallizing write to channel register
spi_write(0x01); //set mux\pga channel 2 here
v[1] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[2]);
spi_write(0x41); //initiallizing write to channel register
spi_write(0x02); //set mux\pga channel 3 here
v[3] = Read_ADC();
delay_us(15);
printf("A/D VALUE = %2x\n\r", v[3]);
only the 1st channel is read, so its not switching channels of the Pga. Ive even tried to spi_read(0); in between writing to the channel and reading the adc value. That doesnt work. Please help. |
You have the delay in the wrong place.
When you issue a 'read_adc', the code triggers the ADC, and waits for the conversion to complete. This takes 10 cycles of the ADC clock. The function does not return till the conversion is complete, hence there is no need to delay aftr the conversion.
However when you change ADC channels, the internal multiplexer, switches the new input to the internal circuit. This comprises a significant capacitance, and some resistance from the FETs in the multiplexer. The external voltage source itself, will also have some resistance, so the result is that it takes time for the voltage on the internal capacitor to charge to the new level.
So when changing channels, the sequence is:
switch channels
delay to allow the capacitor to charge
take the reading
The 'charge time', depends on the source impedance, but with the recommended value (not above 2.5K ohms), the time for the capacitor to charge near enough that the value will be accurate to the limits of the AD, is typically in the order of 10uSec.
The same delay is needed needed when using an external multiplexer (will be more, if the multiplexer displays significant resistance). You are switching the multiplexer, and immediately taking the reading. The result of this will be a voltage near to the last input value, with the actual number dependant on all the resistances involved, and the voltage difference between the various sources.
Move your delay, from after the READ_ADC instruction, to the point between selecting the mltiplexer, and taking the reading. If you know the resistance presented by the multiplexer, and the voltage sources, you can calculate the time atually required.
Best Wishes |
|
|
dipen
Joined: 18 Feb 2004 Posts: 5
|
|
Posted: Thu Mar 18, 2004 12:38 pm |
|
|
I did that, and my channel still doesnt change for the PGA.
the data sheet for the PGA has a low impedance output resistance, yet they do not give any values. Ive tried to delay it up to 125us. I think my main problem could involve the clock. I have connected sck pin of PGA to C3 of the uC and defined it as sck. The measured frequency on that pin is only measure at 25Hz. When i reality it should be clock frequency/ sck divisions = 4Mhz/16 = 250kHz. Way way off. Please help. thanks _________________ nick |
|
|
Kieran
Joined: 28 Nov 2003 Posts: 39 Location: Essex UK
|
|
Posted: Sat Mar 20, 2004 5:41 am |
|
|
Microchip list an application note (AN248) for connecting this device to a PIC, may be worth a look! |
|
|
|
|
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
|