// PIC18 in C - Versione 0.2 - Febbraio 2015 // Copyright (c) 2015, Vincenzo Villa // Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported. // Creative Commons | Attribution-Share Alike 3.0 Unported // https://www.vincenzov.net/tutorial/PIC18/SPI.htm // PIC18F25K20 / MPLABX 2.30 / XC8 1.33 // Software SPI - Full duplex - Master #include "ConfigurationBits.h" #define _XTAL_FREQ 1000000 // Default output frequency of HFINTOSC on Reset //#define MAX146_CONTROL_BYTE 0x8F // 1000 1111 = Channel 0, Unipolar, single ended, external clock (see datasheet) #define MAX146_CONTROL_BYTE 0xCF // 1100 1111 = Channel 0, Unipolar, single ended, external clock (see datasheet) #define MOSI LATCbits.LATC5 // Pin 16 MOSI RC5/SDO #define MISO PORTCbits.RC4 // Pin 15 MISO RC4/SDI #define SS0 LATBbits.LATB0 // Pin 21 DAC_SS RB0 - Unused #define SS1 LATBbits.LATB1 // Pin 22 ADC_SS RB1 #define CLK LATCbits.LATC3 // Pin 14 SCK RC3/SCK // Write a byte to SPI - Master unsigned char SPI_Master_write_read_byte(unsigned char dato); void main(void) { unsigned short int Byte1, Byte2, dummy; // Configure SPI pin TRISCbits.RC5 = 0; // Set MOSI pin as output TRISCbits.RC3 = 0; // Set clock pin as output TRISBbits.RB0 = 0; // Set SS0 pin as output - Unused TRISBbits.RB1 = 0; // Set SS1 pin as output TRISCbits.RC4 = 1; // Set MISO pin as input SS0 = 1; // Disable Slave Select (DAC) - Unused SS1 = 1; // Disable Slave Select (ADC) CLK = 0; // Clear clock while (1) { SS1 = 0; // Enable Slave Select (ADC) dummy = SPI_Master_write_read_byte(MAX146_CONTROL_BYTE); // Write a byte to slave - Read back firs byte __delay_us(20); // Useless delay... Byte1 = SPI_Master_write_read_byte(0); // Write 0 to slave - Read a byte __delay_us(20); // Useless delay... Byte2 = SPI_Master_write_read_byte(0); // Write 0 to slave - Read a byte SS1 = 1; // Disable Slave Select (ADC) __delay_ms(10); } } unsigned char SPI_Master_write_read_byte(unsigned char dato) { unsigned char mask; unsigned char data = 0; for (mask = 0x80; mask != 0; mask >>= 1) { // Write and read 8 bit, starting form MSB if (dato & mask) MOSI = 1; // Write single 1 else MOSI = 0; // Write single 0 __delay_us(10); // Delay half periode CLK = 1; // Clock active on rising edge if (MISO) data = data | mask; __delay_us(10); // Delay half periode CLK = 0; // Clock to idle } return data; }