CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

pic18f slave pic16f master SPI vsim

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
edmundopt



Joined: 08 Dec 2011
Posts: 15
Location: Portugal

View user's profile Send private message

pic18f slave pic16f master SPI vsim
PostPosted: Wed Dec 21, 2011 7:29 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 22, 2011 3:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 22, 2011 4:15 am     Reply with quote

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 Smile

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

View user's profile Send private message

PostPosted: Thu Dec 22, 2011 4:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 22, 2011 6:24 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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