/* ********************************************************************** * Program: GMBIOBE.C - Version 1.1 - 29 June 2005 * * Compiler: ICC AVR Standard, versione 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: GMBIOBE.C - Rel. 1.1 - By Graziano Gaiba This demo allows to use immediately relays outputs available on CN1 and buffered inputs available on CN6. Through the console can be setted the status of the four output relays or it can visualize the status of the eight NPN/PNP inputs. In addition, high level functions available on Mini Module are used: outputs driven by periodic automatic signals, inputs that generate interrupts, inputs counted by hardware, etc. !!!!!!!!!!!!!!!!!!!!!!!!!!! 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; unsigned char cnt_int0 = 0, cnt_int1 = 0, cnt_int_t0 = 0; /**************************************************************************** ** Interrupt service routines ****************************************************************************/ #pragma interrupt_handler int0_isr:2 void int0_isr(void) { cnt_int0++; } #pragma interrupt_handler int1_isr:3 void int1_isr(void) { cnt_int1++; } #pragma interrupt_handler timer0_ovf_isr:10 void timer0_ovf_isr(void) { TCNT0=0xF0; cnt_int_t0++; } /**************************************************************************** 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, dr, dw; 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("I->Optocoupled inputs on CN6"); puts("O->Relay outputs on CN1"); printf("Section (I,O):"); do choice=toupper(getchar()); while ((choice!='I') && (choice!='O')); putchar(choice); puts(""); if (choice=='I') { puts("Management of 8 optocoupled input lines: connects to CN6 NPN or PNP signals"); puts("with relative + or - on pin 9=COM."); puts("Acquisition is running, press a key to exit"); do { dr=get_opto_in(); // Acquires and formats opto in status printf("%2X\r",dr); // Shows acquired status wait_ms(50); // Avoids overflow on console } while(!kbhit()); getchar(); puts("\n"); puts("IN3 of CN6 is also trigger for INT 0, IN4 is trigger for INT 1."); puts("A transition H-L triggers the interrupt, which increments the counter."); puts("INT0 INT1"); cnt_int0=0; // Resets interrupt counters cnt_int1=0; MCUCR&=0xF0; // Interrupt on falling edges MCUCR|=0x0A; GICR=0xC0; // Enable interrupts /INT0 and /INT1 SEI(); // Global interrupts enable do { // Prints value of interrupt counters to the console printf(" %2X %2X\r", cnt_int0, cnt_int1); wait_ms(50); // Prevents overflow on the console } while (! kbhit()); getchar(); CLI(); // Global interrupts disable GICR=0x00; // Enable interrupts /INT0 and /INT1 puts("\n\n"); puts("Timer 0 is configured as hardware counter. IN5 is its trigger."); puts("Every overlow of Timer 0 triggers a counted interrupt."); puts("T0 N.INT"); TCCR0=0x06; // Clock of Timer 0 from pin T0 (counter) TCNT0=0xF0; // Starting value of the counter TIMSK|=0x01; // Enable interrupt of overflow Timer/Counter 0 SEI(); // Enable interrupt do { // Prints values of Counter 0 and Timer/Counter 0 overflow interrupts printf("%2X %2X\r",TCNT0, cnt_int_t0); } while (! kbhit()); getchar(); TIMSK&=0xFE; // Disable interrupt of overflow Timer/Counter 0 CLI(); // Global interrupts disable } else { clrscr(); puts("Management of 4 relays output signals: contacts A1,A2,B1,B2 of CN1 are"); puts("N.O. and are connected to corresonding common point A,B when closed by software."); puts(""); do { printf("Combination of output lines in hexadecimal (from 0 to F, 0 to exit):"); // Reads an hexadecimal figure (from 0 to 9, from A to F) and converts // it into its numeric value. dw=toupper(getchar()); printf("%c\n", dw); dw-='0'; if(dw>9) dw-=7; set_relays(dw); // Formats and seta status of relay outputs } while (dw!=0); } } //endfor (;;) // End infinite loop }