...Timer0 is not getting higher priority than serial interrupt so its not working...
How can i unload values from STACK register (to waste the return value of function).
#include <p18cxxx.h>
#include <delays.h>
#include <stdlib.h>
#include <stdio.h>
#include <usart.h>
#include <timers.h>
#define MAX_EN PORTAbits.RA0
#define TX_MODE 1
#define RX_MODE 0
#define MY_ADDRESS 'a'
#define CM_CHANGE_POWER 100 // Change Power Source [0, 1, 2 ... ]
#define CM_UPDATE_TOGGLES 101 // Change Toggles to ones sent from Master
#define CM_UPDATE_DIMMERS 102 // Change Dimmers to ones sent from Master
#define CM_SEND_TOGGLES 103 // Send Toggles to Master
#define CM_SEND_DIMMERS 104 // Send Dimmers to Master
#define CM_WRITE_EEPROM 105 // Write to EEPROM sent from Master
#define CM_READ_EEPROM 106 // Send EEPROM to Master
#define CM_MASTER 107 // Master On/Off
#define ACK 200 // Acknowlegdment
#define TEST 201 // Acknowlegdment
#define RX_MODE 0 // RA 484 En pin
#define TX_MODE 1 // RA 484 En pin
#define B1 PORTDbits.RD0
#define B2 PORTDbits.RD1
#define B3 PORTDbits.RD2
#define B4 PORTDbits.RD4
#define B5 PORTDbits.RD5
#define B6 PORTDbits.RD6
#pragma config WDT = OFF, LVP = OFF, OSC = HS, DEBUG = OFF
unsigned char receive_count = 0; // Num of Bytes to receive from MASTER
unsigned char transmit_count = 0; // Num of Bytes to transmit from MASTER
unsigned char receive_bytes[5] = {0};
unsigned char transmit_bytes[5] = {0};
void ParseInstruction(unsigned char);
void senddata(unsigned char);
void SlaveSetting(void);
unsigned long timercount = 0;
void T0_handler (void);
#pragma code T0_interrupt = 0x18
void T0_int (void)
{
_asm goto T0_handler _endasm
}
#pragma code
#pragma interrupt T0_handler
void T0_handler (void)
{
}
/* ~~~~ Interrupt Handler ~~~~ */
void rx_handler (void);
#pragma code rx_interrupt = 0x08
void rx_int (void)
{
_asm goto rx_handler _endasm
}
#pragma code
#pragma interrupt rx_handler
void rx_handler (void)
{
unsigned char c;
unsigned char i,j = 0;
if(PIR1bits.RCIF == 1)
{
c = ReadUSART();
if(c != 68){return;} // Compare Address in NINE Bit mode
TMR0H = 0; // Reset Timer0 to 0x0000
TMR0L = 0;
PIE1bits.RCIE = 0; // Disable Serial Interrupt
INTCONbits.T0IF = 0;
INTCONbits.T0IE = 1; // Enable Timer0 Interrupt for timeouts
RCSTAbits.RX9 = 0; // Read data byte now (without Nine bit)
while(!DataRdyUSART());
c = ReadUSART(); // Read Instruction
ParseInstruction(c);
for(i = 0; i < receive_count; i++)
{
while(!DataRdyUSART());
receive_bytes = ReadUSART(); // Fill received bytes
}
MAX_EN = TX_MODE;
TXSTAbits.TX9 = 0;
//Delay10KTCYx(254);
Delay10KTCYx(254);
for(j = 0; j < transmit_count; j++)
{
senddata(0x11); // Transmit required bytes
Delay1KTCYx(1);
}
senddata(ACK);
Delay1KTCYx(1);
//while(!DataRdyUSART());
//putrsUSART((const far rom char *)"SLAVE 1!");
}
if(INTCONbits.T0IF == 1 && INTCONbits.T0IE == 1)
{
timercount++;
if(timercount > 3){SlaveSetting();PORTAbits.RA3 = ~PORTAbits.RA3;}
PORTAbits.RA2 = ~PORTAbits.RA2;
INTCONbits.T0IF = 0;
}
//else{return;}
SlaveSetting(); // Go back to becoming Slave
}
unsigned char button = 0;
void senddata(unsigned char data)
{
//while(BusyUSART());
USART_Status.TX_NINE = 0;
WriteUSART(data);
while(BusyUSART());
}
void sendaddress(unsigned char data)
{
//while(BusyUSART());
USART_Status.TX_NINE = 1;
WriteUSART(data);
while(BusyUSART());
}
void process(void)
{
switch(button)
{
case 1:
sendaddress(68);
break;
case 2:
sendaddress(66);
break;
case 3:
sendaddress(70);
break;
case 4:
senddata(68);
break;
case 5:
senddata(66);
break;
case 6:
senddata(70);
break;
}
button = 0;
}
void main(void)
{
unsigned char i;
//OSCCON = 0x70;
ADCON1 = 0x0F; // make all AN (analog) pins digital (for bit ref)
TRISB = 0b00000000;
TRISA = 0b00000000; // First 5 bits (RA0-RA4) are inputs
TRISC = 0b10000000; // Tx and Rx to input (Tx input as per datasheet)
TRISD = 0xFF;
PORTA = 0;
PORTB = 0; // BUS to be set to 0 before PORTC to avoid junk to latch
PORTC = 0b00000000;
PORTD = 0x00;
// Assumes FOSC = 4 Mhz, 9600 bps.
OpenUSART (
USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_NINE_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 25
);
OpenTimer0 (TIMER_INT_OFF & T0_SOURCE_INT & T0_16BIT & T0_PS_1_1);
MAX_EN = RX_MODE;
RCONbits.IPEN = 1; // Enable interrupt priority
//IPR1bits.RCIP = 1; // Enable all high priority interrupts
INTCONbits.GIEH = 1;
PIR1bits.RCIF = 0; // Clear Receive Interrupt Flag
while(1){
if(B1 == 1){button = 1;while(B1);}
if(B2 == 1){button = 2;while(B2);}
if(B3 == 1){button = 3;while(B3);}
if(B4 == 1){button = 4;while(B4);}
if(B5 == 1){button = 5;while(B5);}
if(B6 == 1){button = 6;while(B6);}
process();
//USART_Status.RX_NINE = 0;
}
}
void ParseInstruction(unsigned char ins)
{
receive_count = 0;
transmit_count = 0;
switch(ins)
{
case CM_CHANGE_POWER:
receive_count = 1;
break;
case CM_UPDATE_TOGGLES:
receive_count = 1;
break;
case CM_UPDATE_DIMMERS:
receive_count = 1;
break;
case CM_SEND_TOGGLES:
transmit_count = 1;
break;
case CM_SEND_DIMMERS:
transmit_count = 1;
transmit_bytes[0] = 0x10;
break;
case CM_WRITE_EEPROM:
receive_count = 2; // Address and Data
break;
case CM_READ_EEPROM:
receive_count = 1; // Address
transmit_count = 1; // Data
break;
case CM_MASTER:
receive_count = 1;
break;
}
}
void SlaveSetting(void)
{
timercount = 0;
INTCONbits.T0IE = 0; // Disable Timer0 Interrupt for timeouts
RCSTAbits.RX9 = 1;
TXSTAbits.TX9 = 1;
PIR1bits.RCIF = 0;
MAX_EN = RX_MODE;
PIE1bits.RCIE = 1; // Enable Serial Interrupt
}
I do not want to see any delays in an ISRwhile(!DataRdyUSART());
Delay10KTCYx(254);
for(j = 0; j < transmit_count; j++)
{
senddata(0x11); // Transmit required bytes
Delay1KTCYx(1);
}
void rx_handler (void)
{
unsigned char c;
unsigned char i,j = 0;
if(PIR1bits.RCIF == 1)
{
c = ReadUSART();
if(c != 68){return;} // Compare Address in NINE Bit mode
TMR0H = 0; // Reset Timer0 to 0x0000
TMR0L = 0;
PIE1bits.RCIE = 0; // Disable Serial Interrupt
INTCONbits.T0IF = 0;
INTCONbits.T0IE = 1; // Enable Timer0 Interrupt for timeouts
RCSTAbits.RX9 = 0; // Read data byte now (without Nine bit)
while(!DataRdyUSART());
c = ReadUSART(); // Read Instruction
ParseInstruction(c);
for(i = 0; i < receive_count; i++)
{
while(!DataRdyUSART());
receive_bytes[i] = ReadUSART(); // Fill received bytes
}
MAX_EN = TX_MODE;
TXSTAbits.TX9 = 0;
//Delay10KTCYx(254);
Delay10KTCYx(254);
for(j = 0; j < transmit_count; j++)
{
senddata(0x11); // Transmit required bytes
Delay1KTCYx(1);
}
senddata(ACK);
Delay1KTCYx(1);
//while(!DataRdyUSART());
//putrsUSART((const far rom char *)"SLAVE 1!");
}
if(INTCONbits.T0IF == 1 && INTCONbits.T0IE == 1)
{
timercount++;
if(timercount > 3){SlaveSetting();PORTAbits.RA3 = ~PORTAbits.RA3;}
PORTAbits.RA2 = ~PORTAbits.RA2;
INTCONbits.T0IF = 0;
}
//else{return;}
SlaveSetting(); // Go back to becoming Slave
}
Is there any way to check that a node with a certain address is on the BUS WITHOUT timeout?
In general you must scan to determine which nodes are present....
What i am asking is that there can be like 50 nodes connected on BUS. Is there any way for the MASTER to know all their addresses and in case a new Node is connected, Master should scan again for new Nodes and detect it (Like in network discovery).
You can not. You can keep a table of known active nodes. It would take some sort of magic to know a node is there without trying to communicate with it. But it pasys to reduce the timeout period to the shortest that works well for the network. You could read the value from the timeout counter when each packet is complete. Write a few lines of code to save the value if it is the greatest seen yet. Run the network for a while and then adjust your timeout accordingly. Or juse a scope to get a ballpark number....
How do i detect if the Node i am trying to send data to exists or not (otherthan waiting for ACK signal and hitting timeout)
You are now outside of what I have done. Adding or removing a node from a working network is called Hot-Plugging. Not all transeceivers are able to do this cleanly. Check the datasheets.. On the data BUS, if any of the controller is powered off and the RS-485 transceiver is still On, the complete BUS gets corrupted (data of other nodes stop working).
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?