Hallo
Ik heb een probleem om 2x SPI te gebruiken op een PIC87J50 in MikroC .
Ik wil een accelerometer ADXL345 en een SD kaart gebruiken.
Beide werken goed appart maar wanneer ze worden samengevoegd in een project werkt 1 van de 2 niet.
Wanneer ik de SD kaart initialiseer(met MMC FAT16 library) werkt de accelerometer niet meer, wanneer ik de accelerometer initialiseer werkt de sd kaart niet meer...
De hardware is als volgt aangesloten:
Iemand een tip ?
Alvast bedankt!
Hoe bedien je de slave-select lijnen? Weet je zeker dat deze hoog worden op het moment dat je klaar bent met een device (en weer laag als je ze wilt gebruiken)?
Edit.De ADXL345 heeft een register (0x31) om tussen 3-wire en 4-wire SPI te schakelen. Staat hij wellicht op 3-wire? nvt...
Wat voor snelheid draait de SPI bus? Kan het zijn dat de MMC library de snelheid omhoog gooit na initialisatie, boven de 5mhz wat de maximum snelheid is van de ADXL?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Je moet waarschijnlijk voor ieder apparaat de SPI nieuw initialiseren i.v.m. kloksnelheid, clockpolariteit, enz, die bij alle drie verschillend kan zijn...
Zeker weet ik niet of ze hoog komen. Maar wanneer ik de accelerometer appart test werkt deze. Hetzelfde met de sd kaart, deze werkt wanneer ik de accelerometer niet initialiseer.
Dit is mijn code
void ADXL345_Write(unsigned short address, unsigned short data1) {
unsigned short internal = 0;
internal = address | _SPI_WRITE; // Register and Write bit
CS_bit = 0;
SPI1_Write(internal);
SPI1_Write(data1);
CS_bit = 1;
}
unsigned short ADXL345_Read(unsigned short address) {
unsigned short internal = 0;
internal = address | _SPI_READ; // Register and Read bit
CS_bit = 0;
SPI1_Write(internal);
internal = SPI1_Read(0);
CS_bit = 1;
return internal;
}
void InitialiseADXL345() {
/*CS_bit = 1; // Deselect Chip before initalization
CS_Direction_bit = 0;*/ // Set direction
// SPI Initialization, Fosc/4, when idle SPI High, Data transmit on low to high edge
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_LOW_2_HIGH);
// Go into standby mode to configure the device.
ADXL345_Write(_POWER_CTL, 0x00);
// Full resolution, +/-16g, 4mg/LSB.
ADXL345_Write(_DATA_FORMAT, 0x03);
// Set data rate.
ADXL345_Write(_BW_RATE, _SPEED);
// Measurement mode.
ADXL345_Write(_POWER_CTL, 0x08);
}
char GetXAcc() {
// Read X Hi
readings[0] = ADXL345_Read(_DATAX0) << 8;
// Read X Lo
readings[0] = readings[0] | ADXL345_Read(_DATAX1);
IntToStr(readings[0], out);
return out;
}
void InitialiseSDCard(){
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
if (Mmc_Fat_Init() == 0) {
// reinitialize spi at higher speed
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_LOW_2_HIGH);
}
else{
Uart1_Write_Text(err_txt);
}
}
void main() {
//cmcon=7;
//adcon1=0x1D;
UART1_Init(9600);
CS_bit = 1; // Deselect Chip before initalization
CS_Direction_bit = 0;
UART1_Write_Text("TEMP START\n\r");
UART1_Write_Text("Initialising SD Card\n\r");
InitialiseSDCard();
UART1_Write_Text("Initialised\n\r");
InitialiseADXL345();
do{
delay_ms(100);
outacc=GetXAcc();
Uart1_Write_Text(outacc);
Uart1_Write_Text("\n\r");
}while(1);Het probleem met die ADXL345 is dat als de CS lijn hoog is (wat goed is met een SPI bus in rust) hij in I2C mode staat.
Als er dus met een ander device op de SPI bus wordt gecommuniceerd kan hij dit als een I2C commando zien en gaat er dan doorheen zitten praten.
Zie datasheet pagina 15 "Preventing bus traffic errors"
OR port ertussen zetten is de oplossing.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
De ADXL heeft _SPI_CLK_IDLE_HIGH, en de SD card _SPI_CLK_IDLE_LOW, dat is niet compatible met elkaar.
Daarom moet je, zoals reeds gezegd, de SPI interface re-initialiseren voor het juiste apparaat...
(Of neem een PIC met meerdere SPI poorten )
De laatste init voor de SD klopt niet, moet idle_low zijn, niet idle_high...
[Bericht gewijzigd door Arco op (14%)]