void main(void) { ProjectInit(); BDRCON |= 0x10; //start the baudrate generator while(1) { while (RI == 0); byteReceived(); } } void ProjectInit(void) { //initialize oscillator OSCCON = 1; //start external oscillator A (40 MHz) CKSEL = 1; //make sure that external oscillator A is used (40MHz) CKCON0 = 1; //activate X2 mode -> CPU-frequency = 40 MHz //initialize parallel ports P0 = 0; //reset all pins of P0 (signals D30 to D37) P1 = 0; //reset all pins of P1 (signals D00 to D07) HIGH ACTIVE!! P2 = 0; //reset all pins of P2 (signals D20 to D27) P3 = 0xfd; //configure P3.0 and P3.2 to P3.7 as inputs (signals RxD and D10 to D15) //initialize serial interface PCON = 0x80; //select double baude-rate mode SCON = 0x5c; //select UART-mode 1, with stop bit high, no multiprocessor communication BDRCON = 0xe; //select fast internal baudrate generator for transmit and receive BRL = 126; //reload-value for internal baudrate generator (for 19200 baud) //enable interrupt for UART interface on level 2 /*IPL0 = 0; //reset low bit of priority IPH0 = 0x10; //set high bit of priority --> level 2 IEN0 = 0x90; //enable interrupt for UART and enable all interrupts*/ } void byteReceived(void) { //local variables static char maxAnz; //maximum number of bytes to receive static char anz; //number of received bytes static char type; //type of received telegram (0=identification, 1 = parameters, 2 = controls, 3 = messages) static char buffer[11]; //buffer for received bytes (static because it's not supposed to be on the stack!) if ((PCON & 0x8) == 0) { //first byte received buffer[0] = SBUF; buffer[0] = buffer[0] & 0x60; //->set maximum number of bytes for the telegram-type switch (buffer[0]) { case 0: //->identification telegram received type = 0; maxAnz = 10; //maximum number of instruments in the circuit break; case 0x20: //->parameter telegram received type = 1; maxAnz = 8; //parameter telegram consists of 8 more bytes break; case 0x60: //->control telegram received type = 2; maxAnz = 1; //control telegram consists of 1 more byte break; } anz = 0; //reset counter for received bytes buffer[0] = SBUF; //store first byte in buffer PCON |= 0x8; //set GF1-bit (indicator for first byte of transfer) } else { anz++; buffer[anz] = SBUF; if (SBUF == 0xff && type == 0) { //end of identification telegram received maxAnz = anz; } } if (anz == maxAnz) { //->full telegram received and stored in buffer //->call corresponding function to transmit the buffer and set parameters if necessary ES = 0; //disable interrupt for UART switch (type) { case 0: //->identification telegram received identification(buffer, anz); break; case 1: //->parameter telegram received parameter(buffer, anz); break; case 2: //->control telegram received control(buffer, anz); break; } ES = 1; //after transmitting the answer telegram enable interrupt for UART PCON &= 0xf7; //reset GF1-bit (indicator for first byte) } RI = 0; //clear IR bit } void identification (char* buffer, char anz) { static char i; //counter variable buffer[anz] = ADDRESS; //overwrite 0xff at the end of the buffer TI = 0; //make sure no transmit interrupt is waiting for (i = 0; i <= anz; i++) { SBUF = buffer[i]; //write byte to transmit buffer while(TI == 0); //wait for transmission to be finished TI = 0; //reset IR flag of transmitter } SBUF = 0xff; //write 0xff (end character of identification telegram) into transmit buffer while(TI == 0); //wait for transmission to be finished TI = 0; //reset IR flag of transmitter } void parameter (char* buffer, char anz) { static char i; //counter variable static bit ack; //set if telegram was for this generator ack = 0; if ((buffer [0] & 0x1f) == ADDRESS) { //telegram was for this generator buffer[0] |= 0x80; //set acknowledge-flag ack = 1; } //TI = 0; //make sure no transmit interrupt is waiting if (ack == 1) { //set parameters according to received bytes P0 = buffer[2]; //set voltage if ((buffer[6] & 0xfc) == 0) { //->positive pulse while (P3_5 == 1) { P1_1 =~ P1_1; } } else { if ((buffer[6] & 0xfc) == 1) { //->negative pulse while (P3_3 == 1) { P1_1 =~ P1_1; } } else { //->alternating polarity while (P3_4 == 1) { P1_1 =~ P1_1; } } } } //transmit all bytes to other generators or computer -> all parameters set if necessary TI = 0; //make sure no transmit interrupt is waiting for (i = 0; i <= anz; i++) { SBUF = buffer[i]; while(TI == 0); TI = 0; } } void control (char* buffer, char anz) { static char i; //counter variable static bit ack ; //set if telegram was for this generator ack = 0; if ((buffer [0] & 0x1f) == ADDRESS) { //telegram was for this generator buffer[0] |= 0x80; //set acknowledge-flag ack = 1; } //transmit all bytes to other generators or computer TI = 0; //make sure no transmit interrupt is waiting for (i = 0; i <= anz; i++) { SBUF = buffer[i]; while(TI == 0); TI = 0; } if (ack == 1) { switch (buffer[1]) { case 1: //->turn generator on P1 = ON; ownState = 1; //set state to ON break; case 2: //->turn generator off P1 = OFF; ownState = 2; //set state to OFF break; case 4: //->charge generator, wait until voltage is reached and signal computer that generator is ready to trigger //->only if generator is switched on! if (ownState == 1) { P1 = START; while (P3_6 == 1); //wait for "ready to trigger" from generator TI = 0; //make sure no interrupt is waiting SBUF = ADDRESS | 0xc0; //send own address and bits for ready to trigger-signal while(TI == 0); //wait until byte is sent TI = 0; //reset IR-flag ownState = 4; //set state to READY-TO-TRIGGER } break; case 8: //->decharge generator -> switch it off and on again P1 = OFF; P1 = ON; ownState = 1; //set state to ON break; case 0x10: //->trigger a pulse //-> only if ready to trigger! if (ownState == 4) { P1 = TRIG; //trigger pulse ownState = 1; //set state to ON } break; } } }