|
|
View previous topic :: View next topic |
Author |
Message |
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
Pin Connections for SPI Examples(EX_SPI.c & EX_SP_Slave) |
Posted: Thu May 24, 2007 8:12 pm |
|
|
I have been trying to communicate two 18452s as master and slave with one pic emulating 9356 EEPROM.
I have been working with the example for a week now but couldnt make it work / simulate properly in Proteus.
Final thoughts are : May be I am not connecting the pins properly.
Need help to simulate the code in Proteus.
What I do not understand is how would I connect the Pin connections used in 9356.C , EX_SPI.C and the EX_SPI_Slave.C) in PROTEUS.
Thanks |
|
|
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Thu May 24, 2007 8:17 pm |
|
|
For help with Proteus simulation, you should really go to their forum and ask Proteus related questions there.
http://support.labcenter.co.uk/forum
Most people on here do not use Proteus and cannot offer help in that regard.
r.b. |
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Fri May 25, 2007 7:59 am |
|
|
I understand your point of view but my question may be considered as general.
How is it, let me explain:
In Ex_SPI.C, the rs232 config. statement is:
Code: | #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) |
Dedicating pins C6 & C7 for the communication.
In this example another file 93c56SPI.C is also included in which the pin assignments are:
Code: | #define EEPROM_SELECT PIN_B0
#define EEPROM_DI PIN_C5
#define EEPROM_DO PIN_C4
#define EEPROM_CLK PIN_C3 |
My problem is that this code is to run on one PIC (the master). How would I make the pins hookup between C6, C7, B0,C5, C4 & C3 of the master PIC?
I hope I have conveyed my confusion this time.
Thanks any way. |
|
|
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Sun May 27, 2007 5:44 am |
|
|
Looking at EX_SPI.c, it appears as if RS232 is used to connect the PIC to a PC, and SPI is used to connect the PIC to the EEPROM. This driver appears to be designed for a protoboard.
Thus your confusion is in thinking that pins C6 and C7 are connected to the EEPROM when they are not.
If you look at the 18F452 data sheet, pins C3, C4 and C5 are the correct pins for SPI communication (SCLK, SDI and SDO respectively). Pin B0 is used as a select pin, as the 9356 has an active high chip select.
Thus you would connect C3 of the master to C3 of the slave, C4 of the master to C5 of the slave and C5 of the master to C4 of the slave.
Connect B0 of the master to pin A5 of the slave, as that is used as the slave select pin of the MSSP. However the polarity of that select line is opposite to that of the 9356.
r.b. |
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Sun May 27, 2007 9:22 pm |
|
|
Thanks reberek.
In view of your suggestion , I modified the master and slave codes removing the rs232 statemnts as I want communication between two pics only.
In the code I am using PORTD as a debug mechanism which has not been used in SPI comunication.I connected them as mentioned in your last post.
The problem is that the code seems to hang-up.
===The slave code=========
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
int8 memory[80], data, instr, address;
#define EEPROM_SELECT PIN_A5
#define EEPROM_DI PIN_C5
#define EEPROM_DO PIN_C4
#define EEPROM_CLK PIN_C3
#define EEPROM_ADDRESS BYTE
#define EEPROM_SIZE 256
/*
void write_data(void)
PURPOSE: Reads data from SPI and writes it to memory
PARAMS: none
RETURNS: None
*/
void write_data(void)
{
PORTD=0x00;
delay_ms(200);
while(!spi_data_is_in());
data = spi_read();
PORTD=data;
delay_ms(200);
if(address >= 0 && address < 80)
{
memory[address] = data;
}
}
/*
BYTE read_data(void)
PURPOSE: To read the memory
PARAMS: none
RETURNS: Data stored in memory
*/
BYTE read_data(void)
{
return (memory[address]);
}
/*
void main(void)
PURPOSE: Peripheral Initialization
*/
void main(void)
{
setup_spi(spi_slave | spi_h_to_l | spi_ss_disabled);
SET_TRIS_D(0);
PORTD=0;
while(true)
{
PORTD=0xFF;
delay_ms(200);
while(!spi_data_is_in());
instr = spi_read();
while(!spi_data_is_in());
address = spi_read();
if (instr == 0x18)
{
instr = spi_read(memory[address]);
}
else if(instr == 0xa)
{
write_data();
}
PORTD=0x00;
delay_ms(500);
}
} |
==========Master Code==============
Code: | #include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include <9356spi.c>
void main()
{
byte value;
EEPROM_ADDRESS address;
SET_TRIS_D(0); // make PORTB all outputs.
PORTD=0;
address=1;
value=0xFF;
init_ext_eeprom();
While(TRUE)
{
PORTD=0xFF;
delay_ms(200);
WRITE_EXT_EEPROM( address, value );
PORTD=READ_EXT_EEPROM(address);
delay_ms(200);
}
} |
|
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Mon May 28, 2007 7:22 am |
|
|
Hi friends,
Continuing my efforts with the SPI & EEPROMS, below is my newest effort to understand the topic.
My current goal is to read and write numbers from 1 to 100 to a fixed location of EEPROM 25640.
As you can see from the code, that before writing the integer to EEPROM address 1, I am displaying the number on PORTA.
I am then reading from EEPROM address 1and dislaying the read value on PORTD.
Pattern on PORTA & PORTD must be the same, which in my case is not. In fact all pins of PORTD are always low, there is no change. PORTA is functioning properly.
Below is the code and the pin connection.
Appreciate any help...
Code: |
=======Master Code=============
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include <25640.c>
void main()
{
byte value;
int8 n;
EEPROM_ADDRESS address;
SET_TRIS_A(0); // make PORTA all outputs.
SET_TRIS_B(0); // make PORTB all outputs.
SET_TRIS_C(0x10); // make pin c4 as input
SET_TRIS_D(0); // make PORTD all outputs.
// initialize to known values.
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
address=1;
//initialize eeprom
init_ext_eeprom();
while (TRUE)
{
for (n=1; n<100;n++)
{
PORTA=n;
delay_ms(200);
WRITE_EXT_EEPROM(address, n);
delay_ms(200);
PORTD=READ_EXT_EEPROM(address);
delay_ms(200);
}//end for
}//end while
} |
F======The Connections========
18f452 EEPROM
RC3 ---> SCK
RC4 ---> SI (Pulled up)
RC5 ---> SO (Pulled up)
RB0 ---> CS
WP ---> GND
HOLD--> GND |
|
|
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Mon May 28, 2007 7:47 am |
|
|
Where in your salve code do you actually send data back to the master?
r.b |
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Tue May 29, 2007 8:32 am |
|
|
Thanks again.
If I use SPI, would the slave respond to data request by the master automatically? |
|
|
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Tue May 29, 2007 8:33 am |
|
|
No. You've got to write code to handle that. There are dozens of examples if you search this forum.
r.b. |
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Tue May 29, 2007 8:23 pm |
|
|
I have seen the examples but what I do not understand is that :
For an EEPROM acting as a slave, do I have to burn the slave code into the EEPROM, in order to make it act accordingly?
Thanks.
Adam |
|
|
rberek
Joined: 10 Jan 2005 Posts: 207 Location: Ottawa, Canada
|
|
Posted: Tue May 29, 2007 9:16 pm |
|
|
OK, now I'm confused. Are you using an 18F452 to emulate an EEPROM, or are you using an actual EEPROM?
An EEPROM with a built-in SPI interface, like the 9356, does not need to be programmed with anything. Write data to it using SPI, and it will store it. Read data using SPI, and you will get data back.
You've been using an 18F452 to emulate an EEPROM though, as far as I know. For that, you need to write code on the PIC to make it emulate a SPI serial EEPROM.
I recommend downloading the datasheets for the 9356 and giving them a read. They'll tell you all you need to know. |
|
|
AdamkT1
Joined: 21 Apr 2007 Posts: 44
|
|
Posted: Wed May 30, 2007 7:40 pm |
|
|
OK, I have a little understanding about SPI now.
I was having a bad time with eeprom for the last two weeks or more.
Since did not had progress, therefore I was forced to see other options also. That is how I then switched to eeprom 25LC640. It was because its VSM (simulation) model is available in Proteus.
Despite trying various examples of I2C & SPI , I still am not able to simulate any of them in Proteus.
Good thing is that I have developed my own driver which is working fine in Proteus. My next goal is to work on floats.
Below is my code for new comers and dedicate it to reberek.
Thanks again reberek.
I wish I could send the proteus file or atleast the pin connections (image file) in order to make things more clearer for the newbies.
Code: |
#include <18F452.h>
#include "25640_test.c"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
void main()
{
int8 n;
EEPROM_ADDRESS address;
SET_TRIS_A(0x02); // Pin A1 is input
SET_TRIS_B(0);
SET_TRIS_C(0);
SET_TRIS_D(0);
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
delay_ms(500); //let the system to stabilize
address=1;
init_ext_eeprom();
while (TRUE)
{
for (n=1; n<100;n++)
{
WRITE_EEPROM(address, n);
delay_ms(200);
PORTD=READ_EEPROM(address);
PORTB=n;
delay_ms(200);
}//end for
}//end while
}
========25640c_test.c==========
#use delay(clock=20000000)
//DEFINE MODES OF EEPROM
#BYTE READ = 0b00000011 // EEPROM READ
#BYTE WRITE = 0b00000011 // EEPROM WRITE
#BYTE WREN = 0b00000011 //EEPROM WRITE ENABLE
#BYTE RDSR = 0b00000011 //EEPROM READ STATUS REGISTER
#ifndef EEPROM_SELECT
#define EEPROM_CLK PIN_A0
#define EEPROM_DI PIN_A1
#define EEPROM_DO PIN_A2
#define EEPROM_SELECT PIN_A3
#endif
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 8192
void init_ext_eeprom(void)
//Check this function
{
output_high(EEPROM_SELECT);
output_low(EEPROM_DI);
output_low(EEPROM_CLK);
}
void init_WREN(void)
{
int8 ctr;
int8 wren;
wren=WREN;
output_low(EEPROM_SELECT); //Chip is selected when low
delay_ms(1); // wait to make the pin stabilize
for(ctr=0; ctr<8; ctr++)
{
output_bit(EEPROM_DI, shift_left(&wren,1,0));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
output_low(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
}
output_high(EEPROM_SELECT);
delay_ms(5); // delay for EEPROM write cycle
}
void write_eeprom(EEPROM_ADDRESS address, BYTE data)
{
int8 ctr;
int8 write;
write=WRITE;
init_WREN(); // Prepare the EEPROM to Write, enable the write enable latch
output_low(EEPROM_SELECT); //Chip is selected when low
delay_ms(1); // Wait to make the pin stabilize
//=======Send the Write Command==============
for(ctr=0; ctr<8; ctr++)
{
output_bit(EEPROM_DI, shift_left(&write,1,0));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
output_low(EEPROM_CLK);
delay_ms(1); //let the pin stabilize
}
//===========Send the address===================
for(ctr=0; ctr<16; ctr++)
{
output_bit(EEPROM_DI, shift_left(&address,1,0));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
output_low(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
}
//===========Send the data===================
for(ctr=0; ctr<8; ctr++)
{
output_bit(EEPROM_DI, shift_left(&data,1,0));
output_high(EEPROM_CLK);
delay_ms(1);
output_low(EEPROM_CLK);
}
output_high(EEPROM_SELECT); //Deselect the chip
delay_ms(5); // delay for EEPROM write cycle
}
BOOLEAN ext_eeprom_ready()
{
BYTE cmd[1], i, data;
cmd[0] = 0x05; //rdsr opcode
output_low(EEPROM_SELECT);
for(i=1; i<=8; ++i) {
output_bit(EEPROM_DI, shift_left(cmd,1,0));
output_high(EEPROM_CLK); //data latches
output_low(EEPROM_CLK); //back to idle
}
for(i=1; i<=8; ++i) {
output_high(EEPROM_CLK); //data latches
shift_left(&data,1,input(EEPROM_DO));
output_low(EEPROM_CLK); //back to idle
}
output_high(EEPROM_SELECT);
return !bit_test(data, 0);
}
BYTE read_eeprom(EEPROM_ADDRESS address)
{
int8 read,data;
int8 ctr;
read=READ;
output_low(EEPROM_SELECT); //Chip is selected when low
delay_ms(1); // Wait to make the pin stabilize
//=======Send the Read Command==============
for(ctr=0; ctr<8; ctr++)
{
output_bit(EEPROM_DI, shift_left(&read,1,0));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
output_low(EEPROM_CLK);
delay_ms(1); // let the pin stabilize
}
//===========Send the address===================
for(ctr=0; ctr<16; ctr++)
{
output_bit(EEPROM_DI, shift_left(&address,1,0));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize.
output_low(EEPROM_CLK);
delay_ms(1); // let the pin stabilize.
}
//===========read the data===================
for(ctr=0; ctr<8; ctr++)
{
shift_left(&data,1,input(EEPROM_DO));
output_high(EEPROM_CLK);
delay_ms(1); // let the pin stabilize.
output_low(EEPROM_CLK);
delay_ms(1); // let the pin stabilize.
}
output_high(EEPROM_SELECT); //Deselect the chip
delay_ms(5); // delay for EEPROM read cycle
return(data);
} |
|
|
|
|
|
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
|