Simple Interrupt program traps/freeze cpu(USART/PIC18F/MICROCHIP/XC8) - c

I am using the following:
pic18f4550,
xc8 compiler,
mplab x ide v3.20,
a transmitter and receiver module (tested with a main program without any interruptions and works).
LED's connected to RD0,RD1 and RD2 (1 = light up)
Buttons connected to RB0,RB1 and RB2 (0 = button is pressed)//does not matter at this point
Apparently everything in this code works fine but with interrupts "void interrupt SerialComm(void)"
(I have made a program without interrupt and led lights up).
The main does not even load up; I have put "PORTD = 0x0F",
(line 3 of main program).
So if the led lights up it means that at least the 3rd line of the main program works.
(at least until that line, but the led didn't.)
Is there any register I have to disable first that I missed out for this?
Also, i have followed most tutorials could there be something i have missed?,
i have seen many programs with #pragma but i'm not sure if i need then when i am using XC8 compiler.
/*
* File: transmit.c
* Author: steve
*
* Created on September 25, 2016, 12:36 AM
*/
#define _XTAL_FREQ 48000000
#include <xc.h>
#include <pic18f4550.h>
void DelayMs(int x);
char ButtonsChecker();
char ButtonsCheckValue = 0; //returned value
char data_received = 0;
void main(void) {
TRISB = 0x0F;
TRISD = 0b00000000;
TRISCbits.TRISC2 = 0; //TXD Power
TRISCbits.TRISC6 = 0; //RC6
TRISCbits.TRISC7 = 1; //RC7
PORTCbits.RC2 = 1;
RCSTA = 0x90;
TXSTA = 0x20;
SPBRG = 77;
RCREG = 0;
RCIF = 0;
PORTDbits.RD0 = 1;
PORTDbits.RD1 = 1;
PORTDbits.RD2 = 1;
RCIE = 1;
TXIE = 0;
PEIE = 1;
GIE = 1;
while (1) {
while (ButtonsChecker()) {
TXREG = ButtonsChecker();
}
//while (!TRMT); // waiting for a whole data frame to be ready for a transmission
//TXREG = PORTB;
//while (!RCIF); // waiting for a whole data frame to be received
//PORTD = RCREG;
}
}
void DelayMs(int x) {
while (x > 0) {
__delay_ms(1);
x--;
}
}
char ButtonsChecker() {
if (PORTBbits.RB0 == 0) {
ButtonsCheckValue = 1;
} else if (PORTBbits.RB1 == 0) {
ButtonsCheckValue = 2;
} else if (PORTBbits.RB2 == 0) {
ButtonsCheckValue = 4;
}//else if (PORTBbits.RB3 == 0) {
// ButtonsCheckValue = 8;}
else ButtonsCheckValue = 0;
return (ButtonsCheckValue);
}
void interrupt ReceiveData() {
if (RCIF == 1) {
RCIF = 0;
~PORTDbits.RD1;
}
}

Everything looks O.K. except that you didn't enable TX and RC interrupts.
So add at USART initiation:
PIE1bits.RCIE = 1;
PIE1bits.TXIE = 1;
At the end of initiation section also add:
INTCONbits.GIE = 1;
...to enable global interrupts.

Related

not able retrieving data from Character in C but the data is there

I am using a i2c sensor on my basys mx3 board for measuring distance.
I've found a demo of this exact sensor with a library for this board and it works as it should.
There are 8 leds on the board adresses with LATA, these represent the distance in centimeters to the object it is pointing at.
The goal is to retrieve the data in centimeters and put it in any accessible variable to print it over UART.
I expected to be able to retrieve the data before it was send to the leds but this seemed beyond my knowledge unfortunatly.
i've tried:
-printing the result that goes into the lata directly to uart(result)
-printing the exact same code that goes to the lata directly to uart (result[1])
-converting the char to an int and then later on print the value of the integer
-copying the data from the result to another char using memcopy (memcpy(distance[1], result[1], 20);) and then printing distance or distance[1] to the uart cmd line.
-retrieving the size of the data and printing it in a char variable sprintf(distance,"%d",sizeof(result[1]));
I do not know what other options i have maybe i am not looking at it the right way.
the code for the I2C library that i am using:
unsigned char I2C_Read(unsigned char slaveAddress,
unsigned char* dataBuffer,
unsigned char bytesNumber)
{
unsigned char status = 0;
unsigned char acknowledge = 0;
unsigned char byte = 0;
int cnt_timeout;
I2C1CONbits.RSEN = 1; // Initiate a start condition
cnt_timeout = 0;
while(I2C1CONbits.RSEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for start condition to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
I2C1TRN = (slaveAddress << 1) + 1;
cnt_timeout = 0;
while(I2C1STATbits.TRSTAT && (++cnt_timeout < I2C_WAIT_TIMEOUT)); // Wait for reception to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
acknowledge = I2C1STATbits.ACKSTAT;
if(acknowledge == 0) //Acknowledge was received
{
for(byte = 0; byte < bytesNumber; byte++)
{
I2C1CONbits.RCEN = 1; //Enable receive mode for I2C
if(byte == (bytesNumber - 1))
{
I2C1CONbits.ACKDT = 1;
}
else
{
I2C1CONbits.ACKDT = 0;
}
cnt_timeout = 0;
while(I2C1CONbits.RCEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for reception to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
dataBuffer[byte] = I2C1RCV;
I2C1CONbits.ACKEN = 1;
cnt_timeout = 0;
while(I2C1CONbits.ACKEN && (++cnt_timeout < I2C_WAIT_TIMEOUT));
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
}
}
else
{
status = 0xFF;
}
I2C1CONbits.ACKEN = 1; //Initiate Acknowledge sequence on SDAx and SCLx pins and transmit ACKDT data bit. Wait for Acknowledge sequence to complete
I2C1CONbits.PEN = 1; //Initiate a stop condition
cnt_timeout = 0;
while(I2C1CONbits.PEN && (++cnt_timeout < I2C_WAIT_TIMEOUT)); //Wait for stop condition to complete
if(cnt_timeout >= I2C_WAIT_TIMEOUT)
{
return 0xFE; // timeout error
}
return status;
}
the code i am using to read the sensor where LATA receives the right distance but any other variable isn't:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <sys/attribs.h>
#include "config.h"
#include "pragma.h"
#include "i2c.h"
#define ADDRESS 0x70
int main (void)
{
TRISA = 0x0;
LATA = 0xF;
I2C_Init(100000);
delay();
char tx_buff[2] = {0x00, 0x51};
char reg_add[1] = {0x02};
char result[2] = {};
while(1)
{
I2C_Write(ADDRESS, tx_buff, 2, 0); // beginnen met meten
delay();// minimaal 65 ms
I2C_Write(ADDRESS, reg_add, 1, 0);
I2C_Read(ADDRESS, result, 2);
delay();
LATA = result[1];
UART_PutString("measured distance is ");
UART_PutString(result);
UART_PutString("cm\n");
}
}
void delay ()
{
_CP0_SET_COUNT(0);
while (_CP0_GET_COUNT() < 4000000)
{
}
}

Issue in interfacing SPI e-ink display with PIC 18F46K22

I am using a PIC 18F46K22 in SPI master mode to communicate with a Waveshare 1.54" ePaper Module. The FOSC frequency is 8Mhz internal and SPI configuration is FOSC/4. So when I check the output on logic-analyzer some output bits are differ from expected. And there is some deviation in SCL.
#include <xc.h>
#include "config.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "main.h"
//#define _XTAL_FREQ 8000000
#define SPI1_DUMMY_DATA 0x0
#define SPI_RX_IN_PROGRESS 0x0
#define MY_BUFFER_SIZE 25
extern UBYTE EPD_Init(const unsigned char* lut);
unsigned char myWriteBuffer[100]="Hi I'm master..";
uint8_t myReadBuffer[100];
uint8_t total;
uint8_t temp;
uint8_t my_data = 0x58;
void UART_Init(void)
{
//69
SPBRG2 = 69;
TXSTA2bits.BRGH = 1;
BAUDCON2bits.BRG16 = 1; // Divisor at 8 bit
TRISDbits.TRISD6 = 0;
TRISDbits.TRISD7 = 1;
RCSTA2bits.SPEN = 1; // Enable serial port
TXSTA2bits.SYNC = 0; // Async operation
TXSTA2bits.TX9 = 0; // No tx of 9th bit
RCSTA2bits.RX9 = 0; // No rx of 9th bit
TXSTA2bits.TXEN = 1; // Enable transmitter
RCSTA2bits.CREN = 1; // Enable receiver
}
void UART_Putch(unsigned char bt)
{
while (!PIR3bits.TX2IF); // hold the program till TX buffer is free
TXREG2 = bt; //Load the transmitter buffer with the received value
}
void UART_Print(unsigned const char *ptr)
{
while (*ptr != 0)
{
UART_Putch(*ptr++);
}
}
unsigned char UART_getch() {
unsigned char temp;
if (RCSTA2bits.OERR) // check for Error
{
RCSTA2bits.CREN = 0; //If error -> Reset
//__delay_ms(10);
RCSTA2bits.CREN = 1; //If error -> Reset
}
while (!PIR3bits.RC2IF); // hold the program till RX buffer is free
temp = RCREG2;
return temp; //receive the value and send it to main function
}
void main()
{
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
TRISBbits.TRISB0 = 0; //RST Pin OUTPUT
TRISBbits.TRISB1 = 0; //DC Pin OUTPUT
TRISBbits.TRISB2 = 0; //CS Pin OUTPUT
TRISBbits.RB3 = 1; //BUSY Pin INPUT
// int i;
TRISD =0;/* PORT initialize as output */
EPD_RST_PIN = 0;
EPD_DC_PIN = 0;
//OSCCON = 0x72; /* Use internal osc. frequency 16 MHz */
OSCCONbits.SCS = 0b10; //Frequency & PLL SETUP
OSCCONbits.IRCF = 0b110; //8 MHz
while (!OSCCONbits.HFIOFS);
OSCTUNEbits.PLLEN = 0; //PLL disable
UART_Init();
SPI_Init_Master(); /* Initialize SPI communication as a master */
if(EPD_Init(lut_full_update) != 0) {
UART_Print("e-Paper init failed\r\n");
while(1);
}
UART_Print("e-Paper init\r\n");
for(uint8_t i = 0; i < 10; i++){
__delay_ms(10);
}
EPD_Clear();
UART_Print("e-Paper cleared\r\n");
for(uint8_t i = 0; i < 10; i++){
__delay_ms(50);
}
while(1)
{
// total = 0;
// //do
// //{
// LATAbits.LATA5=0;
// //total = SPI1_Exchange8bitBuffer(SPI1_DUMMY_DATA, MY_BUFFER_SIZE, &myReadBuffer[total]);
// total = SPI1_Exchange8bit(my_data);
//
// LATAbits.LATA5=1;
// __delay_ms(500);
// __delay_ms(500);
// // Do something else...
//
// //} while(total < MY_BUFFER_SIZE);
// //while(1);
//
// EPD_Clear();
//
// __delay_ms(500);
}
}
void SPI_Init_Master()
{
/* PORT definition for SPI pins*/
TRISCbits.TRISC4 = 1; /* RB0 as input(SDI) */
TRISCbits.TRISC3 = 0; /* RB1 as output(SCK) */
// TRISBbits.TRISB2 = 0; /* RA5 as a output(SS') */
TRISCbits.TRISC5 = 0; /* RC7 as output(SDO) */
/* To initialize SPI Communication configure following Register*/
EPD_CS_PIN = 1;
SSP1STAT=0x00; /* Data change on rising edge of clk , BF=0*/
SSP1CON1=0x20; /* Slave mode,Serial enable, idle state high for clk */
PIR1bits.SSP1IF=0;
/* Disable the ADC channel which are on for multiplexed pin
when used as an input */
ADCON0=0; /* This is for de-multiplexed the SCL
and SDI from analog pins*/
ADCON1=0x0F; /* This makes all pins as digital I/O */
}
uint8_t SPI1_Exchange8bit(uint8_t data)
{
// Clear the Write Collision flag, to allow writing
SSP1CON1bits.WCOL = 0;
SSP1BUF = data;
while(SSP1STATbits.BF == SPI_RX_IN_PROGRESS)
{
}
return (SSP1BUF);
}
uint8_t SPI1_Exchange8bitBuffer(uint8_t *dataIn, uint8_t bufLen, uint8_t *dataOut)
{
uint8_t bytesWritten = 0;
if(bufLen != 0)
{
if(dataIn != NULL)
{
while(bytesWritten < bufLen)
{
if(dataOut == NULL)
{
SPI1_Exchange8bit(dataIn[bytesWritten]);
}
else
{
dataOut[bytesWritten] = SPI1_Exchange8bit(dataIn[bytesWritten]);
}
bytesWritten++;
}
}
else
{
if(dataOut != NULL)
{
while(bytesWritten < bufLen )
{
temp = SPI1_Exchange8bit(SPI1_DUMMY_DATA);
if(temp!=SPI1_DUMMY_DATA)
{
UART_Putch(temp); //uart print
dataOut[bytesWritten] = temp;
bytesWritten++;
}
__delay_ms(5);
}
}
}
}
return bytesWritten;
}
Compare your logic analyser SCK and MOSI timing with that specified for the part at https://www.waveshare.com/wiki/1.54inch_e-Paper_Module:
Note that the MOSI (SDIN) state must be stable on the rising edge of SCK (SCLK). In your case the MOSI transitions are synchronous with the rising edge, and you have a clock transition before the MOSI has the correct D7=0 state. SPI timing is defined by both clock polarity and clock phase - giving four possible clock modes. Compare the Waveshare timing diagram with the 18F46K22 datasheet:
The Waveshare diagram suggests that either CKP=1/CKE=0, or CKP=0/CKE=1 may be used, you have:
SSP1STAT=0x00 ;
SSP1CON1=0x20 ;
Which is CKP=0/CKE=0 (which correlates with your logic analyser trace).
You need on of either:
SSP1STAT=0x20 ; // CKE=1
SSP1CON1=0x20 ; // CKP=0
or
SSP1STAT=0x00 ; // CKE=0
SSP1CON1=0x30 ; // CKP=1
Since idle state (controlled by CKP) of SCK is a don't-care, I suggest leaving that as-is and using the first suggestion - that seems more intuitive somehow.
Note also that your logic analyser must also be set to the same phase/polarity clock mode in order for its presentation of the data to be correct.

TIMER Logic used in PIC15F1516 microcontroller

I am using PIC15F1516 microcontroller, and doing reverse engineering to understand the code without any documentation. I failed to understand use of timer and logic implemented in main.c
Timer0RegValue = 64536.0
Prescalar = 1
Delay = ( (65536-Timer0RegValue)*(Prescalar*4) ) / Fosc = 0.001 Sec
I can understand in the main function timer is updated with value of 1mSec, however, I could not get after how much time ProcessTenthSec() and ProcessTwelfthSec() will get executed?
void TMR1_Initialize(void)
{
//Set the Timer to the options selected in the GUI
//T1CKPS 1:1; T1OSCEN disabled; nT1SYNC synchronize; TMR1CS FOSC/4; TMR1ON disabled;
T1CON = 0x00;
//T1GSS T1G; TMR1GE disabled; T1GTM disabled; T1GPOL low; T1GGO_nDONE done; T1GSPM disabled;
T1GCON = 0x00;
//TMR1H 252;
TMR1H = 0xFC;
//TMR1L 24;
TMR1L = 0x18;
// Load the TMR value to reload variable
// 6396= 0xFC18
// Delay = ( (65536-Timer0RegValue)*(Prescalar*4) ) / Fosc;
// Delay = ( (65536-6396)*(1*4) ) / 500000;
// Delay =
timer1ReloadVal=(TMR1H << 8) | TMR1L;
// Clearing IF flag before enabling the interrupt.
PIR1bits.TMR1IF = 0;
// Enabling TMR1 interrupt.
//PIE1bits.TMR1IE = 1;
// Set Default Interrupt Handler
//TMR1_SetInterruptHandler(TMR1_DefaultInterruptHandler);
// Start TMR1
//TMR1_StartTimer();
}
#define TENTH_SEC_RELOAD 156
#define TWELFTH_SEC_RELOAD 130
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
byTenthSec = TENTH_SEC_RELOAD
byTwelfthSec = TWELFTH_SEC_RELOAD
while (1)
{
if(PIR1bits.TMR1IF)
{
T1CONbits.TMR1ON = 0;
//TMR1H 252;
TMR1H = 0xFC;
//TMR1L 24;
TMR1L = 0x18;
T1CONbits.TMR1ON = 1;
PIR1bits.TMR1IF = 0;
if(--byTenthSec == 0)
{
byTenthSec = TENTH_SEC_RELOAD;
ProcessTenthSec();
}
if(--byTwelfthSec == 0)
{
if(byTwelfthFix--)
{
byTwelfthSec = TWELFTH_SEC_RELOAD ;
}
else
{
byTwelfthFix = 3;
byTwelfthSec = TWELFTH_SEC_RELOAD + 1;
}
ProcessTwelfthSec();
}
}
//if an ADC conversion is in progress do a low priority task
if(uHiPriTasks.HighPriority)
{
if(uHiPriTasks.One)
Function1();
else if(uHiPriTasks.Two)
Function2();
else if(uHiPriTasks.Three)
Function3();
else if(uHiPriTasks.four)
Function4();
else if(uHiPriTasks.five)
Function4();
}
if(uWatchdog.byWatchdog == WDT_ALL_TASKS_COMPLETE)
{
//reset the watchdog task structure
uWatchdog.byWatchdog = 0;
//restart the watchdog timer
CLRWDT();
}
}
}

Timer based interrupt in PIC microcontroller using mikroC for PIC

I am facing a problem while implementing a timer based interrupt in mikroC for PIC.
I want to toggle a port pin for 8 times if there is a keypress at PORTC.F0 and there should be a delay of say 100ms between the toggles.
Normally this would be very easy using a delay function
for (i=0;i<=8;i++)
{
PORTB.F0=~PORTB.F0;
Delay_ms(100);
}
But during the period, any other keypresses are missed by the system. So I thought of implementing the solution using interrupts.
#define SW PORTC.F0
char ttime,i;
volatile flag;
void Inittimer()
{
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0x06;
TMR1L = 0x00;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
void Interrupt()
{
if (TMR1IF_bit)
{
TMR1IF_bit = 0;
TMR1H = 0x06;
TMR1L = 0x00;
ttime--;
if (ttime==0)
{
flag=1;
}
}
}
void main()
{
Inittimer1();
TRISB = 0;
TRISC.F0 = 1;
PORTB = 0x00;
while(1)
{
if (SW==0)
{
ttime=3;
}
if (flag==1)
{
for (i=0;i<=8;i++)
{
PORTB=~PORTB;
flag=0;
}
}
}
}
Nothing is working. Can somebody please help me to correct the code?
Well this doesn't look right:
if (flag==1)
{
for (i=0;i<=8;i++)
{
PORTB=~PORTB;
flag=0;
}
}
When you first see that flag is set, you immediately loop and toggle the output 8 times, without waiting for flag to turn back to 1. That's not right, it's overly simplified.
You need to look for the flag, then toggle the output and clear the flag, and wait for it to to get set again, maintaining the counter in parallel. The for loop is not the proper structure for this, since it will "lock out" the rest of the program and might cause keypresses to be missed.
When you initialize your timer:
void Inittimer()
{
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0x06; // No prescaler? I doubt your clock speed is 40-some KHz!
TMR1L = 0x00;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
Why don't you control the LED directly from the ISR ?
if (ttime)
PORTB.F0 = (--ttime & 1); // ttime is not decremented when led is not blinking.
else
PORTB.F0 = 0; // ensures the LED is off.
To start blinking 8 times:
if (SW==0)
{
PORTB.F0 = 1;
ttime = 16;
}
Note that with a 100ms clock interrupt, the first 'blink' of the LED may last up to 200ms... This is why many like to work with a faster timer interrupt (this has usually other uses as well), controlling the led would require adding a soft post-scaler
if (blinking)
{
if (--blinkTimer == 0)
{
blinkTimer = BLINK_DELAY; // whatever number it takes for 100ms.
PORTB.F0 = (--blinking & 1);
}
}
else
{
PORTB.F0 = 0
}
To start blinking:
if (SW==0)
{
blinking = (2 * BLINKS) - 1;
blinkTimer = BLINK_DELAY;
PORTB.F0 = 1;
}
This should get you a more even first blink.

MicroC rs-485, pic16f887 String sending problems

How can I send the string "MY STRING" from a master pic to a slave?
I'm using MicroC RS-485 library example:
http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/rs-485_library.htm
Im trying to send string from master to slave: and seting dat[7] = "my string"; expecting dat[7] on slave with my string but im geting empty value...
Original code in the link bottom.
Master
char dat[10]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_direction at TRISC2_bit; // set transcieve pin direction
// Interrupt routine
void interrupt() {
RS485Master_Receive(dat);
}
void main(){
long cnt = 0;
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
PORTB = 0;
PORTD = 0;
TRISB = 0;
TRISD = 0;
UART1_Init(9600); // initialize UART1 module
Delay_ms(100);
RS485Master_Init(); // initialize MCU as Master
dat[0] = 0xAA;
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
dat[7] = "MY STRING";
RS485Master_Send(dat,1,160);
RCIE_bit = 1; // enable interrupt on UART1 receive
TXIE_bit = 0; // disable interrupt on UART1 transmit
PEIE_bit = 1; // enable peripheral interrupts
GIE_bit = 1; // enable all interrupts
while (1){
// upon completed valid message receiving
// data[4] is set to 255
cnt++;
if (dat[5]) { // if an error detected, signal it
PORTD = 0xAA; // by setting portd to 0xAA
}
if (dat[4]) { // if message received successfully
cnt = 0;
dat[4] = 0; // clear message received flag
j = dat[3];
for (i = 1; i <= dat[3]; i++) { // show data on PORTB
PORTB = dat[i-1];
} // increment received dat[0]
dat[0] = dat[0]+1; // send back to master
Delay_ms(1);
RS485Master_Send(dat,1,160);
}
if (cnt > 100000) {
PORTD ++;
cnt = 0;
RS485Master_Send(dat,1,160);
if (PORTD > 10) // if sending failed 10 times
RS485Master_Send(dat,1,50); // send message on broadcast address
}
}
}
Slave:
char dat[9]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_direction at TRISC2_bit; // set transcieve pin direction
// Interrupt routine
void interrupt() {
RS485Slave_Receive(dat);
}
void main() {
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
PORTB = 0;
PORTD = 0;
TRISB = 0;
TRISD = 0;
PORTA = 0;
TRISA = 0;
UART1_Init(9600); // initialize UART1 module
Delay_ms(100);
RS485Slave_Init(160); // Intialize MCU as slave, address 160
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that message received flag is 0
dat[6] = 0; // ensure that error flag is 0
RCIE_bit = 1; // enable interrupt on UART1 receive
TXIE_bit = 0; // disable interrupt on UART1 transmit
PEIE_bit = 1; // enable peripheral interrupts
GIE_bit = 1; // enable all interrupts
while (1) {
if(dat[7]=="MY STRING"){
RCA0_bit = 1;
}
if (dat[5]) { // if an error detected, signal it by
PORTD = 0xAA; // setting portd to 0xAA
dat[5] = 0;
}
if (dat[4]) { // upon completed valid message receive
dat[4] = 0; // data[4] is set to 0xFF
j = dat[3];
for (i = 1; i <= dat[3];i++){
PORTB = dat[i-1];
}
dat[0] = dat[0]+1; // increment received dat[0]
Delay_ms(1);
RS485Slave_Send(dat,1); // and send it back to master
}
}
}
char dat[9]; defines an array of 9 bytes, so dat[7] = "MY STRING"; will only store a truncated address not the actual string. memcpy can be used to copy strings from one buffer to another.
see: http://www.cplusplus.com/reference/cstring/memcpy/
dat[7]=="MY STRING" will not work as your comparing the 2 byte address of the string literal "MY STRING" with the single byte stored at dat[7]. If you need to compare strings for differences, strcmp works.
see: http://www.cplusplus.com/reference/cstring/strcmp/

Resources