Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

send Array from UART

Status
Not open for further replies.

treyz

Member level 5
Joined
Sep 26, 2012
Messages
93
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
2,065
Hi,

I am having a problem of tranmitting an frame from UART(PIC used is 18f4680).
Basically, I am getting that frame from SPI communication(PIC slave) and I need to send it via RS485, I have been told that I can still une UART, it is just the hardware which needs some modifications(transceiver etc..).

But my issue is, I don't know how to write my routine to send that frame.
Frame is such: STX-ADDR-DATA-ETX ==> 8 bits each.

my compiler is c18 from Mplab
Do you have any idea?
 

Try something like:
Code:
struct DataFrame {
   char STX;
   char ADDR;
   char DATA;
   char ETX;
   // other data members goes here...
} frame;

// In your transmitter routine use something like
#define SIZE_OF_DATAFRAME 4  // Replace with the size of your DataFrame in bytes
int i;

for(i=0; i<SIZE_OF_DATAFRAME; i++) {
    txbuffer= *(&frame+ i);  // Don't know the name of the transmit register, replace with the correct one
    // Wait until current byte transmitted...
}

That's just what popped in, not sure it'll work or not but worth a try.
 
Try to use the following function.
Code:
void uart_str(const  char *str)
{
        while(*str!='\0')
        {
                uart_char(*str);
                str++;
        }
}
main()
{
   //give declarations
uart_str("picontroller");
}
 

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);

}
}
}
 

Why don't you use code tags when posting code and what's the problem with your code?
 

Hi,

Sorry, I am new, I will do it next tme.
I don't know how to send my frame via RS485.
Is my code right?

Regards
 

Well I can't debug all that code. Have you tried using the suggestions proposed? Can you please isolate your rs485 part of your code and post again. By the way which IC are you using for rs485 communication?
 

Hi,

Yes I have tried, and no changes.
I am using MAX1487 for this application.

Here my RS485 part of my code:

/*-----------------------------------------------------------------------------*/
// 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
{}
}-------------------------------------------------------------
.
.
.
// 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);
//uart_str("picontroller");
.
.
.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top