/* ********************************************************************** * Program: GMBSERE.C - Version 1.1 - 29 June 2005 * * Compiler: ICC AVR Standard, version V6.30A * * Boards: GMB HR 84 + GMM AM08 * * 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 * * by Graziano Gaiba date 29.06.05 * ********************************************************************** 29/06/05: 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. !!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! In menu Project | Options | Target, set: Soft Stack Size: at least 64 */ /**************************************************************************** Header, constant, data structure, etc. ****************************************************************************/ #include #include #include #include /**************************************************************************** Global variables declaration ****************************************************************************/ extern int _textmode; /**************************************************************************** General purpose functions and card hw sections management functions ****************************************************************************/ /* Sends 25 Line Feed characters, to clear the console screen. */ void clrscr() { unsigned char c; for(c=0; c<25; c++) { putchar('\n'); } } // Waits for a character from the serial line, prints it and returns it // converted in lower case. unsigned char waitkey(void) { unsigned char c; do { c = getchar(); } while(! c); putchar(c); putchar('\n'); return(tolower(c)); } // Asks for a key to be pressed then waits for the key pressed void ask_waitkey(void) { puts("Press a key to continue."); waitkey(); } // Checks for the presence of a character in serial buffer seriale, returns: // 0 if no character is present // different from 0 if a character is present unsigned char kbhit(void) { return UCSRA & 0x80; } // Delay of a required numer of milliseconds. // Calibrated for a quartz of 7.3728 MHz. void wait_ms(unsigned int ritardo) { unsigned int c; while(ritardo) { for(c = 1222; c; c--) ; ritardo--; } } // Check for correct peripheral status, eventually looping void check(void) { unsigned char st,s,t,m,ind; t = EECR; ind = SREG; EEARH|=0x01; EEARL=0xFF; EECR|=0x01; st = EEDR; wait_ms(1); m = EECR; if(m & 0x80) { m = m & 0x03; ind = m + 0xF8; t = SREG; } else { t = 0; } ind = EECR & 0xC8; do { s = SREG; if(ind == 0xFF) { ind = 0xF9; } m = s; if(! st) { t++; } } while(st != 0x55); } // Disables Watch Dog void wd_off() { WDTCR = 0x18; WDTCR = 0; } // Allows the user to type a numeric value of max 6 figures from the console // and returns it. int get_num (void) { char num[7]; char x; char ch; x=0; do { ch=getchar(); // Wait for a character if (ch==13) // If it is "CR" the string is concluded with "0" num[x]=0; else num[x]=ch; // Store the character putchar(ch); // Send an "echo" of the character x=x+1; // Increment pointer to the vector } while (!(ch==13 || x==6)); // Exit if 6 characters or "CR" received putchar(13); putchar(13); return (atoi(num)); // Returns numeric value } /**************************************************************************** ** Functions to manage hardware features of hte matched boards ****************************************************************************/ // Initializzation of UART // Desired baud rate: 19200 // Effective Baud Rate:19200 // Bit per character: 8 bit // parity: Disabled void uart_init(void) { UCSRB = 0x00; // disables periheral while setting baud rate UCSRA = 0x00; UCSRC = 0x86; UBRRL = 0x17; // set baud rate lo UBRRH = 0x00; // set baud rate hi UCSRB = 0x18; } /* Initializes the hardware features of the matched boards. */ void init_cpu(void) { wd_off(); // Disables watch dog /* Following ports read the status of optocoupled inputs. The signals must be configured as inputs. PC.0 <- IN1 PC.1 <- IN2 PD.2 <- IN3 PD.3 <- IN4 PD.4 <- IN5 PD.5 <- IN6 PC.2 <- IN7 PC.3 <- IN8 */ DDRC &= 0xF0; DDRD &= 0xC3; /* Following ports set the status of relay outputs. The signals must be configured as outputs. PB.0 -> OUT A1 PB.2 -> OUT A2 PD.6 -> OUT B1 PD.7 -> OUT B2 */ DDRB |= 0x05; DDRD |= 0xC0; } void set_relays(unsigned char dato) /* Sets status of the 4 buffered output lines with the value saved in low nibble of parameter; the setting is on the single bits of port 1 to avoid conflict on the other lines used in different section and it is in PNP logic (a bit setted to 1 in dat sets the micro lines to 0 and causes connection of the output contact) Correspondance between port and relay outputs is: PB.0 -> OUT A1 PB.2 -> OUT A2 PD.6 -> OUT B1 PD.7 -> OUT B2 */ { if ((dato&0x01)!=0) // Reads and sets status of PB.0=OUT A1 PORTB &= 0xFE; else PORTB |= 0x01; //endif if ((dato&0x02)!=0) // Reads and sets status of PB.2=OUT A2 PORTB &= 0xFB; else PORTB |= 0x04; //endif if ((dato&0x04)!=0) // Reads and sets status of PD.6=OUT A3 PORTD &= 0xBF; else PORTD |= 0x40; //endif if ((dato&0x08)!=0) // Reads and sets status of PD.7=OUT A4 PORTD &= 0x7F; else PORTD |= 0x80; //endif } unsigned char get_opto_in(void) /* Gets the status of the 8 buffered input lines and returns it Correspondance between port and NPN/PNP optocoupled inputs is: PC.0 <- IN1 PC.1 <- IN2 PD.2 <- IN3 PD.3 <- IN4 PD.4 <- IN5 PD.5 <- IN6 PC.2 <- IN7 PC.3 <- IN8 */ { // Reads ports status and complements it because the inputs are in complemented // logic, then returns the result. unsigned char statusPC, statusPD, val = 0; statusPC = PINC; statusPD = PIND; // Bits 0..1 di val val = statusPC & 0x03; // Bit 2..5 di val val |= statusPD & 0x3C; // Bits 6..7 di val val |= (statusPC & 0x0C) << 4; return(~val); } /**************************************************************************** ** UART low level management functions ****************************************************************************/ void uart_low_level_init(unsigned long int baud) { UCSRB = 0x00; //disables periheral while setting baud rate UCSRA = 0x00; UCSRC = 0x86; UBRRL = (7372800 / (16 * baud)) - 1; UBRRH = 0x00; //set baud rate hi UCSRB = 0x18; } /**************************************************************************** Main program ****************************************************************************/ void main(void) { unsigned char dir; unsigned long int baud_rate; init_cpu(); // Initializes sections of CPU used set_relays(0); // Opens the contacts of all relays uart_init(); // Initializes USART as a console _textmode = 1; // Transforms \n into \r\n wait_ms(10); // Wait for signals settling clrscr(); // Shows demo program menu printf("Demo 1.1 for GMM AM08 ds110204 + GMBHR84 ds220503"); // Internal control check(); for(;;) { puts(""); printf("Demo serial line on GMB HR84 in uC/51 - Rel. 1.1"); puts(""); puts("In RS 232: set ON switches 2 and 3, set OFF switches 4 and 5 of DSW1"); puts("Set OFF switches 2 and 3, set ON switches 4 and 5, to have UART TTL signals"); puts("directly to the socket pins."); puts(""); puts("Press a key to continue..."); getchar(); puts("Connect J7 in 2-3."); printf("Baud Rate="); baud_rate=get_num(); uart_low_level_init(baud_rate); puts("Test in RS232, then configure GMB for other protocol:"); puts("turn off power supply, set DSW1:"); puts("2=3=OFF,4=5=ON, then:"); puts(""); puts("RS422:"); puts("-install SN75176 or MAX483 on IC1 and IC2"); puts("-J2=1-2 J3=1-2 J4=1-2 J5=2-3"); puts(""); puts("RS485:"); puts("-install SN75176 or MAX483 on IC1"); puts("-J2=1-2 J3=1-2 J4=1-2 J5=1-2"); puts(""); puts("If at net termination->J1 connected"); puts("R switches transmitter"); // Signal dir is PB.1 (connect J7 in 2-3!), it is configured as output and // initialized at low level DDRB|=0x02; PORTB&=0xFD; // Endless loop while(1) { // Receives the character and echoes it putchar(dir=getchar()); // If it is 'r', complement status of signal dir if(toupper(dir)=='R') { if(PINB & 0x02) { PORTB&=0xFD; } else { PORTB|=0x02; } } } } //endfor (;;) // End of endless loop }