/* ********************************************************************** ** Programma: gmbdae.c - Versione : 1.1 - 30 Giugno 2005 ** ** Compilatore : ICC AVR Standard, versione V6.30A ** ** Scheda : GMB HR84 + GMM AM08 ** ** Ditta: grifo(r) ITALIAN TECHNOLOGY ** ** Via Dell' Artigiano 8/6 40016 San Giorgio di Piano (BO) ** ** Tel.+39 051 892 052 Fax +39 051 893 661 ** ** http://www.grifo.com http://www.grifo.it ** ** Realizzato da: Graziano GAIBA ** ********************************************************************** 30/06/05: GMBDAE.C - Rel. 1.1 - By Graziano Gaiba This demo uses timer 2 of Mini Module to generate on CN4, a PWM signal with preset frequency and duty cycle programmable in percent by console. Such signal, connected to an opportune intergrating circuit (RC network, operational amplifier with capacitor on feedback, etc.) allows to obtain an anlog signal like the one of a D/A. Demo execution depends on which Mini Module is used and serial line configuration !!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! In menu Project | Options | Target, set: Soft Stack Size: at least 64 */ /**************************************************************************** Header, constant, data structure, etc. ****************************************************************************/ #include #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); } //Initialize Timer 2 to work as PWM void init_pwm(void) { DDRB|=0x08; // Set PB.3 as output OCR2=0x80; // Duty Cycle 50% // Fast PWM mode, No Prescaler, Set to 1 pin 8 of 40 pins socket // on every match between registers OCR2 and the counter of the timer TCCR2=0x79; TCNT2=0; // Reset timer } /**************************************************************************** Main program ****************************************************************************/ void main(void) { unsigned char duty_cycle; init_c pu(); // 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("Timer 2 (8 bit) configured as PWM (pin 3 of CN4)."); puts(""); init_pwm(); // Initialize Timer 2 as PWM do { printf("Duty cycle in decimal (from 0 to 255, 0 to reset): "); duty_cycle=get_num(); puts(""); OCR2 = duty_cycle; // Reset duty cycle }while(duty_cycle); TCCR2=0x48; // Stop Timer 2 } //endfor (;;) // End infinite loop }