/* ********************************************************************** * Program: GMBIOTE.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: GMBIOTE.C - Rel. 1.1 - By Graziano Gaiba This demo allows to use immediatly TTL I/O digital lines available on CN4. According to Mini Module used, the list of available lines is printed. When the required line is selected it can be managed as input (its status is shown continuously on console) or as output (setting it high or low). Should the line selected be associated to Real Time Clock, this peripheral manages it. !!!!!!!!!!!!!!!!!!!!!!!!!!! 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; } /**************************************************************************** ** 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); } /**************************************************************************** Main program ****************************************************************************/ void main(void) { unsigned char choice, dir, data; 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(""); puts("On CN4 are available the following digital I/O pins:"); puts(""); puts("1) Pin 2"); puts("2) Pin 3"); puts("3) Pin 5"); puts("4) Pin 6"); puts(""); printf("Select:"); do { choice=toupper(getchar()); } while ((choice<'1') || (choice>'4')); putchar(choice); printf("\n\nDemo in Input,Output,Exit?"); do dir=toupper(getchar()); while ((dir!='I') && (dir!='O') && (dir!='E')); putchar(dir); puts(""); switch(dir) { // Manages I/O TTL signals on CN4 as inputs case 'I': puts("\nShows status of selected pin. Press a key to exit."); // Sets as inputs PB.1,3,4 and 5 DDRB&=0xC6; do { switch(cho ice) { case '1': // Reads status of PB.5 data=(PINB & 0x20) ? '1' : '0'; break; case '2': // Reads status of PB.3 data=(PINB & 0x08) ? '1' : '0'; break; case '3': // Reads status of PB.4 data=(PINB & 0x10) ? '1' : '0'; break; case '4': // Reads status of PB.1 data=(PINB & 0x02) ? '1' : '0'; break; } printf("Status: %c\r", data); wait_ms(100); } while(! kbhit()); getchar(); break; // Manages I/O TTL signals on CN4 as outputs case 'O': // Sets as outputs PB.1,3,4 e 5 DDRB|=0x39; do { printf("Type status of selected pin (0, 1; 2 exit): "); data=getchar(); printf("%c\n", data); switch(choice) { case '1': // Sets status of PB.5 if(data=='1') { PORTB|=0x20; } if(data=='0') { PORTB&=0xDF; } break; case '2': // Sets status of PB.3 if(data=='1') { PORTB|=0x08; } if(data=='0') { PORTB&=0xF7; } break; case '3': // Sets status of PB.4 if(data=='1') { PORTB|=0x10; } if(data=='0') { PORTB&=0xEF; } break; case '4': // Sets status of PB.1 if(data=='1') { PORTB|=0x02; } if(data=='0') { PORTB&=0xFD; } break; } } while(data!='2'); break; } // endswitch } //endfor (;;) // End of infinite loop }