Hi Gents
Thank for replying,
The issue is, the fram is sent from a PC via RS232, goes to the first PIC(master) and sent to the second pic(Slave) and Then sent out via RS485.
I am not supposed to know the value of the data sent out from the PC.
Here is my pice of code for the Slave.
#include "s_code.h"
#include "delays.h"
#include <p18f4680.h>
//FOSC = ECIO_EC - External Oscillator/ IO On RA6
//PCLKEN = ON - Primary Clock Enable
//FCMEN = OFF - Fail-Safe Clock Monitor disabled
//PWRTEN = OFF - Power Up Timer disabled
//BOREN = OFF - Brown-out Reset disabled in hardware and software
//WDTEN = OFF - WDT is controlled by SWDTEN bit of the WDTCON register
//MCLRE = ON - MCLR pin enabled, RE3 input pin disabled
//LVP = OFF - Single-Supply ICSP disabled
//PBADEN = OFF - PortB<4:0> are configured as digital I/O On reset
//STVREN = OFF - Stack full/underflow will not cause reset
//CPO = OFF - Code protect disabled
/*----------------------------------------------------------------------------*/
//Theses lines do some set up of the compiler and the chip. The are normally called
//configuration fuses.
/*----------------------------------------------------------------------------*/
#pragma config OSC= HS
#pragma config CP0=OFF, WDT=OFF, MCLRE=ON, PBADEN=OFF, BOREN=OFF, PWRT=OFF
#pragma config LVP=OFF, STVREN=OFF, FCMEN=OFF
//OSC=ECIO,
//#pragma code high_vector=0x08
/*-----------------------------------------------------------------------------*/
// Interrupt code section
/*----------------------------------------------------------------------------- */
#pragma code InterruptVectorLow=0x18
void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow //jump to interrupt routine
_endasm
}
//#pragma CLOCK_FREQ 20000000
/*-----------------------------------------------------------------------------*/
// Description: Delay
/*----------------------------------------------------------------------------- */
void delay(unsigned char delayValue)
{
while(delayValue)
--delayValue;
}
/*-----------------------------------------------------------------------------*/
// Description: Configure the MSSP module for SPI
/*----------------------------------------------------------------------------- */
void init_spi() /* Initialise the PIC18F4680 SPI Peripheral*/
{
PORTA = 0x00; //Clear PORTA
PORTB = 0x00; //Clear PORTB
PORTC = 0x00; //Clear PORTC
PORTD = 0x00; //Clear PORTD
TRISCbits.TRISC0 = 0; //Set SS as an Output(chip select)
TRISCbits.TRISC5 = 0; //Set SDO as an output(Serial Data Out)
TRISCbits.TRISC4 = 1; //Set SDI as an Input(Serial Data In)
TRISAbits.TRISA6 = 1; //Set for External Oscillator
SSPCON1 = 0x24; //Enable SPI Slave with clock on SCK pin.
SSPSTAT = 0x40; //Set SMP=0 and CKE=1. Notes: The lower 6 bit is read only
PORTCbits.RC0 = 1; //Disable Chip Select or ss
INTCON = 0x80; //Enable Interruptions
}
/*-----------------------------------------------------------------------------*/
// Initialization of UART
/*----------------------------------------------------------------------------- */
void init_uart(void) // init UART module for 9600bps boud, start bit 1, stopbit 1, parity NONE
{
cUART_data_flg=0; //Init data receive flag to zero (no data)
TRISCbits.TRISC7=1; //Make UART RX pin input
TRISCbits.TRISC6=0; //Make UART TX pin output
SPBRGH = 0x00; //9600bps 20MHz Osc
SPBRG = 0x81;
RCSTAbits.CREN=1; //1 = Enables receiver
RCSTAbits.SPEN=1; //1 = Serial port enabled (configures RX/DT and TX/CK pins as serial port pins)
RCSTAbits.RX9 = 1; //1 = 9-bit Receive Enable bit
BAUDCONbits.BRG16=1; //1 = 16-bit Baud Rate Generator – SPBRGH and SPBRG
TXSTAbits.SYNC=0; //0 = Asynchronous mode
TXSTAbits.BRGH=1; //1 = High speed
TXSTAbits.TXEN=1; //1 = Transmit enabled
RCONbits.IPEN = 1; //Enable Interrupt priority levels
IPR1bits.RCIP=0; //EUSART Receive Interrupt Priority 0 = Low priority
PIE1bits.RCIE=1; //1 = Enables the EUSART receive interrupt
INTCONbits.GIEL = 1; //Enable interrupts
INTCONbits.GIEH = 1;
}
void UART_putc( unsigned char result)
{
TXSTAbits.TXEN=0; //Disable transmission
TXREG = result; //Load txreg with data
TXSTAbits.TXEN=1; //Enable transmission
while(TXSTAbits.TRMT==0); //Wait until the byte is sent
{}
}
/*---------------------------------------------------------------------------------*/
// Initialize Interrupts
/*---------------------------------------------------------------------------------*/
void init_interrupt (void)
{
RCON |= 0x80;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
INTCON2bits.INTEDG0 = 0;
INTCONbits.INT0IE = 1;
}
//----------------------------------------------------------------------------
// Low priority interrupt routine
//----------------------------------------------------------------------------
#pragma code
#pragma interrupt InterruptHandlerLow
void InterruptHandlerLow(void)
{
if (PIR1bits.RCIF==1) //Is interrupt occured by EUSART receive?,
//Then RCREG is full we have new data (cleared when RCREG is read)
{
if(RCSTA&0x06) //More efficient way than following commented method to check for reception error
//If(RCSTAbits.FERR==1 || RCSTAbits.OERR==1 )
{
RCSTAbits.CREN=0; //Overrun error (can be cleared by clearing bit CREN)
cUART_char=RCREG; //Clear Framing error
RCSTAbits.CREN=1;
}
else
{
cUART_char = RCREG; //Read new data into variable
cUART_data_flg = 1; //New data received. so enable flg
}
}
}
/*-----------------------------------------------------------------------------*/
// Description: Read from the SPI (Slave)
/*----------------------------------------------------------------------------- */
unsigned char SPI_Read( void )
{
unsigned char result;
result = SSPBUF; // Clear BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPBUF = 0x00; // Initiate bus cycle
while(!PIR1bits.SSPIF); // Wait until cycle complete
return ( SSPBUF ); // Return with byte read
}
/*----------------------------------------------------------------------*/
void main()
{
unsigned char result[32];
unsigned char rs485_data_ready = 0;
unsigned char checksum;
int j = 0;
int i=0;
init_spi(); // Init SPI module.
init_uart(); // Init UART module
//init_interrupt();
while(1) // Infinite loop which handles incoming data as they arrive
{
// Main function of chip is to receive data from Master via SPI, and send to system under test via RS485 - and that's it.
// So after initialization of registers, wait until chip select line is low.
while (!PIR1bits.SSPIF); // wait until interrupt flag is triggered - signifies data in SSPBUF.
result[j] = SPI_Read(); // Read the data from SPI.
if (result[j] == 0x02) // Right data coming in?(STX)
{
j++;
// Because we've detected STX, we can assume this signifies valid data we want to receive.
// We don't know the length of data, so we'll use another forever loop until we "break" it i.e. exit the loop after receiving ETX or
// we've reached the tolerance level (maximum size) of the receive buffer.
while(1)
{
while (!PIR1bits.SSPIF); // wait until data - as above
result[j] = SPI_Read(); // Read the data from SPI.
// 1. ETX data detected.
if (result[j] == 0x03)
{
// Calculate checksum
unsigned char sum, i;
for(i=2; i<=(j-2);i++) // Add data bytes in frame i.e. add from result[2] to result[j-2]
{
sum = sum + result;
}
//Do 2's complement to get checksum
checksum = ~sum + 1;
// Compare with checksum received from PC and validate frame has no erros
if (checksum == result[j-2])
{
rs485_data_ready = 1; // Set flag to signify valid data to send over SPI to slave.
}
else
{
rs485_data_ready = 0;
}
break;
}
// 2. J(length of received data) is greater than maximum buffer size i.e. 32, and we still not received ETX
else if ((result[j] != 0x03) && ((j+1) > 31))
{
break;
}
j++;
}
}
// Valid data ready for slave transmission?
if (rs485_data_ready)
{
rs485_data_ready = 0;
// Write to System under test for RS485 transimission here
UART_putc(cUART_char);
}
}
}