| ??? 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 |



