|
|
View previous topic :: View next topic |
Author |
Message |
BABA
Joined: 07 Dec 2003 Posts: 5
|
strange bootup on pic16F876A and pic16f873A |
Posted: Sun Oct 24, 2004 1:01 pm |
|
|
hello guys,
I've made a design under 16F876A (and I migrate to 16F873A)
design define a simplified modbus (RS485) that manages some relays and read counters that detect input change from LtoH levels.
I'm facing strange bootup on these 2 devices with same program.
Sometime applications bootup correcty, and sometime the EEPROM used to keep parameters or RS232 are out and then application is out of order.
Have you ever been facing on this strange behaviour in your design using pic16F876(873)A. I have tried changing value on MCLR, from a simple resistor pullup'ed to VDD, to a small rc value up to 1seconde RC value on VDD...
I doesn't understand why if could be a code issue, because the code operate sometime...But I don't know what can happening :(
If anyone have a suggestion...
Stefan. |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Sun Oct 24, 2004 2:25 pm |
|
|
Make sure LVP is disabled. I've had problem with that before when I have left the LVP pin floating :-( |
|
|
BABA
Joined: 07 Dec 2003 Posts: 5
|
|
Posted: Mon Oct 25, 2004 12:59 am |
|
|
NOLVP option is set #fuse list... |
|
|
BABA
Joined: 07 Dec 2003 Posts: 5
|
|
Posted: Mon Oct 25, 2004 1:02 am |
|
|
here is hte code of the main program...if you see something wrong :)
///////////////////////////////////////////////////////////
#include <16F873A.h>
#define FREQUENCY 20000000
#fuses HS,PROTECT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=FREQUENCY)
///////////////////////////////////////////////////////////
// Definition des parametres generaux
///////////////////////////////////////////////////////////
// La pin d'interruption Ext_INT est defini sur la PIN RBO
#define Horloge1 PIN_C3
#define Horloge2 PIN_C2
#define Horloge3 PIN_C1
#define Horloge4 PIN_C0
#define Id_val0 PIN_A5
#define Id_val1 PIN_B7
#define Id_val2 PIN_B6
#define Id_val3 PIN_B5
#define Id_val4 PIN_B4
#define Id_val5 PIN_B3
#define Id_val6 PIN_B2
#define Id_val7 PIN_B1
#define Relais1 PIN_A3
#define Relais2 PIN_A2
#define Relais3 PIN_A1
#define Relais4 PIN_A0
#define Div200 PIN_A4
//#define EN485 PIN_C4
//#define TX485 PIN_C6
//#define RX485 PIN_C7
///////////////////////////////////////////////////////////
#include <modbus_slave.c>
///////////////////////////////////////////////////////////
// definitions des variables globales
int32 h1_compt_debit,h2_compt_debit,h3_compt_debit,h4_compt_debit;
int8 h2_compt_debit_200,h4_compt_debit_200;
int1 h1_new_edge,h2_new_edge,h3_new_edge,h4_new_edge;
int8 relais;
int1 Compt_Div200;
///////////////////////////////////////////////////////////
// interruption externe detection une problable coupure de courant:
// sauvegarde du contenu des compteurs debits et extinction des relais
///////////////////////////////////////////////////////////
#int_ext
void ext_isr() {
//arret des sortie
output_high(Relais1);
output_high(Relais2);
output_high(Relais3);
output_high(Relais4);
// ecriture des parametres en memoire eeprom
write_eeprom(0,(h1_compt_debit));
write_eeprom(1,(h1_compt_debit>>8));
write_eeprom(2,(h1_compt_debit>>16));
write_eeprom(3,(h1_compt_debit>>24));
write_eeprom(4,(h2_compt_debit));
write_eeprom(5,(h2_compt_debit>>8));
write_eeprom(6,(h2_compt_debit>>16));
write_eeprom(7,(h2_compt_debit>>24));
write_eeprom(8,(h3_compt_debit));
write_eeprom(9,(h3_compt_debit>>8));
write_eeprom(10,(h3_compt_debit>>16));
write_eeprom(11,(h3_compt_debit>>24));
write_eeprom(12,(h4_compt_debit));
write_eeprom(13,(h4_compt_debit>>8));
write_eeprom(14,(h4_compt_debit>>16));
write_eeprom(15,(h4_compt_debit>>24));
write_eeprom(16,h2_compt_debit_200);
write_eeprom(17,h4_compt_debit_200);
write_eeprom(18,relais);
// disable all interrupts
disable_interrupts(INT_EXT);
disable_interrupts(GLOBAL);
}
///////////////////////////////////////////////////////////
#int_timer1
void timer_isr() {
// definitions des variables locales
///////////////////////////////////////////////////////////
// verifie si une nouvelle impulsion est detecté sur l'horloge1
if ((input(Horloge1)==1) && (h1_new_edge==1)){
// incremente le compteur de debit
h1_compt_debit++;
// fin du traitement,
// on bloque la detection de l'etat haut sur l'entrée horloge
h1_new_edge=0;
}
// lorsque l'horloge repasse a zero, on accepte a nouveau la detection de
// l'etat haut de l'horloge
else if (input(Horloge1)==0){
h1_new_edge=1;
}
///////////////////////////////////////////////////////////
// verifie si une nouvelle impulsion est detecté sur l'horloge2
if ((input(Horloge2)==1) && (h2_new_edge==1)){
// incremente le compteur de debit
if (Compt_Div200==1){
h2_compt_debit_200++;
if (h2_compt_debit_200==0xC7){
h2_compt_debit++;
h2_compt_debit_200=0;
}
}else{
h2_compt_debit++;
}
// fin du traitement,
// on bloque la detection de l'etat haut sur l'entrée horloge
h2_new_edge=0;
}
// lorsque l'horloge repasse a zero, on accepte a nouveau la detection de
// l'etat haut de l'horloge
else if (input(Horloge2)==0){
h2_new_edge=1;
}
///////////////////////////////////////////////////////////
// verifie si une nouvelle impulsion est detecté sur l'horloge3
if ((input(Horloge3)==1) && (h3_new_edge==1)){
// incremente le compteur de debit
h3_compt_debit++;
// fin du traitement,
// on bloque la detection de l'etat haut sur l'entrée horloge
h3_new_edge=0;
}
// lorsque l'horloge repasse a zero, on accepte a nouveau la detection de
// l'etat haut de l'horloge
else if (input(Horloge3)==0){
h3_new_edge=1;
}
///////////////////////////////////////////////////////////
// verifie si une nouvelle impulsion est detecté sur l'horloge4
if ((input(Horloge4)==1) && (h4_new_edge==1)){
// incremente le compteur de debit
if (Compt_Div200==1){
h4_compt_debit_200++;
if (h4_compt_debit_200==0xC7){
h4_compt_debit++;
h4_compt_debit_200=0;
}
}else{
h4_compt_debit++;
}
// fin du traitement,
// on bloque la detection de l'etat haut sur l'entrée horloge
h4_new_edge=0;
}
// lorsque l'horloge repasse a zero, on accepte a nouveau la detection de
// l'etat haut de l'horloge
else if (input(Horloge4)==0){
h4_new_edge=1;
}
// set timer1
set_timer1(32767);
}
///////////////////////////////////////////////////////////
void main() {
// definitions des variables locales
int8 system_id;
int8 data[4];
int8 counter_prog;
//traitement initial:
// lecture en EEPROM des compteurs de debits
h1_compt_debit = read_eeprom(3);
h1_compt_debit <<= 8;
h1_compt_debit |= read_eeprom(2);
h1_compt_debit <<= 8;
h1_compt_debit |= read_eeprom(1);
h1_compt_debit <<= 8;
h1_compt_debit |= read_eeprom(0);
h2_compt_debit = read_eeprom(7);
h2_compt_debit <<= 8;
h2_compt_debit |= read_eeprom(6);
h2_compt_debit <<= 8;
h2_compt_debit |= read_eeprom(5);
h2_compt_debit <<= 8;
h2_compt_debit |= read_eeprom(4);
h3_compt_debit = read_eeprom(11);
h3_compt_debit <<= 8;
h3_compt_debit |= read_eeprom(10);
h3_compt_debit <<= 8;
h3_compt_debit |= read_eeprom(9);
h3_compt_debit <<= 8;
h3_compt_debit |= read_eeprom(8);
h4_compt_debit = read_eeprom(15);
h4_compt_debit <<= 8;
h4_compt_debit |= read_eeprom(14);
h4_compt_debit <<= 8;
h4_compt_debit |= read_eeprom(13);
h4_compt_debit <<= 8;
h4_compt_debit |= read_eeprom(12);
h2_compt_debit_200 = read_eeprom(16);
h4_compt_debit_200 = read_eeprom(17);
// lecture en EEPROM de l'info relais
relais = read_eeprom(18);
// affecte les infos de relais afin de piloter les relais
output_bit(Relais1,((relais) & 0x1));
output_bit(Relais2,((relais) & 0x2));
output_bit(Relais3,((relais) & 0x4));
output_bit(Relais4,((relais) & 0x8));
// recuperation de l'ID du systeme
system_id = 0;
system_id = input(Id_val7);//MSB: bit7
system_id <<= 1;
system_id |= input(Id_val6); //bit6
system_id <<= 1;
system_id |= input(Id_val5); //bit5
system_id <<= 1;
system_id |= input(Id_val4); //bit4
system_id <<= 1;
system_id |= input(Id_val3); //bit3
system_id <<= 1;
system_id |= input(Id_val2); //bit2
system_id <<= 1;
system_id |= input(Id_val1); //bit1
system_id <<= 1;
system_id |= input(Id_val0); //bit0
// initialise l'esclave modbus
init_modbus_slave(system_id);
// verifie si le pre-diviseur est activé
if (input(Div200)==1){Compt_Div200=1;}
else{Compt_Div200=0;}
// efface le bit de programmation des compteurs
counter_prog=0;
// definitions des interruptions
// Detection d'un front montant sur la pin d'interruption
ext_int_edge(H_TO_L);
// Le Timer1 is incremente 5 Millions de fois par seconde ((20Mhz/4))
// L'interruption apparait tous les 65536 cycles (1/((20Mhz/4)))*65536 soit environ 13ms.
// Le temps defini devra etre de 6.5ms donc le timer sera pre-regle a la moitié de sa valeur.
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(32767);
// validation des interruptions
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
// boucle infini
while(TRUE){
//lecture dans la memoire modbus
//address0x12: 1byte
modbus_read(0x12,data,1);
counter_prog=(data[0] & 0x1);
// mode programmation des compteurs
if (counter_prog==1){
//effacement des compteur intermediaire
h2_compt_debit_200=0;
h4_compt_debit_200=0;
// lecture dans la memoire modbus
// lecture de la valeur du compteur debit 1
modbus_read(0x0,data,4);
//address 0x0: word msb
h1_compt_debit=0;
h1_compt_debit|=data[0];//high msb
h1_compt_debit<<=8;
h1_compt_debit|=data[1];//low msb
h1_compt_debit<<=8;
//address 0x2: word lsb
h1_compt_debit|=data[2];//high lsb
h1_compt_debit<<=8;
h1_compt_debit|=data[3];//low lsb
// lecture dans la memoire modbus
// lecture de la valeur du compteur debit 2
modbus_read(0x4,data,4);
//address 0x4: word msb
h2_compt_debit=0;
h2_compt_debit|=data[0];//high msb
h2_compt_debit<<=8;
h2_compt_debit|=data[1];//low msb
h2_compt_debit<<=8;
//address 0x6: word lsb
h2_compt_debit|=data[2];//high lsb
h2_compt_debit<<=8;
h2_compt_debit|=data[3];//low lsb
// lecture dans la memoire modbus
// lecture de la valeur du compteur debit 3
modbus_read(0x8,data,4);
//address 0x8: word msb
h3_compt_debit=0;
h3_compt_debit|=data[0];//high msb
h3_compt_debit<<=8;
h3_compt_debit|=data[1];//low msb
h3_compt_debit<<=8;
//address 0xA: word lsb
h3_compt_debit|=data[2];//high lsb
h3_compt_debit<<=8;
h3_compt_debit|=data[3];//low lsb
// lecture dans la memoire modbus
// lecture de la valeur du compteur debit 4
modbus_read(0xC,data,4);
//address 0xC: word msb
h4_compt_debit=0;
h4_compt_debit|=data[0];//high msb
h4_compt_debit<<=8;
h4_compt_debit|=data[1];//low msb
h4_compt_debit<<=8;
//address 0xE: word lsb
h4_compt_debit|=data[2];//high lsb
h4_compt_debit<<=8;
h4_compt_debit|=data[3];//low lsb
}else{
// ecriture dans la memoire modbus
// address 0x0: 4bytes (2words)
// ecriture de la valeur du compteur debit 1
//address 0x0: word msb
data[0]=((h1_compt_debit >> 24) & 0xFF);//high msb
data[1]=((h1_compt_debit >> 16) & 0xFF);//low msb
//address 0x2: word lsb
data[2]=((h1_compt_debit >> 8) & 0xFF);//high lsb
data[3]=(h1_compt_debit & 0xFF);//low lsb
modbus_write(0x0,data,4);
// address 0x4: 4bytes (2words)
// ecriture de la valeur du compteur debit 2
//address 0x4: word msb
data[0]=((h2_compt_debit >> 24) & 0xFF);//high msb
data[1]=((h2_compt_debit >> 16) & 0xFF);//low msb
//address 0x6: word lsb
data[2]=((h2_compt_debit >> 8) & 0xFF);//high lsb
data[3]=(h2_compt_debit & 0xFF);// low lsb
modbus_write(0x4,data,4);
// address 0x8: 4bytes (2words)
// ecriture de la valeur du compteur debit 3
//address 0x8: word msb
data[0]=((h3_compt_debit >> 24) & 0xFF);//high msb
data[1]=((h3_compt_debit >> 16) & 0xFF);//low msb
//address 0xA: word lsb
data[2]=((h3_compt_debit >> 8) & 0xFF);//high lsb
data[3]=(h3_compt_debit & 0xFF);// low lsb
modbus_write(0x8,data,4);
// address 0xC: 4bytes (2words)
// ecriture de la valeur du compteur debit 4
//address 0xC: word msb
data[0]=((h4_compt_debit >> 24) & 0xFF);//high msb
data[1]=((h4_compt_debit >> 16) & 0xFF);//low msb
//address 0xE: word lsb
data[2]=((h4_compt_debit >> 8) & 0xFF);//high lsb
data[3]=(h4_compt_debit & 0xFF);// low lsb
modbus_write(0xC,data,4);
}
//lecture dans la memoire modbus
//address0x10: 2byte
modbus_read(0x10,data,2);
relais=(data[1] & 0xF);
// affecte les infos recu du maitre afin de piloter les relais
output_bit(Relais1,((relais) & 0x1));
output_bit(Relais2,((relais) & 0x2));
output_bit(Relais3,((relais) & 0x4));
output_bit(Relais4,((relais) & 0x8));
}
} |
|
|
BABA
Joined: 07 Dec 2003 Posts: 5
|
|
Posted: Mon Oct 25, 2004 1:03 am |
|
|
here is the modbus_slave.c file called in the main project
///////////////////////////////////////////////////////////
#define EN485 PIN_C4
#define TX485 PIN_C6
#define RX485 PIN_C7
///////////////////////////////////////////////////////////
#define BAUDRATE 57600
#define PAR N
///////////////////////////////////////////////////////////
#define MAX_STREAM 17
#define MAX_MEM 32
///////////////////////////////////////////////////////////
#define BROADCAST_ADDRESS 0x0
#define MEM_READ_WORD 0x3
#define MEM_WRITE_SINGLE_WORD 0x6
#define MEM_WRITE_MULTIPLE_WORD 0x10
///////////////////////////////////////////////////////////
#define TIMER_DIV 128
#define TIMEOUT_VAL ((12*4*1000000)/BAUDRATE)
#define TIMEOUT_STEP ((4*TIMER_DIV*1000000)/FREQUENCY)
#define TIMEOUT (256-(TIMEOUT_VAL/TIMEOUT_STEP))
///////////////////////////////////////////////////////////
#bit Timer0IF = 0xB.2
#bit Timer1IF = 0xC.0
#bit Timer2IF = 0xC.1
///////////////////////////////////////////////////////////
// Reserved for debug purpose
//#define DEBUG
///////////////////////////////////////////////////////////
// define rs232 mode
///////////////////////////////////////////////////////////
#use rs232(baud=BAUDRATE,parity=PAR,bits=8,xmit=TX485,rcv=RX485,enable=EN485,errors,stream=comm1)
///////////////////////////////////////////////////////////
// global variables
///////////////////////////////////////////////////////////
int8 modbus_mem[MAX_MEM];
int8 modbus_slave_addr;
int8 rx_data_num;
int8 tx_data_num;
int8 tx_data_size;
int8 rxtx_buffer[MAX_STREAM];
int16 timeout_value;
int1 modbus_process;
///////////////////////////////////////////////////////////
// function that initialise modbus in slave mode
///////////////////////////////////////////////////////////
void init_modbus_slave(int8 slave_address){
rx_data_num=0;
tx_data_num=0;
modbus_process=0;
// Use 8bits timer0 clock pulse 25.6us for 20Mhz Quartz (
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
timeout_value=TIMEOUT;
#ifdef DEBUG
printf("timeout_value=%lu\r\n",timeout_value,comm1);
#endif
modbus_slave_addr=slave_address;
enable_interrupts(int_rda);
enable_interrupts(global);
}
///////////////////////////////////////////////////////////
// Function that calculate CRC16 of a stream
///////////////////////////////////////////////////////////
int16 cal_crc16(int8* data,int8 length){
int16 calc_crc16,comp_value;
int8 Spam,oct_nb;
int8 lsb_calc_crc16,msb_calc_crc16;
//calculate CRC16 value
//initialize process with FFFFh value
calc_crc16 = 0xFFFF;
for(oct_nb=0;oct_nb<length;oct_nb++){
//assign data to comp value
comp_value=*data;
//increase data address
data++;
//made a XOR bettween calc_crc16 and character defined
calc_crc16 = calc_crc16 ^ comp_value;
//same process 8 times with following charcacter
for(Spam=0; Spam<8; Spam++){
// if lsb is equal calc_crc16 to 1
if ((calc_crc16 & 0x0001)==1){
// made a right shift and XOR with A001 polynom
calc_crc16= calc_crc16 >> 1;
calc_crc16= calc_crc16 ^ 0xA001;
}else{
// else made a right shift
calc_crc16= calc_crc16 >> 1;
}
}
}
//msb and lsb are inverted
lsb_calc_crc16=calc_crc16 >> 8;
msb_calc_crc16=calc_crc16 & 0xff;
calc_crc16=msb_calc_crc16 << 8;
calc_crc16=calc_crc16 | lsb_calc_crc16;
// function recturn crc16 calculated
return calc_crc16;
}
///////////////////////////////////////////////////////////
// function that manage the modbus in slave mode
///////////////////////////////////////////////////////////
void modbus_slave(int8* rxtx_buffer,int8* modbus_mem){
int8 temp_low,temp_high;
int8 rcv_data_num;
int8 rcv_slave_addr,rcv_fonction;
int16 rcv_subaddr,rcv_word0;
int16 rcv_crc16,calc_crc16;
int8 data_byte,data_stream;
int8 mem_data;
int8 i;
//save number of character received
rcv_data_num=rx_data_num;
// formate received value
rcv_slave_addr= rxtx_buffer[0];
rcv_fonction= rxtx_buffer[1];
temp_high= rxtx_buffer[2];
temp_low= rxtx_buffer[3];
rcv_subaddr= temp_high<<8;
rcv_subaddr|= temp_low;
temp_high= rxtx_buffer[4];
temp_low= rxtx_buffer[5];
rcv_word0= temp_high<<8;
rcv_word0|= temp_low;
temp_high= rxtx_buffer[rcv_data_num-2];
temp_low= rxtx_buffer[(rcv_data_num-1)];
rcv_crc16= temp_high<<8;
rcv_crc16|= temp_low;
#ifdef DEBUG
printf("rcv data num=%2x\r\n",rcv_data_num,comm1);
printf("rcv slave addr=%2x\r\n",rcv_slave_addr,comm1);
printf("rcv fonction=%2x\r\n",rcv_fonction,comm1);
printf("rcv subaddr=%4lx\r\n",rcv_subaddr,comm1);
printf("rcv word0=%4lx\r\n",rcv_word0,comm1);
printf("rcv crc16=%4lx\r\n",rcv_crc16,comm1);
#endif
// verify modbus slave address
if((rcv_slave_addr==modbus_slave_addr)||(rcv_slave_addr==BROADCAST_ADDRESS)){
#ifdef DEBUG
printf("Slave Address ok\r\n",comm1);
#endif
calc_crc16=cal_crc16(rxtx_buffer,(rcv_data_num-2));
#ifdef DEBUG
printf("calculated CRC16=%4lx\r\n",calc_crc16,comm1);
#endif
// verify CRC16
if (calc_crc16==rcv_crc16){
#ifdef DEBUG
printf("CRC16 ok\r\n",comm1);
#endif
///////////////////////////////////////////////////////////
// verify if transaction is memory read
// Function does not support BROADCAST Messages
if((rcv_fonction==MEM_READ_WORD)&&(rcv_slave_addr!=BROADCAST_ADDRESS)){
#ifdef DEBUG
printf("Function Memory Read\r\n",comm1);
#endif
//detect how many data byte must be read
data_byte=(int8)(rcv_word0<<1);
// verify modbus sub-address + words asked
// are located in the defined memory
if((rcv_subaddr+(data_byte-1))<MAX_MEM){
// be sure that max received data is limited to max stream
if (data_byte>0 && data_byte<=(MAX_STREAM-3)){
//save byte count
*(rxtx_buffer+2)=data_byte;
// read data into memory
for(i=0;i<data_byte;i++){
mem_data=(modbus_mem+(int8)rcv_subaddr+i);
*((rxtx_buffer+3)+i)=*mem_data;
}
//calculate new crc16, so making a stream without crc16
data_stream=data_byte+3;
calc_crc16=cal_crc16(rxtx_buffer,data_stream);
// assign crc16 to end of stream
temp_low= calc_crc16 & 0xff;
temp_high= (calc_crc16>>8) & 0xff;
*(rxtx_buffer+(data_stream))= temp_high;
*(rxtx_buffer+data_stream+1)= temp_low;
// calculate final stream size with crc16
tx_data_size=data_stream+2;
// send response stream by using uart transmit empty bit interrupt
enable_interrupts(int_tbe);
}
}
}
///////////////////////////////////////////////////////////
// verify if transaction is single memory write
// Function support BROADCAST Messages
if(rcv_fonction==MEM_WRITE_SINGLE_WORD){
#ifdef DEBUG
printf("Function Single Memory Write\r\n",comm1);
#endif
// verify modbus sub-address + words asked
// are located in the defined memory
data_byte=(rcv_data_num-6);
if((rcv_subaddr+(data_byte-1))<MAX_MEM){
// modbus function is limited to one word only
if(data_byte==2){
// write data into memory
for(i=0;i<data_byte;i++){
mem_data=(modbus_mem+(int8)rcv_subaddr+i);
*mem_data= *((rxtx_buffer+4)+i);
}
// when BROADCASTING, no answer is transmitted
if(rcv_slave_addr!=BROADCAST_ADDRESS){
// calculate stream size
tx_data_size=rcv_data_num;
// just need to send the stream received
// send response stream by using uart transmit empty bit interrupt
enable_interrupts(int_tbe);
}
}
}
}
///////////////////////////////////////////////////////////
// verify if transaction is multiple memory write
// Function support BROADCAST Messages
if(rcv_fonction==MEM_WRITE_MULTIPLE_WORD){
#ifdef DEBUG
printf("Function Multiple Memory Write\r\n",comm1);
#endif
//detect how many data byte must be read
data_byte=(int8)(rcv_word0<<1);
if((rcv_subaddr+(data_byte-1))<MAX_MEM){
// check words received with byte count value received
if(data_byte==*((rxtx_buffer+6))){
// write data into memory
for(i=0;i<data_byte;i++){
mem_data=(modbus_mem+(int8)rcv_subaddr+i);
*mem_data= *((rxtx_buffer+7)+i);
}
// when BROADCASTING, no answer is transmitted
if(rcv_slave_addr!=BROADCAST_ADDRESS){
//calculate new crc16, so making a stream without crc16
calc_crc16=cal_crc16(rxtx_buffer,6);
// assign crc16 to end of stream
temp_low= calc_crc16 & 0xff;
temp_high= (calc_crc16>>8) & 0xff;
*(rxtx_buffer+6)= temp_high;
*(rxtx_buffer+7)= temp_low;
// calculate stream size
tx_data_size=8;
// just need to send the first six bytes received
// send response stream by using uart transmit empty bit interrupt
enable_interrupts(int_tbe);
}
}
}
}
}
}
}
///////////////////////////////////////////////////////////
// comm1 Receive Interrupt
///////////////////////////////////////////////////////////
#int_rda
receive_isr(){
disable_interrupts(int_timer0);
// limit to MAX_STREAM value
if(rx_data_num<MAX_STREAM){
// Get incomming byte from receive buffer
rxtx_buffer[rx_data_num]= getc(comm1);
// Increase receive data number
rx_data_num++;
modbus_process=1;
// Clear timer0 interrupt
Timer0IF=0;
set_timer0(timeout_value);
enable_interrupts(int_timer0);
}
}
///////////////////////////////////////////////////////////
// comm1 Receive Complete timer Interrupt
///////////////////////////////////////////////////////////
#int_timer0
timeout_isr(){
#ifdef DEBUG
int8 i;
#endif
// Disable timer0 Overflow Interrupt
disable_interrupts(int_timer0);
#ifdef DEBUG
printf("rx_data_num=%2u\r\n",rx_data_num,comm1);
for(i=0;i<rx_data_num;i++){
printf("%2x",rxtx_buffer[i],comm1);
}
printf("\r\nModbus Question Stream\r\n",comm1);
#endif
// start modbus process with following parameter
modbus_slave(rxtx_buffer,modbus_mem);
// modbus process is finished
modbus_process=0;
rx_data_num=0;
#ifdef DEBUG
printf("tx_data_size=%2u\r\n",tx_data_size,comm1);
for(i=0;i<tx_data_size;i++){
printf("%2x",rxtx_buffer[i],comm1);
}
printf("\r\nModbus Answer Stream\r\n",comm1);
#endif
}
///////////////////////////////////////////////////////////
// comm1 Transmit Interrupt
///////////////////////////////////////////////////////////
#int_tbe
transmit_isr(){
if(tx_data_num<tx_data_size){
// Start the byte transmition
putc(rxtx_buffer[tx_data_num],comm1);
tx_data_num++;
}
if (tx_data_num==tx_data_size){
disable_interrupts(int_tbe);
tx_data_num=0;
}
}
///////////////////////////////////////////////////////////
// modbus dedicated function to write data in memory
///////////////////////////////////////////////////////////
void modbus_write(int8 addr,int8* data,int8 data_num){
int8 i;
// waiting until modbus is not under processing
while(modbus_process==1){
}
for(i=0;i<data_num;i++){
*(modbus_mem+(addr+i))= *(data+i);
}
}
///////////////////////////////////////////////////////////
// modbus dedicated function to read data in memory
///////////////////////////////////////////////////////////
void modbus_read(int8 addr,int8* data,int8 data_num){
int8 i;
// waiting until modbus is not under processing
while(modbus_process==1){
}
for(i=0;i<data_num;i++){
*(data+i)= *(modbus_mem+(addr+i));
}
} |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|