/* ********************************************************************** * File: GMBSERE.C - Rel. 1.1 with uC/51 V. 1.10.15 * * Boards: GMB HR168 + GMM AC2 * * GRIFO(R) via Dell'Artigiano 8/6 40016 S. Giorgio di Piano (BO) * * Tel. +39 051 892052 Fax. +39 051 893661 * * http://www.grifo.com http://www.grifo.it * * sales@grifo.it tech@grifo.it grifo@grifo.it * * by Graziano Gaiba date 10.03.04 * ********************************************************************** 10/03/04: GMBSERE.C - Rel. 1.1 - By Graziano Gaiba This demo is a simple example of communication capableto work with all electric protocols available on CN2 (RS 232, RS 422, RS 485, current loop or TTL). In detail, through low level functions, it is possible to program baud rate from console, then each character received from serial port is sent to the port itself; reception of character 'R' decides how to manage the communication direction (signal DIR) for RS 422 and RS 485. Note To avoid problems do not use complex operations on a single source line, especially inside procedures by using their parameters or their local variables. */ /**************************************************************************** Header, constant, data structure, etc. ****************************************************************************/ #include "canarye.h" #include #include #define FALSE 0x00 // Boolean value #define TRUE 0xFF #define LF 0x0A // ASCII codes #define CRET 0x0D // Global variables for I2C BUS management near unsigned char resi2c; // I2C BUS error variable bit unsigned char SDA @ 0xA1; // SDA pin bit unsigned char SCL @ 0xA0; // SCL pin // General purpose global variables used by main and procedures near unsigned char choice,dr,dw,hlp; near unsigned int val; inear unsigned char input[9]; // Console input buffer /**************************************************************************** General purpose functions and card hw sections management functions ****************************************************************************/ unsigned char divappr(unsigned long divid,unsigned long divis) /* Procedure that calculates the 8 bit integer quotient, correctly approximated, between the dividend and the divisor passed as parameters, by using the successive subtractions tecnique. This function is used to reserve the 2K of code required by the same librari functions. */ { unsigned char d; d=0; // Set quotient to zero while (divid>=divis) { divid=divid-divis; d++; } //endwhile divis=divis>>1; // Halves divisor to check the remainder if (divid>=divis) d++; //endif return d; } void init_cpu(void) /* Perform some specific initialization of CPU SFRs */ { EA=0; // Ensures interrupt disabled CKCON=0x00; // Set X1 clock mode = standard mode AUXR=0x0C; // Selects ERAM on external data area EECON=0x00; // Disables internal EEPROM } void iniser(unsigned long baud) /* Initializes the serial line with: Bit x chr = 8 Stop bit = 1 Parity = None Baud rate = baud using timer 1 as baud rate generator. */ { SCON=0x052; // Mode 1, enables receiver TMOD&=0x00F; // Timer 1 in auto-reload mode TMOD|=0x020; TR1=0; // Stops TIMER 1 TH1=(unsigned char)(256-divappr((2*14745600),(384*baud))); // 14.7456 MHz PCON=PCON|0x080; // Sets SMOD=1 for high baud rates TR1=1; // Starts TIMER 1 TI=1; // Sets end of transmission bit for optimized console (SIOTYPE=k) } void clrscr(void) /* Performs the clear screen function for a generic console */ { unsigned char r; putc(CRET); for (r = 0 ; r < 25 ; r++) { putc(LF); // Transmit 25 Line Feeds } //endfor } void delay(unsigned int del) /* Executes a software delay of del milliseconds, calibrated on a 14.7456 MHz CPU Clock */ { unsigned int r,dt1ms; dt1ms=100; // Experimental value for 1 msec. delay do { for (r=0 ; r0); } void setP01234inp(void) /* Sets all the lines of all the ports (P1,P2,P3,P4) in input. */ { P0=0xFF; // Setta Port 0 in INPUT dr=P0; ADCF=0x00; // Sets P1.x as I/O port P1=0xFF; // Sets Port 1 as INPUT dr=P1; P2=0xFF; // Sets Port 2 as INPUT dr=P2; P3=0xFF; // Sets Port 3 as INPUT dr=P3; P4=0xFF; // Sets Port 4 as INPUT dr=P4; } void riti2c(void) /* Performs a delay for syncronous I2CBUS communication. The delay is sufficient for a 22 MHz clock, X1 modality */ { #asm nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop #endasm } void starti2c(void) /* Generates start sequence for I2C BUS */ { SCL=0; // Start sequence SDA=1; riti2c(); SCL=1; SDA=0; riti2c(); SCL=0; //endif } void stopi2c(void) /* Generates stop sequences for I2C BUS */ { SCL=0; // Stop sequence SDA=0; riti2c(); SCL=1; SDA=1; riti2c(); SCL=0; //endif } void wri2c_bit(unsigned char i2cbit) /* Serializes the D0 bit of i2cbit, on I2CBUS */ { SCL=0; // Sets SDA and generates positive pulse on SCL SDA=i2cbit; riti2c(); SCL=1; riti2c(); SCL=0; //endif } unsigned char rdi2c_bit(void) /* Deserializes one bit from I2CBUS and saves it on lsb of the returned value */ { unsigned char biti2c; SDA=1; // Avoids conflicts in SDA acquisition SCL=0; // Ensures SCL status riti2c(); SCL=1; // Generates positive pulse on SCL and reads SDA biti2c=SDA; riti2c(); SCL=0; //endif return biti2c; } void wri2c_byte(unsigned char i2cbyte) /* Serializes the i2cbyte byte on I2CBUS */ { unsigned char b; for (b = 1; b <= 8; b++) { if ((i2cbyte & 0x80) == 0) // Determines and sets b bit wri2c_bit(0); else wri2c_bit(1); i2cbyte = i2cbyte << 1; } } void putcar(unsigned char tra) /* Transmits the tra character on serial line */ { while (!TI) // Waits free transmitter continue; TI = 0; // Transmits character SBUF = tra; } unsigned char getcar(unsigned char *rec) /* Checks if the serial line has received one character and if available gets and saves it on rec parameter; the function return a boolean value that indicates if character was received */ { if (RI) // Checks if character received { RI = 0; // Acquires and saves received character *rec = SBUF; return(TRUE); } else return(FALSE); // No characters available //endif } unsigned char peekb(unsigned int addr) /* Reads the byte from addr address of external data area and returns it */ { return *(xdata unsigned char *)addr; // Gets byte from location } void rd_ee(unsigned int eeaddr,unsigned char *eedat) /* Reads the eedat byte from eeaddr address of internal EEPROM */ { AUXR=0x2E; // Deselects ERAM and increase MOVX duration EECON=0x02; // Selects microprocessor EEPROM on external data area *eedat=peekb(eeaddr); // Performs EEPROM reading AUXR=0x0C; // Selects ERAM on external data area EECON=0x00; // Disables microprocessor EEPROM } /**************************************************************************** Main program ****************************************************************************/ void main(void) { unsigned long baud; // Variables for serial line demo init_cpu(); // Initializes the used CPU iniser(19200); // Initializes serial line for console with timer 1 setP01234inp(); // Sets Port 0,1,2,3,4 as INPUT clrscr(); // Selects used Mini Module do { rd_ee(0x07F8,&dr); } while (dr!=0); for(;;) { puts("Configure serial line for required electric protocol following the user"); puts("manual indications and connect the signals to CN6."); puts("Connect J10 in 1-2."); puts("The demo continuosly checks the chr reception and when available it transmit"); puts("them back, through low level functions, until chr E is received that restores"); puts("communication with console at 19200 Baud. The R character reception"); puts("complements the status of DIR signal, used in RS422,RS485 communication"); puts("to manage the transmitter."); printf("Baud Rate="); inputse(input, 8); // Gets unsigned long baud=(unsigned long)atol(input); puts(""); delay(10); // Waits end of transmission of last chr iniser(baud); // Initializes serial line with inserted baud rate dr=0; do { if (getcar(&dr)) // If chr received from serial line { if (dr=='R' || dr=='r') { // Complements transmitter status P2_3=P2_3 ^ 1; // Through signal DIR } // endif putcar(dr); // Transmit received chr } // endif } while (dr!='E' || dr=='e'); // Waits E reception delay(10); // Waits end of transmission of last chr iniser(19200); // Initializes serial line for console at 19200 Baud } //endfor (;;) // End of endless loop }