Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
09/27/05 22:38
Read: times


 
#101631 - problems again, pls help me
Responding to: ???'s previous message

i've made modifications to the code tryin' to communicate more than 2 at89c52.

the idea is:

1. one at89c52 is the master, when the master is goin to transmit sends a start command to the slaves. then sends the slave's address he wants to communicate and at last send a command byte and 3 data bytes.

2. the slaves recieves the command, change the recieve status to "starting" (C_INICIANDO), the recieve the address if the address is its address then change the recieve status to "recieving" (C_RECIBIENDO) else if the address is not its address the change the status to "busy" (C_OCUPADO). when recieving it must recieve 3 data bytes and finish.

i've made an include named "ptrans.h" in this include i've configured the serial port and defined the status and the commands. here is the code:

#include <at89x52.h>

// recieve status
#define C_OCUPADO       0x00    // busy state
#define C_LIBRE         0x01    // free state    
#define C_INICIANDO     0x02    // starting state
#define C_RECIBIENDO    0x03    // recieving state

// commands for the transmition
#define CMD_INICIAR     0xaa    // start
#define CMD_ACK         0xac    // ack
#define CMD_CANCELAR    0xcc    // cancel
#define CMD_FINALIZAR   0xee    // finish

unsigned char estado;           // channel state
unsigned char direccion_local;  // local addres
unsigned char ind_trama;        // index of the buffer
unsigned char  trama[5];        // buffer
unsigned char  ROk;             // software recieve flag

void cfg_pto_serial(){
	SCON=0x50;          // uart in mode 1 (8 bit), REN=1
	TMOD=TMOD|0x20;     // Timer 1 in mode 2
	TH1=0xFD;           // 9600 Bds at 11.059MHz
	TL1=0xFD; 			// 9600 Bds at 11.059MHz
	TI=0;               // clears TI
    RI=0;               // clears RI
	ES=1; 				// Enable serial interrupt
}



after call cfg_pto_serial() i put:
EA=1;
TR=1;
to enable the global interrupt and run timer 1.


for the slaves i've defined an include named "esclavo.h" here i've overloaded the serial interrupt manager. here is the code:

#include "ptrans.h"

void puerto_serial_event() interrupt 4 using 1{
	if(RI == 1){	                // if reception occur 
        switch(SBUF){               // check SBUF
            case CMD_INICIAR:{      // SBUF = start command
                estado=C_INICIANDO; // set status to starting
                ROk=0;              // set recieve software flag to 0
            }break;
            case CMD_CANCELAR:{     // SBUF = cancel command
                estado=C_LIBRE;     // set status to free
                ROk=0;              // set recieve software flag to 0
            }break;
            case CMD_FINALIZAR:{    // SBUF = finish command
                estado=C_LIBRE;     // set status to free
                ROk=0;              // set recieve software flag to 0
            }break;
            default:{                   // else
                switch(estado){         // check the status
                    case C_OCUPADO:{    // status = busy
                    }break;
                    case C_LIBRE:{      // status = free
                    }break;
                    case C_INICIANDO:{  // status = starting
                        if(SBUF&direccion_local==direccion_local){  // checking the address
                            ind_trama=0;            // set the index of the buffer to 0
                            estado=C_RECIBIENDO;    // set status to recieving
                            SBUF=CMD_ACK;           // send the ack command
                        }
                        else{
                            estado=C_OCUPADO;       // if the address is not mine set status to busy
                        }
                    }break;
                    case C_RECIBIENDO:{             // status = recieving
                        trama[ind_trama]=SBUF;      // put SBUF in the buffer
                        ind_trama++;                
                        if(ind_trama>3){            // check if the 3 data bytes are complete
                            ind_trama=0;            // set index to 0
                            ROk=1;                  // set the software recieve flag to 1
                        }
                        SBUF=CMD_ACK;               // send the ack command
                    }break;
                }
            }break;
        }
        RI = 0; 			        // clear reception flag for next reception 
	}
    if(TI==1){                      //if transmition occurs
        TI=0;                       //clears TI
    }
}


for the master i've made an include named "master.h" where i've overloaded the serial interrupt manager, a send command and a waiting ack function. here is the code:

#include "ptrans.h"

void puerto_serial_event() interrupt 4 using 1;
unsigned char relojSerial();
char enviar_comando(unsigned char, unsigned char, unsigned char[3]);


void init_pto(){
    TI=0;
    SBUF=CMD_CANCELAR;
}

void puerto_serial_event() interrupt 4 using 1{
	if(RI == 1){	                // if reception occur 
        RI = 0; 			        // clear reception flag for next reception 
        if(SBUF==CMD_ACK){          
            ROk=1;
        }
	}
    if(TI==1){                      //if transmition occurs
        TI=0;                       //clears TI
        ROk=0;
    }
}


// send command
// inputs:
//          direccion   =   slave address
//          comando     =   command byte to the slave (data)
//          parametros  =   data bytes
//
// return:
//          0           =   the transmition was ok
//          1           =   there were erros in the transmition
char enviar_comando(unsigned char direccion, unsigned char comando, unsigned char parametros[3]){
    unsigned char i;
    TI=0;
    SBUF=CMD_INICIAR;   // sends start command
    SBUF=direccion;     // sends the slave address
    if(relojSerial()==0){
        ROk=0;
        SBUF=CMD_CANCELAR;
        return 1;
    }
    SBUF=comando;       //  sends a command byte
    if(relojSerial()==0){
        ROk=0;
        SBUF=CMD_CANCELAR;
        return 1;
    }
    for(i=0;i<3;i++){
        SBUF=parametros[i]; // sends the 3 data bytes
        if(relojSerial()==0){
            ROk=0;
            SBUF=CMD_CANCELAR;
            return 1;
        }
    }
    SBUF=CMD_FINALIZAR;     // sends the finish command 
    return 0;
}

unsigned char relojSerial(){    // wait 5ms aprox for the ack
    unsigned char i,j,sw;
    sw=0;
    i=0;
    j=0;
    while((sw==0)&&(i<10)){
        sw=ROk;     // if ROk=1 the ack arrives
        if(j>181){
            j=0;
            i++;
        }
        else{
            j++;
        }
    }
    return sw;  // if 0 no ack arrives
}


the true is, i'm feeling like a stupid. i've tried to find where the error is and i've haven't found. i've been looking for about 4 days and noting yet. i'll apreciate the help.

thanks,

Ruben Porras

List of 20 messages in thread
TopicAuthorDate
Serial communication between 2 at89c52            01/01/70 00:00      
   I had a quick look and since I am not            01/01/70 00:00      
   pic?            01/01/70 00:00      
      again            01/01/70 00:00      
         re your ISR            01/01/70 00:00      
            i've modified the ISR            01/01/70 00:00      
               get it going with a PC at one end that g            01/01/70 00:00      
                  i'll try 2 do that            01/01/70 00:00      
               transmit            01/01/70 00:00      
                  sorry            01/01/70 00:00      
                     No, do it in the interrupt            01/01/70 00:00      
                        must be like this?            01/01/70 00:00      
                           should be            01/01/70 00:00      
                              thanks            01/01/70 00:00      
                     NO            01/01/70 00:00      
   problems again, pls help me            01/01/70 00:00      
      still don't get it            01/01/70 00:00      
   with only two processors why are you con            01/01/70 00:00      
      i've said            01/01/70 00:00      
         then this is a bad title.            01/01/70 00:00      

Back to Subject List