??? 09/28/05 16:27 Read: times |
#101680 - Serial communication 1 master 6 slaves |
i'm using at89c52 there's one master and 6 slaves.
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 |
Topic | Author | Date |
Serial communication 1 master 6 slaves | 01/01/70 00:00 | |
Double Post | 01/01/70 00:00 | |
not looking better answers | 01/01/70 00:00 | |
Virtually the same doesn't mean correct | 01/01/70 00:00 | |
thanks | 01/01/70 00:00 | |
the mouse ate an elephant | 01/01/70 00:00 | |
thanks anyway![]() | 01/01/70 00:00 |