#include <p18f46k22.h>
//#include <usart.h>
/* PIC Configuratings */
#pragma romdata config
#pragma config FOSC = INTIO67, PLLCFG = OFF, PRICLKEN = ON, FCMEN = OFF, IESO = OFF
#pragma config PWRTEN = OFF, BOREN = OFF, BORV = 285 //Normal
#pragma config WDTEN = ON, WDTPS = 32768
#pragma config PBADEN = OFF, HFOFST = OFF, MCLRE = EXTMCLR
#pragma config STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
#pragma config CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTC = OFF, WRTB = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config EBTRB = OFF
#pragma romdata
/* INITIALIZE VARIABLES */
unsigned int CRC;
unsigned char Buffer_Tx[8] = {0x01,0x04,0x00,0x00,0x00,0x22,0x70,0x13}; //Data frame to get info from the fan
//unsigned char Buffer_Tx[8] = {0x01,0x06,0x00,0x42,0x02,0xBC,0x69,0xFB}; //Data frame to actuate on the fan
unsigned char Buffer_Rx[128];
unsigned char Buffer_Rx_Aux[100];
unsigned int RxBuffer = 0;
unsigned int Alarma1_H, Alarma1_L, Alarma2_H, Alarma2_L;
unsigned int Alarma1, Alarma2;
void USART_initialize(void);
unsigned int CRC16 (unsigned char *dirBuffer, unsigned char BytesBuffer);
void RX_Buffer_initialize(void);
void sendData(void);
void VectorInterrupcionAlta (void);
void RutinaInterrupcionAlta (void);
int i;
void main() {
TRISC = 0b11000000;
USART_initialize(); //Initialize USART module
RX_Buffer_initialize();
OSCCONbits.IRCF = 0b111; //Configure Clock Speed to 16 Mhz
//Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE &
// USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 27);
CRC = CRC16(&Buffer_Tx[0],6); //Obtains CheckSUM
Buffer_Tx[6] = (unsigned char)(CRC & 0x00FF);
Buffer_Tx[7] = (unsigned char)((CRC >> 8) & 0x00FF);
while(1)
{
sendData(); //Send Data frame by MODBUS
Alarma1_H = Buffer_Rx[23];
Alarma1_L = Buffer_Rx[24];
Alarma1 = ((Alarma1_H<<8)&0xFF00) + Alarma1_L; //Gets Alarma1 code
Alarma2_H = Buffer_Rx[37];
Alarma2_L = Buffer_Rx[38];
Alarma2 = ((Alarma2_H<<8) & 0xFF00) + Alarma2_L; //Gets Alarma2 code
if(Alarma1 != 0 | Alarma2 !=0)
{
PORTCbits.RC2 = 1; //Activate Relay if alarm detected
}
RxBuffer = 0;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+INTERRUPT SERVICE ROUTINE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//-----------------------------------------------------------------------------
//- HIGH INTERRUPT Addressing -
//-----------------------------------------------------------------------------
#pragma code VectorInterrupcionAlta = 0x08
void VectorInterrupcionAlta (void)
{
_asm
goto RutinaInterrupcionAlta
_endasm
}
//-----------------------------------------------------------------------------
//- HIGH INTERRUPT Function -
//-----------------------------------------------------------------------------
#pragma code
#pragma interrupt RutinaInterrupcionAlta
void RutinaInterrupcionAlta (void)
{
if (PIR1bits.RC1IF)
{ //UART1-BUCLE
if (RCSTA1bits.FERR)
{ //Detect an error in the received byte
}
PIE1bits.RC1IE = 0; //Disable interrupts
//Read USART data
Buffer_Rx[RxBuffer] = RCREG; //Read RX register
//Buffer_Rx[RxBuffer] = Read1USART();
RxBuffer++;
PIR1bits.RC1IF = 0; //Clear rx flag
PIE1bits.RC1IE = 1; //Enable interrupts again
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+USART INICIALIZATION
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void USART_initialize(void){
//Configuration TX and RX pins
TRISCbits.RC6 = 1; //TX intput
TRISCbits.RC7 = 1; //RX input
//TXSTA: Transmit Status and Control Register
TXSTA1bits.SYNC = 0; //Asynchronous mode
TXSTA1bits.TX9 = 0; //8bit transmission
TXSTA1bits.BRGH = 0; //Set LOW Baud rate
TXSTA1bits.TXEN = 1; //Enable transmitter
TXSTA1bits.SENDB = 0; //Disable break
//RCSTA: Receive Status and Control Register
RCSTA1bits.SPEN = 1; //Serial Port enabled
RCSTA1bits.RX9 = 0; //8bit reception
RCSTA1bits.CREN = 1; //Enables Receiver
//Test bits
//RCSTAbits.FERR = 0; //No framing error, cleared by reading
//RCSTAbits.OERR = 0; //No Overrun error, cleared by clearing CREN
//Disable receiver CREN 0
//BAUDCON Control register
BAUDCONbits.BRG16 =0; //8bit baud rate generator
//OSCCON = 0x66;
//SPBRG = 0xCF;
OSCCONbits.IRCF = 0b111;//Configure Clock Speed to 16 Mhz
SPBRG = 25; // Set to 9600 baud rate, 16Mhz, High Speed, BRG16
//Test bits
//BAUDCONbits.RCIDL = 0;//Receive in progress
// USART interrupts configuration
RCONbits.IPEN = 1; // ENABLE interrupt priority
INTCONbits.GIE = 1; // ENABLE interrupts
INTCONbits.PEIE = 1; // ENABLE peripheral interrupts.
PIE1bits.RC1IE = 1; // ENABLE USART receive interrupt
PIE1bits.TX1IE = 0; // DISABLE USART TX interrupt
IPR1 = 0b00110000; // SET RC1 Interrupt as HIGH PROPRITY
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+CHECKSUM CALCULATE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unsigned int CRC16 (unsigned char *dirBuffer, unsigned char BytesBuffer)
{
//------------------------------
unsigned char crc16tmp;
unsigned int crc16;
//------------------------------
for(crc16=0xFFFF; BytesBuffer!=0; BytesBuffer--)
{
crc16 ^= *dirBuffer++;
for(crc16tmp =0; crc16tmp <8; crc16tmp++)
{
if(crc16 & 0x0001)
crc16 =(crc16>>1)^0xA001;
else
crc16 >>=1;
}
}
return(crc16);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+BUFFER INICIALIZATION
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void RX_Buffer_initialize(void){
for (i=0;i<128;i++)
{
Buffer_Rx[i] = 0x00;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+SEND DATA
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void sendData(void)
{
//RS485 in SEND MODE
PORTCbits.RC0 = 1; //Bit C0 set to 5V
PORTCbits.RC1 = 1; //Bit C1 set to 5V
//TXSTA1bits.TXEN = 1; //Start the transmitter
for(i=0;i<8;i++)
{
TXREG1 = Buffer_Tx[i];
Buffer_Rx_Aux[i] = Buffer_Tx[i];
while (TXSTA1bits.TRMT == 0){};
//Write1USART(Buffer_Tx[i]);
}
//TXSTA1bits.TXEN = 0; //Stop the transmitter
//RS485 in RECEIVE MODE
PORTCbits.RC0 = 0; //Bit C0 set to 0V
PORTCbits.RC1 = 0; //Bit C1 set to 0V
}