|
|
View previous topic :: View next topic |
Author |
Message |
David Pouzar
Joined: 20 Sep 2005 Posts: 27
|
SPI not return the right values PIC18F4685 |
Posted: Mon Feb 19, 2018 11:13 am |
|
|
I have been trying to use a Demo programs EX_SPI.C and EX_SPI_SLAVE. I modified them to work with an LCD Display and use a PIC18F4685. Sadly, the slave does not seem to be replying the value I am expecting.
Here is the Code, I did not modified the include files. Compiler version 5.075
Master
Code: |
#if defined(__PCB__)
#include <16C56.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)
#elif defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#elif defined(__PCH__)
#include "18F4685.H"
#FUSES INTRC_IO //Internal Clock with IO
#FUSES NOFCMEN //NO FAIL SAFE CLOCK
#FUSES NOIESO
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Brownout reset
#FUSES BORV28 //Brownout reset at 2.70V
#FUSES NOWDT //Watch Dog Timer
#FUSES WDT1024 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT //Code not protected from reading
//#FUSES NOOSCSEN //Oscillator switching is disabled, m oscillator is source
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG // No Debug mode for ICD
#FUSES NOLVP //no low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program Memory not Write Protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOLPT1OSC //NO LTP1 TIMER ENABLED
#FUSES MCLR //Master Clear pin enabled
#define XTAL_FREQUENCY 32000000
#define TIMER0_FREQUENCY (XTAL_FREQUENCY/4) //(XTAL_FREQUENCY/4) //1 clock tick = 1 instr. cycle = crystal frequency / 4
#use delay(internal = XTAL_FREQUENCY,/*clock=40MHZ,*/RESTART_WDT) //use to be 16
//#use delay(clock=20000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#elif defined(__PCD__)
#include <30F2010.h>
#fuses HS, NOWDT, NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600, UART1A)
#endif
//#include <input.c>
#include "9356.c"
#include "display.h"
void main()
{
byte value,cmd;
EEPROM_ADDRESS address;
address=0x15;
init_ext_eeprom();
// WRITE_EXT_EEPROM(address, 0X10);
lcd_init();
lcd_clear();
lcd_position(0x00);
printf(send_lcd_data,"Hello World!");
lcd_position(0x40);
printf(send_lcd_data,"%2X",READ_EXT_EEPROM( address ));
WHILE(1)
{
lcd_position(0x40);
printf(send_lcd_data,"%2X",READ_EXT_EEPROM( address ));
delay_ms(500);
RESTART_WDT();
}
}
|
Slave
Code: |
/////////////////////////////////////////////////////////////////////////
//// ////
//// EX_SPI_SLAVE.C ////
//// ////
//// Uses the PIC's SPI peripheral in slave mode to emulate a 9356 ////
//// SPI EEPROM. This example is the counterpart to EX_SPI.C. ////
//// Run EX_SPI_SLAVE.C on one PIC and connect it to another PIC ////
//// running EX_SPI. ////
//// ////
//// This example will work with the PCM and PCH compilers. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for each compiler. Change the device, clock and ////
//// RS232 pins for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2012 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#define EEPROM_BYTES 80
#elif defined(__PCH__)
#include <18F4685.h>
#FUSES INTRC_IO //Internal Clock with IO
#FUSES NOFCMEN //NO FAIL SAFE CLOCK
#FUSES NOIESO
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Brownout reset
#FUSES BORV28 //Brownout reset at 2.70V
#FUSES NOWDT //Watch Dog Timer
#FUSES WDT1024 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT //Code not protected from reading
//#FUSES NOOSCSEN //Oscillator switching is disabled, m oscillator is source
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG // No Debug mode for ICD
#FUSES NOLVP //no low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program Memory not Write Protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOLPT1OSC //NO LTP1 TIMER ENABLED
#FUSES MCLR //Master Clear pin enabled
#define XTAL_FREQUENCY 32000000
#define TIMER0_FREQUENCY (XTAL_FREQUENCY/4) //(XTAL_FREQUENCY/4) //1 clock tick = 1 instr. cycle = crystal frequency / 4
#use delay(internal = XTAL_FREQUENCY,/*clock=40MHZ,*/RESTART_WDT) //use to be 16
#define EEPROM_BYTES 256
#elif defined(__PCD__)
#include <24FJ128GA006.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#define EEPROM_BYTES 256
#endif
#if defined(__PCD__)
#use spi(SLAVE, SPI2, MODE=1, bits=8)
#else
#use spi(SLAVE, SPI1, MODE=1, bits=8)
#endif
#define EEPROM_COMMAND_WRITE 0x0A
#define EEPROM_COMMAND_READ 0x18
#define EEPROM_COMMAND_INIT 0x09
int32 ticker;
int8 do_clock_stuff;
int1 toggle;
enum {
EEPROM_STATE_COMMAND,
EEPROM_STATE_ADDRESS,
EEPROM_STATE_WRITE_DATA,
EEPROM_STATE_READ_DATA,
} EepromState = EEPROM_STATE_COMMAND;
unsigned int8 Memory[EEPROM_BYTES];
#if defined(__PCD__)
#INT_SPI2
#else
#INT_SSP
#endif
void spi_slave_isr(void)
{
static unsigned int8 LastCommand = EEPROM_COMMAND_WRITE;
static unsigned int8 Address;
unsigned int8 Data;
Data = spi_xfer_in();
// output_bit(PIN_A4,!input_state(PIN_A4));
switch(EepromState)
{
case EEPROM_STATE_COMMAND:
if((Data == EEPROM_COMMAND_WRITE) || (Data == EEPROM_COMMAND_READ))
{
LastCommand = Data;
EepromState++;
}
break;
case EEPROM_STATE_ADDRESS:
Address = Data;
if(LastCommand == EEPROM_COMMAND_WRITE)
EepromState = EEPROM_STATE_WRITE_DATA;
else
{
spi_prewrite(Memory[Address]);
EepromState = EEPROM_STATE_READ_DATA;
}
break;
case EEPROM_STATE_WRITE_DATA:
if(Address < EEPROM_BYTES)
Memory[Address] = Data;
case EEPROM_STATE_READ_DATA:
EepromState = EEPROM_STATE_COMMAND;
break;
}
}
#INT_TIMER0
void timer0_functions()
{
ticker -= 65536; // Decrement ticker by clocks per interrupt
if ( ticker < 65536 ) // If second has expired
{
ticker += TIMER0_FREQUENCY; // Increment ticker by clocks per second
do_clock_stuff++;
}
if(do_clock_stuff>0)
{
output_bit(PIN_A3,toggle);
toggle=!toggle;
do_clock_stuff--;
}
}
/*
void main(void)
PURPOSE: Peripheral Initialization
*/
void main(void)
{
#if defined(__PCD__)
enable_interrupts(INT_SPI2);
enable_interrupts(INTR_GLOBAL);
#else
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
ticker=65536;
// setup_oscillator(OSC_32MHZ);
enable_interrupts(INT_SSP);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
#endif
[color=yellow] Memory[0x15] = 0xAB;[/color]
while(true)
{
}
}
|
Note I force address 0x15 to AB, I get 0x15 back? Ideas?
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 19, 2018 11:56 am |
|
|
Post your list of connections between the two 18F4685 PICs (SPI master
and slave PICs). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Mon Feb 19, 2018 12:15 pm |
|
|
First, tidy. Over 1/3rd of what you have posted is stuff for other processors.
Then you need to modify the drivers. The PIC cannot correctly emulate this SPI EEPROM. Reasons are two separate issues:
1) The PIC will need a pause between each byte sent, to allow the slave time to get into the routines.
2) The EEPROM you are trying to emulate uses a non 'byte wide' clock pattern. The master can handle this but the SPI slave on the PIC only supports byte wide operation. Choose an EEPROM that uses byte orientated SPI. Larger EEPROM's like the 25AA010 support this format, so emulate just the number of bytes required of one of these or a similar chip. |
|
|
David Pouzar
Joined: 20 Sep 2005 Posts: 27
|
|
Posted: Mon Feb 19, 2018 12:37 pm |
|
|
Master Slave
SCL (Pin 18) ---> SCL(Pin 18)
SDI (Pin 23) ---> SDO(Pin 24)
SDO(Pin 24) ---> SDI (Pin 23)
I have 1K pullups of SDI and SDO pin between the Chips. No Pullup on SCL. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Mon Feb 19, 2018 12:42 pm |
|
|
SPI doesn't need pull-ups, but they won't hurt.
My previous comments still apply. |
|
|
David Pouzar
Joined: 20 Sep 2005 Posts: 27
|
|
Posted: Mon Feb 19, 2018 12:44 pm |
|
|
Thanks for the input. I am actually trying to communicate with a Temperature sensor made by Adafruit https://www.adafruit.com/product/2652 . But I will need to also replace my eeprom chips and will look into using what you recommend Ttelmah. |
|
|
|
|
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
|