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 support@ccsinfo.com

Slow sampling (newbie)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Swan
Guest







Slow sampling (newbie)
PostPosted: Thu Sep 27, 2007 10:40 am     Reply with quote

Hi, i'm trying to sample some data from an ADC using SPI.
I'm using a 18f4520, while the ADC is MAX1270.
I need to sample 8 channels at the speed of 2kHz.
As far as i've seen, if i sample 4 channels, everithing goes right, while if i sample all the 8 chs... or it takes longer then 500us, or it just crashes.

I've set the SPI as follow:
setup_spi (SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_4).


here is part of the code:

void process()
{
unsigned char bDataH0,bDataL0,bDataH1,bDataL1,
bDataH2, bDataL2,bDataH3,bDataL3,
bDataH4, bDataL4,bDataH5,bDataL5,
bDataH6, bDataL6,bDataH7,bDataL7,


if(ADC_On && sample_GO)
{
select_cs(ADC_DEVICE);

read_sample (0,&bDataH0, &bDataL0);
read_sample (1,&bDataH1, &bDataL1);
read_sample (2,&bDataH2, &bDataL2);
read_sample (3,&bDataH3, &bDataL3);
read_sample (4,&bDataH4, &bDataL4);
read_sample (5,&bDataH5, &bDataL5);
read_sample (6,&bDataH6, &bDataL6);
read_sample (7,&bDataH7, &bDataL7);

select_cs(NONE_DEVICE);

Sample_GO=0; //Sample_GO turns to 1 through an T2 interrupt
}
}

I cannot believe that it needs more then 500us to read 8 channels, thus i'm sure i must have done something wrong.
Thank you very much in advance for every help you could give me
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 27, 2007 11:22 am     Reply with quote

1. Post your compiler version.

2. Post a complete test program, not just pieces of it. Post all #include,
#fuses, #use, etc. statements. The program should be compilable.

Make sure you disable HTML when you post the code. There's a tickbox
for this just below the posting window.
Guest








PostPosted: Thu Sep 27, 2007 11:55 am     Reply with quote

Here it is...sorry for the comments in italian...
my compiler version is 4.013.
Just to say.. I've got the same result even if i avoid writing the data on rs232, so the problem, for the time beeing, shouldn't be there
Thank you


#INCLUDE <18F4520.H>
#INCLUDE <stdlib.h>
#INCLUDE "Defines.h" // PINS Defines

#fuses HS,NOWDT,NOPROTECT,NOLVP

#Use delay(clock=14745600)
#use RS232(Baud=9600,Xmit=PIN_C6,Rcv=PIN_C7)

unsigned char device;
unsigned char oldDevice;
unsigned char ADC_On=0;
unsigned char sample_GO=0;
unsigned char connectionOn=0;

char bText[16];
byte carattere;
unsigned char received_char=0;

unsigned char inizio=0;

#int_TIMER2
void SamplingTimer()
{
sample_GO=1;
}

#int_rda
void serial_interrupt ( )
{
carattere=getc();
received_char=1;
}


//////////////////////DRIVER SPI//////////////////////////////////////////////
void Init_SPI()
{

// Imposto i valori di default
output_high(SPI_SCK);
output_high(SPI_CS_LCD);
output_high(SPI_CS_EEPROM);
output_high(SPI_CS_SD);
output_high(SPI_CS_ADC);
output_low(SPI_SDO);

oldDevice=NONE_DEVICE;
}

void select_cs( unsigned char device )
{
// Se e' gia' selezionato esco...
if ( device == oldDevice ) return;

// Seleziono un chip per volta
switch (device) {

case ADC_DEVICE:

SSPEN=0;
setup_spi(SPI_MASTER | SPI_L_TO_H |SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);
output_high(SPI_CS_LCD);
output_high(SPI_CS_SD);
output_low (SPI_CS_ADC);
output_high(SPI_CS_EEPROM);
SSPEN=1;

break;

case LCD_DEVICE:

SSPEN=0;
setup_spi(SPI_MASTER | SPI_H_TO_L |SPI_XMIT_L_TO_H | SPI_CLK_DIV_64);
// Abilito il correto CS
output_low (SPI_CS_LCD);
output_high (SPI_CS_SD);
output_high (SPI_CS_ADC);
output_high (SPI_CS_EEPROM);
SSPEN=1;
break;
default:

// disabilito i CS
output_high(SPI_CS_LCD);
output_low (SPI_RS_LCD);
output_high(SPI_CS_SD);
output_high(SPI_CS_ADC);
output_high(SPI_CS_EEPROM);

break;
}

// Salvo la selezione
oldDevice = device;
}

////////////////////FINE DRIVER SPI///////////////////////////////////////////

///////////////////INIZIO DRIVER LCD//////////////////////////////////////////
void Init_LCD()
{
//Accendo la backlight
output_high(LED_BKL);
//attendo 45 ms
delay_ms(45);
select_cs( LCD_DEVICE );
output_low(SPI_RS_LCD);
delay_ms(45);
spi_write(0b00111001);
delay_ms(45);
spi_write(0b00010100);
delay_ms(45);
spi_write(0b01111111);
delay_ms(45);
spi_write(0b01010101);
delay_ms(45);
spi_write(0b01101101);
delay_ms(45);
spi_write(0b00001100);
delay_ms(45);
spi_write(0b00000001);
delay_ms(45);
spi_write(0b00000110);
delay_ms(45);
select_cs( NONE_DEVICE);
}

// Invia una stringa all'lcd --------------------------------------------------
void write_lcd( char * bTemp, unsigned char bLen, unsigned char bLine )
{

unsigned char bCounter;

// Seleziono l'LCD
select_cs ( LCD_DEVICE );
output_low(SPI_RS_LCD);

delay_us(40);

// Imposto il cursore nella giusta locazione
if ( bLine == 0 )
{
// [Command] [RS] [R/W] [DB7] [DB6] [DB5] [DB4] [DB3] [DB2] [DB1] [DB0]
// Return Home 0 0 0 0 0 0 0 0 1 0
spi_write(0b00000010);

delay_us(40);
}
else
{
// [Command] [RS] [R/W] [DB7] [DB6] [DB5] [DB4] [DB3] [DB2] [DB1] [DB0]
// Set DDRAM Addr 0 0 1 1 0 0 0 0 0 0
// DB6: AC6 -> DDRAM Address
// DB5: AC5 -> DDRAM Address
// DB4: AC4 -> DDRAM Address
// DB3: AC3 -> DDRAM Address
// DB2: AC2 -> DDRAM Address
// DB1: AC1 -> DDRAM Address
// DB0: AC0 -> DDRAM Address
spi_write(0b11000000);
delay_us(40);
}

// Pronti a scrivere
output_high(SPI_RS_LCD);
delay_us(40);

// Per ogni carattere da spedire...
for ( bCounter = 0; bCounter < 16; bCounter++ )
{

// Scrivo i dati o gli spazi
if ( bCounter < bLen )
spi_write( bTemp[bCounter]);
else
spi_write(0x20);

delay_us(40);
}

// Deseleziono l'LCD
select_cs( NONE_DEVICE );

}//end write_lcd

////////////////////////////FINE DRIVER LCD////////////////////////////////////

///////////////////////INIZIO DRIVER ADC//////////////////////////////////////

void read_sample( unsigned char bChannel, unsigned char *bHigh, unsigned char *bLow )
{

// Acquisisco il canale X
switch( bChannel ) {
case 0:
spi_write(0b10000100);
break;
case 1:
spi_write(0b10010100);
break;
case 2:
spi_write(0b10100100);
break;
case 3:
spi_write(0b10110100);
break;
case 4:
spi_write(0b11000100);
break;
case 5:
spi_write(0b11010100);
break;
case 6:
spi_write(0b11100100);
break;
case 7:
spi_write(0b11110100);
break;
}

// Attendo che lo strobe vada a zero
while(input(SPI_STRB_ADC)) delay_cycles( 1 );

// Attendo che lo strobe ritorni ad uno
while (input(!SPI_STRB_ADC) ) delay_cycles( 1 );

*bHigh = spi_read(0b00000000); //Serve solo per mettere da qualche parte i dati dummy
//che l'ADC invia all'inizio
*bHigh = spi_read(0b00000000);
*bLow = spi_read(0b00000000);
}



/////////////////////////FINE DRIVER ADC//////////////////////////////////////

////////////////////////DRIVER BT////////////////////////////////////////////
void Init_BT()
{
delay_ms(10);
output_low(PIN_D7);
output_low(BT_PIO4);
output_low(BT_RESET);
delay_ms(10);
output_high(BT_RESET);
delay_ms(500);


// delay_ms(500);
printf("ATSW20,1887,0,0,0\r" ); //472 per 115200, 944 è per una velocità di 230400kbs, 1887 per 460800
delay_ms(500);

set_uart_speed(460800);
printf( "ATSW25,0,0,0,0\r" );
carattere=getc();
putc(carattere);
carattere=getc();
putc(carattere);
carattere=getc();
putc(carattere);
carattere=getc();
putc(carattere);
carattere=getc();
putc(carattere);
carattere=getc();
putc(carattere);

}
///////////////////////////////FINE DRIVER BT//////////////////////////////////

//////////////////////////////DRIVER POWER////////////////////////////////////
void PSU_ADC_On()
{
output_high(PSU_ADC);
}
void PSU_ADC_Off()
{
output_low(PSU_ADC);
}
//////////////////////////FUNZIONI DI SERVIZIO/////////////////////////////////
void start_adc()
{
PSU_ADC_On();
sprintf( bText, "In acquisizione" );
write_lcd( bText, strlen(bText),0);
delay_ms(100);
ADC_On = 1;
output_high(LED_3);
enable_interrupts(INT_TIMER2);

}

void stop_adc()
{
PSU_ADC_Off();
delay_ms(100);
ADC_On = 0;
sprintf( bText, "In attesa" );
output_low(LED_3);
write_lcd( bText, strlen(bText),0);
disable_interrupts(INT_TIMER2);
}

void StartConnection()
{
output_high(LED_2);
delay_us(10);
carattere=getc();
putc(carattere);
if (carattere==0x0A)
{
if(inizio==0)
{
inizio=1;
}
else
{
connectionOn=1;
enable_interrupts(int_rda);
}
}
}

void StopConnection()
{
connectionOn=0;
inizio=0;
disable_interrupts(int_rda);
output_low(LED_2);
carattere=getc();
putc(carattere);
gets(*test);
carattere=getc();
}


void Init_LED()
{
output_high(LED_4);
output_high(LED_1);
output_high(LED_3);
output_high(LED_2);
delay_ms(500);
output_low(LED_4);
output_low(LED_3);
output_low(LED_2);
}

void InterpretCommand()
{
if (carattere==']') //se si tratta del carattere di start per 2 canali
{
if(ADC_On==0) //Se non sto già in acquisizione, la avvio
start_adc();
}
else if (carattere=='£') //Se si tratta del carattere di stop
{
if(ADC_On==1) //Se sto in acquisizione, mi fermo
stop_adc();
}
received_char=0;
}



void Process_System()
{
if (input(BT_CONN))
{
if (connectionOn==0) //Ci stiamo connettendo ora, devo ricevere la stringa
//di connessione da parte del dispositivo BT
StartConnection();
else
{
// controllo se è stato ricevuto un comando dalla seriale
if (received_char==1) //è arrivato un carattere
{
InterpretCommand();
}
}
}
else
{
if(connectionOn) StopConnection(); //Eravamo Connessi, mi vado ad occupare della chiusura
}
}

void Process_User()
{

long UrielData;
unsigned char valuehigh,valuelow,bDataH0,bDataH1,bDataH2,bDataH3,bDataL0,bDataL1,bDataL2,bDataL3;


if (ADC_On && sample_GO==1)
{
// Seleziono l'ADC
select_cs( ADC_DEVICE );
// Acquisisco i campioniF
read_sample( 0, &bDataH0, &bDataL0 );
read_sample( 1, &bDataH1, &bDataL1 );
read_sample( 2, &bDataH2, &bDataL2 );
read_sample( 3, &bDataH2, &bDataL2 );
// read_sample( 4, &bDataH3, &bDataL3 );
// read_sample( 5, &bDataH3, &bDataL3 );
// read_sample( 6, &bDataH3, &bDataL3 );
// read_sample( 7, &bDataH3, &bDataL3 );


select_cs( NONE_DEVICE );

delay_cycles(1);
printf("[%c%c%c%c",bDataH0,bDataL0,bDataH1,bDataL1);
sample_GO=0;
}
}


void main()
{
Init_SPI();
Init_LCD();
Init_BT();
Init_LED();
// PSU_ADC_On();
setup_timer_2(T2_DIV_BY_4,0xE5,2);//Timer associato al campionamento (500us->E5. C8,più basso)

enable_interrupts(GLOBAL); //enable all interrupts

// Scrivo l'LCD
sprintf( bText, "Sistema avviato" );
write_lcd( bText, strlen(bText),0);
sprintf( bText, "Hello_1" );
write_lcd( bText, strlen(bText),1);

delay_ms(2000);
sprintf( bText, "Waiting.." );
write_lcd( bText, strlen(bText), 0);


while(TRUE)
{
process_System();
process_user();
}

}


defines in "defines.h":
#Define LED_1 PIN_E0
#Define LED_2 PIN_E1
#Define LED_3 PIN_E2
#Define LED_4 PIN_C0
#Define BT_PIO4 PIN_D7
#Define BT_RESET PIN_D5
#Define BT_CONN PIN_D6
#Define SPI_SDI PIN_C4
#Define SPI_SDO PIN_C5
#Define SPI_SCK PIN_C3
#Define SPI_CS_LCD PIN_D1
#define SPI_RS_LCD PIN_D0
#define SPI_CS_EEPROM PIN_D4
#define SPI_CS_SD PIN_D3
#define SPI_CS_ADC PIN_D2
#define SPI_STRB_ADC PIN_B0
#define LED_BKL PIN_C1
#define PSU_ADC PIN_A1


#define NONE_DEVICE 0
#define ADC_DEVICE 1
#define LCD_DEVICE 2
swan
Guest







PostPosted: Mon Oct 01, 2007 3:28 am     Reply with quote

Sorry... yet i haven't had any answer. Please somebody could give me a hand, a hint, wathever can help me understand what i have done wrong...
Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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