|
|
View previous topic :: View next topic |
Author |
Message |
edmundopt
Joined: 08 Dec 2011 Posts: 15 Location: Portugal
|
pic18f slave pic16f master SPI vsim |
Posted: Wed Dec 21, 2011 7:29 pm |
|
|
Using ccs v4.124
First of all, are there any known problems using Proteus to VSIM spi functions ?
If not, please look at the code:
Master:
Code: |
#include <16F877A.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#define SPI_SS PIN_A3
// SPI mode definitions.
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
void main()
{
char c;
int8 result;
output_high(SPI_SS); // Initial Slave Select to a high level
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF); // no AD(AnalogDigital) converter
setup_psp(PSP_DISABLED); // no PSP port
setup_timer_1(T1_DISABLED); // no TMR1 timer1
setup_timer_2(T2_DISABLED,0,1); // no TMR2 timer 2
setup_comparator(NC_NC_NC_NC); // no comparator
setup_vref(FALSE);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
while(TRUE)
{
if (rs232_errors==1) putc('!');
c = getc();
switch(c)
{
case '1': // Read ADC on Slave PIC
printf("\n\r value");
c = getc();
output_low(SPI_SS);
spi_write(c); // Send command to slave
output_high(SPI_SS);
delay_us(50); // Give slave some time to respond
output_low(SPI_SS);
result = spi_read(0); // Read response from slave
output_high(SPI_SS);
printf(" - result = %x, %u \n\r", result, result);
break;
/** the rest of the code is basic **/
}
}
}
|
Slave:
Code: |
#pragma case // Case sensitivity is turned on
#list
#include <18F4620.h>
#device adc=8
#FUSES INTRC_IO // for internal osc and followed by setup_oscillator(OSC_32MHZ | OSC_PLL_ON);
#FUSES NOCPD //NO EE protection
#FUSES NOSTVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //Debug mode for use with ICD
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //NO Reset when brownout detected
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST // does not used ADDFSR, ADDULNK, CALLW, MOVSF, MOVSS, PUSHL, SUBFSR, SUBULNK
#FUSES NOLPT1OSC //Timer1 configured for low-power operation
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#use delay(clock=32000000) // internal osc 8mhz * 4
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COMMPORT,ERRORS)
#byte SSPBUF = 0xFC9 // SPI Register address for 18f4620
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
unsigned int8 g_array_rcv[10];
unsigned int8 g_a_pos;
short g_spi_flag;
#int_ssp
void ssp_isr(void)
{
unsigned int8 spi_msg;
spi_msg = SSPBUF;
g_array_rcv[g_a_pos]=spi_msg;
if (spi_msg!=0)
{
if (spi_msg==0xff) // request for 0111 1111
{
SSPBUF = 0x7f;
}
else
{
if (spi_msg==0xfe) // request for 0000 1111
{
SSPBUF = 0x0f;
}
else
{
if (spi_msg==0xfd) // request for 1111 0000
{
SSPBUF = 0xf0;
}
else
{
SSPBUF = spi_msg; // request for spi_msg
}
}
}
g_spi_flag = TRUE;
}
g_a_pos++;
if (g_a_pos==10) g_a_pos=0;
} // end of INT_SSP handler
void main()
{
unsigned int8 a_pos;
g_spi_flag = FALSE;
g_a_pos=0;
setup_adc(ADC_OFF); // no AD(AnalogDigital) converter
setup_psp(PSP_DISABLED); // no PSP port
setup_timer_1(T1_DISABLED); // no TMR1 timer1
setup_timer_2(T2_DISABLED,0,1); // no TMR2 timer 2
setup_timer_3(T3_DISABLED|T3_DIV_BY_1); // no TMR3 timer 3
setup_comparator(NC_NC_NC_NC); // no comparator
setup_oscillator(OSC_32MHZ | OSC_PLL_ON); // INTERNAL OSCILLATOR
setup_spi(SPI_SLAVE | SPI_MODE_0);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(TRUE)
{
if (g_spi_flag)
{
printf("\n\r");
for (a_pos=0;a_pos<10;a_pos++) printf(" %x,",g_array_rcv[a_pos]);
g_spi_flag = FALSE;
}
}
}
|
It works very good, except for the part that the bits sent from the pic18f to the pic16f don't match, for example if 0xff is requested, 0b0011111 is the result, should be 0b01111111
Please notice, that the pic18f receives the byte correctly!
This is using ISIS, will it work in the pcb ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Dec 22, 2011 3:00 am |
|
|
Do a search here.
Proteus, does not correctly simulate just about anything complex on the PIC's.
On a _few_ chips the simulation gets close to reality, but on 99% of chips it differs wildly from the hardware. I have several projects that work in the real hardware, and will not work in Proteus. The simulator originally looked 'useful', but I now rate it - when dealing with PIC's, as not worth wasting time on.
Far better to try in the real board.
Best Wishes |
|
|
edmundopt
Joined: 08 Dec 2011 Posts: 15 Location: Portugal
|
|
Posted: Thu Dec 22, 2011 4:15 am |
|
|
Thank you Ttelmah, I will try it in the real life. I think the code is ok, although I had problems with breadboards testing spi, and some pins and wires too thin and so on.
I searched the forum, specific SPI VSIM I could not find, although I've found your code, I use it to read a memchip
Code: |
#if define (__PCH__)
#byte SSPBUF = 0xFC9
#byte SSPCON = 0xFC6
#byte I2CBUF = 0xFC8
#byte SSPSTAT = 0xFC7
#else
#byte SSPBUF = 0x13
#byte SSPCON = 0x14
#byte I2CBUF = 0x93
#byte SSPSTAT = 0x94
#endif
// Now the SSP handler code.
#DEFINE READ_SSP() (SSPBUF)
#DEFINE WAIT_FOR_SSP() while((SSPSTAT & 1)==0)
#DEFINE WRITE_SSP(x) SSPBUF=(x)
#DEFINE CLEAR_WCOL() SSPCON=SSPCON & 0x3F
|
If you notice mine is based on the PCM programer post, because it works for a full pic to pic spi transaction, is there any example of your code with two pic's ?
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Dec 22, 2011 4:34 am |
|
|
Just search for mentions of Proteus.
You will get many threads, and most will end with the line 'try it in hardware instead'....
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Thu Dec 22, 2011 6:24 am |
|
|
I've used those 'white breadboards' for the past 30 years and have a few tips.
1) Never use any wire bigger than 22ga, even once !.It will deform the 'bus bar strip' connector inside the breadboard.
2) Never try to run high current(>1 amp) through them.Again, you'll cause problems.
3) I have some 20+ years old and they still work fine.
4) If you find a bad 'strip' they can be taken apart and repaired but really just buy a new one, nowadays they are not much money.
5)My typical setup is two boards, clipped together, attached to a piece board using double sided tape.The lower one has an 2X16LCD in the right end, the PIC on the left.The middle space is for devices I always use(RS232 interface, RTC chip).The upper breadboard is for 'devices' of interest.Vinculum,SPI,I2C,analog,etc.
6)I bought a spool of 10 conductor, 22ga solid wire years ago. It's perfect as you get ALL ten colours making it easy to layout and trace your wiring.You'll save hours of 'problem solving' if you only use one colour and misplace a wire or two in the wrong pins!
7) Any project built on a breadboard will work in a PCB.I have made several 16F877 products running at 20MHz, all have worked without problems.
8) Be sure to use decoupling caps(.1 mfd) and good filter caps(470mfd) on each board.
hope this helps |
|
|
|
|
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
|