SPI doesn't use addressing at the hardware or protocol layer. SPI uses chip select pins to select or "address" different devices.
The application layer may require addressing (i.e. send a command, indicate an address to read write dummy bytes to get all the data read out).
Sorry I don't understand your question in further detail and your code isn't very useful without understanding the implementation of putsSPI and getsSPI.
It is definitely not like I2C where there is an explicit address at the protocol layer.
to talk to an ADC in polling mode something like this is usually done:
send SPI byte
wait for transmission complete flag to set
read SPI byte (so that the read buffer doesn't overflow but you can throw the byte away)
For a multichannel ADC you often do the above 2 or 3 times then:
send SPI dummy byte
wait for transmission to finish
read SPI byte (store it as it's the real ADC value now)
repeat above for
bytes
Dear Gallymimu,
Thanks for your advices. I am trying to read adc values from 10-bit adc(MCP3008, Microchip). But, I am always getting bad bytes which are not expected bytes. For example, I put the analog input pin of MCP3008 to the 5v line, I expect 1024(decimal) but always I get wrong bytes. The MCP3008 adc device sending 10-bit adc data and SPI protocol is making 8 bir communication. Is there any issue at reading these datas? Briefly, this program reads adc values from device and sends it via usart to my pc.
My code:
void main(void) {
unsigned char adcDataLow,adcDataHigh;
//setup usart and peripherals
setupUsartOnlyTransmit(); //MY CUSTOM FUNCTION IN myLib.h was given below
setupSPIforMCP3008(); //MY CUSTOM FUNCTION IN myLib.h was given below
//wait for 0.1ms
_delay(4000);
while(1)
{
adcDataLow = readSPI();
adcDataHigh = readSPI() & 0b00000011;
sendToSerial(adcDataHigh);
sendToSerial(adcDataLow);
}
return;
}
My custom functions:
void setupUsartOnlyTransmit()
{
//Reset usart register
TXSTA = 0;
RCSTA = 0;
//async op
TXSTAbits.SYNC = 0;
//8 bit transfer enable
TXSTAbits.TX9 = 0;
//high baud rate select
TXSTAbits.BRGH = 1;
//clear interrupt flag
PIR1bits.TXIF = 0;
//disable interrupt on receipt
PIR1bits.RCIF = 0;
//disable interrupt on transmission
PIE1bits.TXIE = 0;
//16bit baud generator disable
BAUDCONbits.BRG16 = 0;
//set SPBRG
//for 10MHZ fosc, 51 for 9600 baud
//for 40MHZ fosc, 21 for 115200 baud, 255 for 9600 baud
// the term "fosc" in datasheet refers the cpu clock speed
SPBRG = 255;
//auto baud rate disable
BAUDCONbits.ABDEN = 0;
//transmitter enable
TXSTAbits.TXEN = 1;
//USART module is set as active! this config should be done definetely!
RCSTAbits.SPEN = 1;
//configure pinouts
TRISCbits.RC6 = 0;
}
void setupSPIasMaster()
{
//for 18f4620,
//RC5 sdo
//RC4 sdi
//RC3 sck
//RA5 SS
SSPCON1 = 0x00;
//ssp power on state
SSPSTAT = 0x3f;
//bus mode is 00, data transmit on falling edge
//spi clock select
//transmit occurs on transition from active to idle state
SSPSTATbits.CKE = 1;
SSPCON1bits.CKP = 0 ;
//bus-phase
SSPSTATbits.SMP = 0;
//0100 = SPI Slave mode, clock = SCK pin, SS pin control enabled
//0000 = SPI Master mode, clock = Fosc/2
//SSPM3:SSPM0: Master Synchronous Serial Port Mode Select bits(3)
SSPCON1bits.SSPM0 = 0;
SSPCON1bits.SSPM1 = 0;
SSPCON1bits.SSPM2 = 0;
SSPCON1bits.SSPM3 = 0;
//define clock bit as output
TRISCbits.RC3 = 0;
//set input output pins
TRISCbits.RC4 = 1;
TRISCbits.RC5 = 0;
//enable syncronous serial communication
SSPCON1bits.SSPEN = 1;
//use RD0 pin as cs
TRISDbits.RD0 = 0;
LATDbits.LATD0 = 1;
_delay(100);
LATDbits.LATD0 = 0;
}
void setupSPIforMCP3008()
{
//settings for mcp3008
//0b10000000 for single ended ch0
//msb transmitted first
setupSPIasMaster();
unsigned char settings = 0b10000000;
_delay(4000);//0.1ms bekle
//write leading zeros
while(writeSPI(0x01));
//write settings to ADC
while(writeSPI(settings));
}