SC9
Newbie

Hi all,
I'm using PIC18F25K22 which is 8 bit system, SPI, MCP23S08.
A1 is set to 1 and A0 is set to 1 as well on the hardware.
The software used in Mplab – anscii – embedded c
I want the SPI supposed to be control a servo later on - but at the moment I have little faith that the SPI connection to PIC is working..
I'm trying to use LCD screen to show the state of dipswitches.
The LCD code works on it's own, but the dipswitch message always read 0, regardless of what I do to them.
The code is below I believe the issue is somewhere with the SPI and MCP configuration but I've been staring at it for the past week and I really can't see what I'm missing.
Any pointers would be appreciated!
I'm using PIC18F25K22 which is 8 bit system, SPI, MCP23S08.
A1 is set to 1 and A0 is set to 1 as well on the hardware.
The software used in Mplab – anscii – embedded c
I want the SPI supposed to be control a servo later on - but at the moment I have little faith that the SPI connection to PIC is working..
I'm trying to use LCD screen to show the state of dipswitches.
The LCD code works on it's own, but the dipswitch message always read 0, regardless of what I do to them.
The code is below I believe the issue is somewhere with the SPI and MCP configuration but I've been staring at it for the past week and I really can't see what I'm missing.
Any pointers would be appreciated!
#include <xc.h>
#pragma config FOSC = HSMP // HS oscillator - medium power
#pragma config PWRTEN = ON // Powerup timer on
#pragma config BOREN = OFF // Brownout detect off
#pragma config LVP = OFF // Low voltage programming off
#pragma config PBADEN = OFF // Port B all digital I/O
#define _XTAL_FREQ 4000000 // Clock frequency for delay functions
// Port definitions
#define TRIS_SDI TRISCbits.TRISC5 // Direction define SDI input
#define TRIS_SCK TRISCbits.TRISC3 // Direction define clock pin as output
#define CS PORTBbits.RB0 // CS - RB0
#define TRIS_CS TRISBbits.TRISB0 // Direction CS - B0
#define TRIS_SDO TRISCbits.TRISC4// Direction SD0 as output
// MCP23S08 registers taken from datasheet
#define mcp23S08_read 0x47 // Control byte 01000 - first 5 bits. 11 A1 A0 - user dependent - last bit R/W=1 so read
#define mcp23S08_address_write 0x46 // Control byte 01000 - 11(A1 A0), R/W=0 so write
#define MCP_IODIR 0x00 // IO Direction register set to output
#define MCP_IPOL 0x01 // IO Polarity register - bit7 opposite logic state of the input pin
#define MCP_IOCON 0x05 // bit 0=1 - but unimplemented in data sheet. bit 2=1 - overrides intpol
#define MCP_GPPU 0x06 // 00000110 - pull-up resistor enabled on bit 1&2
#define MCP_GPIO 0x09 //
#define MCP_DEFVAL 0x03
#define MCP_INTCON 0x04
// LCD definitions
#define LCD_Port PORTB
#define EN PORTCbits.RC6
#define RS PORTCbits.RC7
#define Set_LCD_Address_command 0x80
#define Set_LCD_Position_R1C1 0x00
#define Set_LCD_Position_R2C1 0xC0
#define clear_LCD 0x01
// Function declarations
void PIC_Initialise(void);
void SPI_Initiailise(void);
void MCP23S08_Initialise(void);
void SPI_Send_data(unsigned char device_address, unsigned char register_adress, unsigned char register_data);
void WriteSPI(unsigned char data);
unsigned char ReadDipswitches(void);
void LCD_Init(void);
void LCD_Command(unsigned char cmd);
void LCD_Char(char dat);
void LCD_String(char *msg);
void main(void) {
PIC_Initialise();
SPI_Initiailise();
MCP23S08_Initialise();
LCD_Init();
LCD_Command(0x80);
LCD_String("Crying");
__delay_ms(1000);
LCD_Command(clear_LCD);
while (1) {
unsigned char switchState = ReadDipswitches();
LCD_Command(0x80); // Move cursor to the beginning of the first line
LCD_String("DIPSWITCH: ");
LCD_Char(switchState + '0'); // Display the switch state as a character
__delay_ms(500); // Delay before checking the dipswitches again
}
}
void PIC_Initialise(void) {
// Configure SPI pins
TRISCbits.TRISC3 = 0; // SCK as output
TRISCbits.TRISC4 = 1; // SDI as input
TRISCbits.TRISC5 = 0; // SDO as output
TRISBbits.TRISB0 = 0; // CS as output
// Configure LCD control pins
TRISCbits.TRISC6 = 0; // EN as output
TRISCbits.TRISC7 = 0; // RS as output
// Configure LCD data pins
TRISBbits.TRISB4 = 0; // Data 4 as output
TRISBbits.TRISB5 = 0; // Data 5 as output
TRISBbits.TRISB6 = 0; // Data 6 as output
TRISBbits.TRISB7 = 0; // Data 7 as output
// Set all other ports as digital outputs
ANSELA = ANSELB = ANSELC = 0x00;
// Clear all port outputs
LATA = LATB = LATC = 0x00;
}
void SPI_Initiailise(void) {
SSP1STAT = 0x40; // Bit 6 set to 1 - SPI Clock Edge Select
SSP1CON1 = 0x20; // Enables serial port and configures SCKx, SDOx, SDIx and SSx, clock = FOSC / 4
}
void MCP23S08_Initialise ()
{
SPI_Send_data(mcp23S08_address_write, MCP_IOCON, 0x38); //sequential and slew disables
SPI_Send_data(mcp23S08_address_write, MCP_IODIR, 0xFF); // sets all as inputs
SPI_Send_data(mcp23S08_address_write, MCP_IPOL, 0x00); //set polarity to same
SPI_Send_data(mcp23S08_address_write, MCP_GPPU, 0x00); //pull ups disabled
SPI_Send_data(mcp23S08_address_write, MCP_INTCON, 0x00); //compare register for interrupt on change
SPI_Send_data(mcp23S08_address_write, MCP_DEFVAL, 0x00); //compare register for interrupt on change
}
void SPI_Send_data(unsigned char device_address, unsigned char register_adress, unsigned char register_data) {
CS = 0;
WriteSPI(device_address);
WriteSPI(register_adress);
WriteSPI(register_data);
CS = 1;
}
void WriteSPI(unsigned char data) {
SSP1BUF = data; // Write data to SSPBUF (data buffer)
while(!PIR1bits.SSPIF); // Wait for complete 1 byte transmission
PIR1bits.SSPIF = 0; // Clear SSPIF flag
}
unsigned char ReadDipswitches(void) {
unsigned char switchState;
CS = 0; // Lower chip select line
WriteSPI(mcp23S08_read); // Selecting read address
WriteSPI(MCP_GPIO); // GPIO register selection
// Dummy write to receive data
SSP1BUF = 0x00;
while(!SSP1STATbits.BF); // Wait for buffer full
switchState = SSP1BUF; // Read received data
CS = 1;
return switchState; // Value read from SSP1BUF (data buffer) is the SPI
}
void LCD_Init(void)
{
LCD_Port = 0x00; // Port as output port
__delay_ms(20); // 41ms delay
LCD_Command(0x30); //
__delay_ms(5); // 41ms delay
LCD_Command(0x30); //
__delay_ms(2); // 41ms delay
LCD_Command(0x30); //
__delay_ms(1); // 41ms delay
LCD_Command(0x02); // Return home
__delay_ms(5); // 41ms delay
LCD_Command(0x28); //
__delay_ms(5); // 1ms delay
LCD_Command(0x08); //
__delay_ms(5); // 1ms delay
LCD_Command(0x01); // Clear Display
__delay_ms(15); // 41ms delay
LCD_Command(0x06); //
__delay_ms(1); // 2ms delay
LCD_Command(0x0F); //
__delay_ms(1); // 2ms delay
}
void LCD_Command(unsigned char cmd)
{
char ldata = 0;
ldata = (ldata & 0x0f) | (0xF0 & cmd); //
RS = 0; //
EN = 1; //
PORTB = ldata;
__delay_ms(1);
EN = 0;
__delay_ms(5);
ldata = (ldata & 0x0f) | (cmd << 4); //
PORTB = ldata;
EN = 1;
__delay_ms(1);
EN = 0;
__delay_ms(5);
}
void LCD_String(char *msg)
{
while ((*msg) != 0)
{
LCD_Char(*msg);
msg++;
}
}
void LCD_Char(char dat)
{
char ldata = 0;
ldata = (ldata & 0x0f) | (0xF0 & dat);
//ldata = dat; //
PORTB = ldata;
RS = 1; //
EN = 1; //
// NOP();
__delay_us(10);
EN = 0;
__delay_ms(5);
ldata = (ldata & 0x0f) | (dat << 4);
//ldata = dat; //
PORTB = ldata;
EN = 1; //High
__delay_us(10);
// NOP();
EN = 0;
__delay_ms(5);
}