/* ---------------------------------------------------------------------------- * Source lndk_avr006.c * Programme pour micro-controleur ATMEGA8535L * Mesures d'une station solaire, commandes de délestage des charges * * Copyright (c) November 2007, Marc Dilasser, Le Net du Kermeur * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1 Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2 Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3 Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "lndk_avr006.h" #define LNDK_VERSION "LNDK Programme AVR006, version 0.01" #define LNDK_SHORTVER "LNDK_AVR006v0.01 11/2007" #define TRUE (1) #define FALSE (0) #define SPACE 0x20 #define FREQ_CPU 8000000 // Calcul du diviseur : DIVISEUR = (((FREQ_CPU / (BAUDRATE * 16))) - 1) // Valeur pour 19200 #define BAUDRATE 19200 #define DIVISEUR 25 // Valeur pour 9600 // #define BAUDRATE 9600 // #define DIVISEUR 51 // Pour du 4800 bauds // #define BAUDRATE 4800 // #define DIVISEUR 103 // Extension Timer #define EXTENSION_TIMER // #define EXTENSION_REINIT #define REDUCTION_DATA #define WATCHDOG #define MIN_WATCHDOG 60 #define MAX_WATCHDOG 86400 // A compter de la version 5, mesure des ADCs toutes les 20 secondes #define MESURE_CONTINUE #define INTERVALLE 20 // La mesure différentielle n'est pas utilisable sur le package PDIP // de l'ATMEGA8535 (cf. page 206 du DataSheet), dommage ... // #define MESURE_DIFFERENTIELLE u8 ch = ' ', // Caractère dans la ligne de commande data = ' '; // Caractère sur le port série volatile int inda = 1; // Index écriture du buffer de réception int indb = 1, // Index lecture de ce meme buffer inde = 1, running = 1, debug = 1; u8 echo = 0; // Echo des caractères reçus #ifdef EXTENSION_TIMER // DEBUT_SIECLE=$(date -d "2000-01-01 00:00:00" "+%s") + 3600 #define DEBUT_SIECLE 946684800L // Duree maximale de temporisation = 24H #define MAX_DUREE 86400L volatile u32 timer = 1L; // Secondes ecoulees #ifdef WATCHDOG volatile u32 silence = 1L; u32 watchdog = 1L; #endif u8 dizieme = 1, // Dizieme de seconde testled = 1, activite = 1; // Délai de clignotement (en 1/10s) si activité série u32 offsec = 1L; // Secondes à rajouter à l'uptime pour date Unix u32 portbend[8] = { 1, 1, 1, 1, 1, 1, 1, 1}; u8 portbeta[8] = { 1, 1, 1, 1, 1, 1, 1, 1}; int portsflg = 1; #endif // Buffer de reception du port série char bufrec[64] = " " " "; // Buffer pour ligne de commande char line[32] = " "; #ifdef WATCHDOG char cmdwatch[32] = " "; #endif #ifdef MESURE_CONTINUE volatile u16 time_mesure = -1; int mesures[64] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; u8 lissage = 6; #endif #ifdef REDUCTION_DATA char MsgHlp[] = "See http://www.lekermeur.net/lndkavr/\r\n"; char MsgSyntax[] = "-;(\r\n"; char MsgVersion[] = LNDK_SHORTVER; #else char MsgHlp[] = "lndk_avr006\r\n" "Commandes reconnues :\r\n" " help\r\n" " version\r\n" " debug\r\n" #ifdef EXTENSION_REINIT " exit\r\n" #endif #ifdef EXTENSION_TIMER " date\r\n" " uptime\r\n" " testled\r\n" #endif " portb 1..8 [ON-OFF [DELAI]]\r\n" " portbs\r\n" " adca 1..8\r\n" " adcas\r\n"; char MsgSyntax[] = "Taper HELP pour la syntaxe des commandes\r\n"; char MsgVersion[] = LNDK_VERSION; #endif char MsgPrompt[] = "-> "; char MsgCRLF[] = "\r\n"; char MsgADC[] = "ADC x : 9999"; char MsgBuffer[] = "Date 2007-01-01 24h 60m 60s "; // ------------------------------------------------ U S A R T _ R X _ v e c t // Gestion de l'interruption caractere recu ISR(USART_RX_vect) { data = UDR; if (data > 0) { bufrec[inda++] = data; inda &= 0x3F; #ifdef EXTENSION_TIMER activite = 6; #endif // #ifdef MESURE_CONTINUE // time_mesure = 0; // #endif if (echo) { UDR = data; // Si caractere RETOUR-CHARIOT, rajouter un LINE-FEED if (data == 13) { while ( !( UCSRA & (1<= 10) { timer ++; dizieme = 0; #ifdef WATCHDOG silence ++; #endif #ifdef MESURE_CONTINUE time_mesure ++; #endif } // Si activite en cours, ou changement de seconde, changer etat de la diode if (testled) { // Si indicateur d'activite UART, le decrementer if (activite > 0) activite--; if ((activite) || (dizieme == 0)) { PORTB ^= (1 << 0); } } } #endif // ---------------------------------------------------------- S e n d C h a r int SendChar(char carac) { if (echo) { while ( !( UCSRA & (1<= max) max = mesures[ij]; if (mesures[ij] <= min) min = mesures[ij]; } val = (total - (min + max)) / (lissage - 2); #else ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1)| (1 << ADPS0); // Choix du Canal et de la reference de tension // ADMUX = 0xE0 | Canal; #ifdef MESURE_DIFFERENTIELLE if (Diff == 0) ADMUX = (1 << REFS1) | (1 << REFS0) | Canal; else // Mesure différentielle avec multiplicateur x 10 ADMUX = (1 << REFS1) | (1 << REFS0) | ((Diff == 1) ? 0x09 : 0x1B); #else ADMUX = (1 << REFS1) | (1 << REFS0) | Canal; #endif // Activer la conversion ADCSRA = ADCSRA | ( 1 << ADSC); // Attendre le bit ADIF while (! (ADCSRA & (1 << ADIF))); val = ADCL; val |= (ADCH << 8); #endif MsgADC[4] = (Diff == 0) ? (Canal + 49) : (Diff + 64); ij = 8; if (val >= 1024) { MsgADC[ij++] = '#'; MsgADC[ij++] = '#'; MsgADC[ij++] = '#'; done = FALSE; } else { if (val >= 1000) MsgADC[ij ++] = '1'; if (val >= 100) MsgADC[ij ++] = (((val % 1000) / 100) + 48); if (val >= 10) MsgADC[ij ++] = (((val % 100) / 10) + 48); MsgADC[ij ++] = ((val % 10) + 48); done = TRUE; } MsgADC[ij] = 0; SendString(MsgADC); SendString(MsgCRLF); return(done); } #ifdef EXTENSION_TIMER // -------------------------------------------------------------- U p t i m e int Uptime(int utc) { u32 seconds, secdeb, duree; int year, month, jou, heu, min, sec, ij, done; seconds = timer; year = 2000; secdeb = DEBUT_SIECLE; month = 1; if (utc) { if (offsec >= DEBUT_SIECLE) { seconds += offsec; // Trouver l'année done = FALSE; do { duree = ((year % 4) == 0) ? (366 * 86400L) : (365 * 86400L); if ((secdeb + duree) < seconds) { secdeb += duree; year ++; } else done = TRUE; } while (! done); // Trouver le mois done = FALSE; while ( ! done) { // Mois de 31 jours duree = 31L; // Sauf Avril, Juin, Septembre, Novembre if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) { duree -= 1L; } // Et Février à 28 ou 29 suivant si l'année est bissextile ou non if (month == 2) duree -= ((year % 4) == 0) ? 2L : 3L; // Traduire en nombre de secondes (86400 = 24 x 3600) duree *= 86400L; if ((secdeb + duree) < seconds) { secdeb += duree; month ++; } else done = TRUE; } jou = ((seconds - secdeb) / 86400L) + 1; seconds -= secdeb; seconds -= ((jou - 1) * 86400L); } else utc = 0; } if (! utc) { jou = (seconds / 86400L); seconds -= (jou * 86400L); } heu = (seconds / 3600L); seconds -= (heu * 3600L); min = (seconds / 60L); seconds -= (min * 60L); sec = seconds; ij = 0; if (utc) { MsgBuffer[ij++] = 'D'; MsgBuffer[ij++] = 'a'; MsgBuffer[ij++] = 't'; MsgBuffer[ij++] = 'e'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = (year / 1000) + 48; MsgBuffer[ij++] = ((year % 1000) / 100) + 48; MsgBuffer[ij++] = ((year % 100) / 10) + 48; MsgBuffer[ij++] = (year % 10) + 48; MsgBuffer[ij++] = '-'; MsgBuffer[ij++] = (month / 10) + 48; MsgBuffer[ij++] = (month % 10) + 48; MsgBuffer[ij++] = '-'; MsgBuffer[ij++] = (jou / 10) + 48; MsgBuffer[ij++] = (jou % 10) + 48; } else { MsgBuffer[ij++] = 'U'; MsgBuffer[ij++] = 'p'; MsgBuffer[ij++] = 't'; MsgBuffer[ij++] = 'i'; MsgBuffer[ij++] = 'm'; MsgBuffer[ij++] = 'e'; MsgBuffer[ij++] = ' '; if (jou > 0) { if (jou >= 1000) MsgBuffer[ij++] = ((jou / 1000) + 48); if (jou >= 100) MsgBuffer[ij++] = (((jou % 1000) / 100) + 48); if (jou >= 10) MsgBuffer[ij++] = (((jou % 100) / 10) + 48); MsgBuffer[ij++] = ((jou % 10) + 48); MsgBuffer[ij++] = 'j'; MsgBuffer[ij++] = ' '; } } MsgBuffer[ij++] = ' '; if (heu >= 10) MsgBuffer[ij++] = ((heu / 10) + 48); MsgBuffer[ij++] = ((heu % 10) + 48); MsgBuffer[ij++] = 'h'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = ((min / 10) + 48); MsgBuffer[ij++] = ((min % 10) + 48); MsgBuffer[ij++] = 'm'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = ((sec / 10) + 48); MsgBuffer[ij++] = ((sec % 10) + 48); MsgBuffer[ij++] = 's'; MsgBuffer[ij] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); return TRUE; } #endif // ------------------------------------------------------ P o r t B S t a t e int PortBState(int pinoche, int Affiche) { int state, ij; // Lecture de la valeur en cours state = FALSE; if (~ PINB & (1 << pinoche)) { state = TRUE; } if (Affiche) { ij = 0; MsgBuffer[ij++] = 'P'; MsgBuffer[ij++] = 'O'; MsgBuffer[ij++] = 'R'; MsgBuffer[ij++] = 'T'; MsgBuffer[ij++] = 'B'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = pinoche + 49; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = ':'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = state + 48; MsgBuffer[ij++] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); } return(state); } // ---------------------------------------------- T o u t e s _ M e s u r e s int Toutes_Mesures(void) { int ij; for (ij = 0; ij < 8; ij ++) { Mesure(ij, 0); } return(0); } // -------------------------------------------------------------- P r o m p t int Prompt(void) { SendString(MsgPrompt); return TRUE; } // ---------------------------------------------------------- B a n n i e r e void Banniere(void) { int ij; SendString(MsgCRLF); for (ij = 0; ij < 40; ij++) SendChar('-'); SendString(MsgCRLF); SendString(MsgVersion); SendString(MsgCRLF); for (ij = 0; ij < 40; ij++) SendChar('-'); SendString(MsgCRLF); Prompt(); } // ------------------------------------------------------ T r a i t e m e n t int Traitement_Ligne(void) { int ij, ik, ik1, ik2, pina, done; #ifdef MESURE_DIFFERENTIELLE int pinb; #endif #ifdef EXTENSION_TIMER u32 u32tmp, duree; #endif // Nettoyer les blancs de fin while ((line[inde] == ' ') && (inde > 0)) { inde--; line[inde] = 0; } if (debug) { SendString(line); SendString(MsgCRLF); } // ij = inde; // Ligne de moins de 3 caractères est invalide if (inde >= 3) { done = FALSE; // Switcher sur le premier caractère pour éviter // de multiplier les comparaisons de chaines ch = line[0]; switch (ch) { case 'A' : if (inde == 4) { if ( (line[1] == 'I') && (line[2] == 'D') && (line[3] == 'E')) { Help(); done = TRUE; } } if (inde == 5) { if ( (line[1] == 'D') && (line[2] == 'C') && (line[3] == 'A') && (line[4] == 'S')) { Toutes_Mesures(); done = TRUE; } } if (inde == 6) { if ( (line[1] == 'D') && (line[2] == 'C') && (line[3] == 'A') && (line[4] == ' ')) { // Numero de pinoche de 1 a 8 ik = line[5] - 48; if ((ik >= 1) && (ik <= 8)) { Mesure(ik - 1, 0); done = TRUE; } } } break; case 'D' : if (inde == 5) { if ( (line[1] == 'E') && (line[2] == 'B') && (line[3] == 'U') && (line[4] == 'G')) { debug = (! debug); ij = 0; MsgBuffer[ij++] = 'D'; MsgBuffer[ij++] = 'E'; MsgBuffer[ij++] = 'B'; MsgBuffer[ij++] = 'U'; MsgBuffer[ij++] = 'G'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = 'i'; MsgBuffer[ij++] = 's'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = 'O'; MsgBuffer[ij++] = (debug) ? 'N' : 'F'; MsgBuffer[ij++] = (debug) ? '\0' : 'F'; MsgBuffer[ij] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); done = TRUE; } } #ifdef EXTENSION_TIMER else { if (inde >= 4) { if ( (line[1] == 'A') && (line[2] == 'T') && (line[3] == 'E')) { if (inde == 4) { Uptime(1); done = TRUE; } else { // Mise à l'heure du timer u32tmp = atol(line + 5); // Pas de base inférieure a 2000-01-01 00h00m00s UTC if (u32tmp >= DEBUT_SIECLE) { offsec = u32tmp - timer; done = TRUE; } } } #ifdef MESURE_DIFFERENTIELLE else { // Mesure différentielle de tension, amplification x 10 if ( (line[1] == 'I') && (line[2] == 'F') && (line[3] == 'F') && (line[4] == ' ') && (line[6] == ' ') && (line[8] == '\0')) { // Numero de pinoche de 1 a 8 pina = line[5] - 48; pinb = line[7] - 48; if ( ((pina == 1) && (pinb == 2)) || ((pina == 3) && (pinb == 4))) { Mesure(0, (pinb / 2)); done = TRUE; } } } #endif } } #endif break; case 'E' : if (inde >= 7) { if ( (line[1] == 'C') && (line[2] == 'H') && (line[3] == 'O') && (line[4] == ' ')) { if ( (inde == 8) && (line[5] == 'O') && (line[6] == 'F') && (line[7] == 'F')) { echo = 0; done = TRUE; } else { if ( (inde == 7) && (line[5] == 'O') && (line[6] == 'N')) { echo = 1; done = TRUE; } } } } break; #ifdef EXTENSION_REINIT if (inde == 4) { if ( (line[1] == 'X') && (line[2] == 'I') && (line[3] == 'T')) { running = 0; SendString(MsgCRLF); done = TRUE; } } break; #endif case 'H' : if (inde == 4) { if ( (line[1] == 'E') && (line[2] == 'L') && (line[3] == 'P')) { Help(); done = TRUE; } } break; #ifdef MESURE_CONTINUE case 'L' : if (inde == 9) { if ( (line[1] == 'I') && (line[2] == 'S') && (line[3] == 'S') && (line[4] == 'A') && (line[5] == 'G') && (line[6] == 'E') && (line[7] == ' ')) { ik = atoi(line + 8); if ((ik >= 4) && (ik <= 8)) { lissage = ik; done = TRUE; } } } break; #endif case 'M' : if ( (line[1] == 'O') && (line[2] == 'D') && (line[3] == 'E') && (line[4] == 'B')) { if (inde == 5) { // ik = DDRB & 0x0F; ik = DDRB; ik1 = ik >> 4; ik2 = ik & 0x0F; ij = 0; MsgBuffer[ij++] = 'M'; MsgBuffer[ij++] = 'O'; MsgBuffer[ij++] = 'D'; MsgBuffer[ij++] = 'E'; MsgBuffer[ij++] = 'B'; MsgBuffer[ij++] = ' '; // Valeur affichée en hexa MsgBuffer[ij++] = '0'; MsgBuffer[ij++] = 'x'; MsgBuffer[ij++] = (ik1 >= 10) ? (ik1 + 55) : (ik1 + 48); MsgBuffer[ij++] = (ik2 >= 10) ? (ik2 + 55) : (ik2 + 48); MsgBuffer[ij] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); done = TRUE; } else { if ( (inde >= 7) && (inde <= 8) && (line[5] == ' ') && ((line[6] >= '0') && (line[6] <= '9'))) { ik = atoi(line + 6); if ((ik >= 0) && (ik <= 15)) { DDRB = (0x0F << 4) | ik; done = TRUE; } } } } break; case 'P' : // Commandes sur les ports I/O if (inde >= 7) { if ( (line[1] == 'O') && (line[2] == 'R') && (line[3] == 'T') && (line[4] == 'B') && (line[5] == ' ')) { // Numero de pinoche de 1 a 8 ik = line[6] - 48; if ((ik >= 1) && (ik <= 8)) { pina = ik - 1; if (inde == 7) { PortBState(pina, TRUE); done = TRUE; } else { if (inde >= 10) { if ((line[7] == ' ') && (line[8] == 'O')) { // Commandes a ON if (line[9] == 'N') { // Simple commande a ON if (line[10] == '\0') { PORTB &= (~(1 << pina)); done = TRUE; } #ifdef EXTENSION_TIMER // Commande a ON avec duree if (line[10] == ' ') { duree = atol(line + 11); if ((duree > 0L) && (duree <= MAX_DUREE)) { portbeta[pina] = PortBState(pina, FALSE); portbend[pina] = timer + duree; portsflg |= (1 << pina); PORTB &= (~(1 << pina)); done = TRUE; } } #endif } if ((line[9] == 'F') && (line[10] == 'F')) { // Simple commande a OFF if (line[11] == '\0') { PORTB |= (1 << pina); done = TRUE; } #ifdef EXTENSION_TIMER // Commande a OFF avec duree if (line[11] == ' ') { duree = atol(line + 11); if ((duree > 0L) && (duree <= MAX_DUREE)) { portbeta[pina] = PortBState(pina, FALSE); portbend[pina] = timer + duree; portsflg |= (1 << pina); PORTB |= (1 << pina); done = TRUE; } } #endif } } } } } else { // Numero de pinoche incorrecte Syntaxe(); } } } else { if (inde == 6) { if ( (line[1] == 'O') && (line[2] == 'R') && (line[3] == 'T') && (line[4] == 'B') && (line[5] == 'S')) { for (pina = 0; pina < 8; pina ++) PortBState(pina, TRUE); done = TRUE; } } } break; case 'R' : if (inde >= 11) { // Commande RELAIS Numero ON|OFF [DUREE] // Comme la commande PORTB mais a ON pour relais monte // et les ports 5 a 8 correspondent aux relais 1 a 4 if ( (line[1] == 'E') && (line[2] == 'L') && (line[3] == 'A') && (line[4] == 'I') && (line[5] == 'S') && (line[6] == ' ') && (line[8] == ' ') && (line[9] == 'O')) { // Numero de relais de 1 a 4 pina = (line[7] - 48); if ((pina >= 1) && (pina <= 4)) { // Les relais sont cables sur PORTB 5 a 8 pina += 3; // Commandes a ON if (line[10] == 'N') { // Simple commande a ON if (line[11] == '\0') { PORTB |= (1 << pina); done = TRUE; } #ifdef EXTENSION_TIMER // Commande a ON avec duree if (line[11] == ' ') { duree = atol(line + 11); if ((duree > 0L) && (duree <= MAX_DUREE)) { portbeta[pina] = PortBState(pina, FALSE); portbend[pina] = timer + duree; portsflg |= (1 << pina); PORTB |= (1 << pina); done = TRUE; } } } // Fin de commande ON #endif if ((line[10] == 'F') && (line[11] == 'F')) { // Simple commande a OFF if (line[12] == '\0') { PORTB &= (~(1 << pina)); done = TRUE; } #ifdef EXTENSION_TIMER // Commande a OFF avec duree if (line[12] == ' ') { duree = atol(line + 12); if ((duree > 0L) && (duree <= MAX_DUREE)) { portbeta[pina] = PortBState(pina, FALSE); portbend[pina] = timer + duree; portsflg |= (1 << pina); PORTB &= (~(1 << pina)); done = TRUE; } } #endif } // Fin de commande OFF } // Fin numero de relais de 1 a 4 } // Fin de commande RELAIS } // Fin de longueur de commande >= 11 break; #ifdef EXTENSION_TIMER case 'T' : if (inde == 7) { if ( (line[1] == 'E') && (line[2] == 'S') && (line[3] == 'T') && (line[4] == 'L') && (line[5] == 'E') && (line[6] == 'D')) { testled = (! testled); ij = 0; MsgBuffer[ij++] = 'T'; MsgBuffer[ij++] = 'E'; MsgBuffer[ij++] = 'S'; MsgBuffer[ij++] = 'T'; MsgBuffer[ij++] = 'L'; MsgBuffer[ij++] = 'E'; MsgBuffer[ij++] = 'D'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = 'i'; MsgBuffer[ij++] = 's'; MsgBuffer[ij++] = ' '; MsgBuffer[ij++] = 'O'; MsgBuffer[ij++] = (testled) ? 'N' : 'F'; MsgBuffer[ij++] = (testled) ? '\0' : 'F'; MsgBuffer[ij] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); done = TRUE; } } break; case 'U' : if (inde == 6) { if ( (line[1] == 'P') && (line[2] == 'T') && (line[3] == 'I') && (line[4] == 'M') && (line[5] == 'E')) { Uptime(0); done = TRUE; } } break; #endif case 'V' : if (inde == 7) { if ( (line[1] == 'E') && (line[2] == 'R') && (line[3] == 'S') && (line[4] == 'I') && (line[5] == 'O') && (line[6] == 'N')) { SendString(MsgVersion); SendString(MsgCRLF); done = TRUE; } } break; #ifdef WATCHDOG case 'W' : if (inde >= 9) { if ( (line[1] == 'A') && (line[2] == 'T') && (line[3] == 'C') && (line[4] == 'H') && (line[5] == ' ')) { if ( (inde == 9) && (line[6] == 'O') && (line[7] == 'F') && (line[8] == 'F')) { watchdog = 0L; cmdwatch[0] = '\0'; done = TRUE; } else { ij = 6; u32tmp = 0L; while ((line[ij] >= '0') && (line[ij] <='9')) { u32tmp = (10 * u32tmp) + (line[ij] - 48); ij ++; } if ( (u32tmp >= MIN_WATCHDOG) && (u32tmp <= MAX_WATCHDOG) && (line[ij] == ' ') && ((line[ij + 1] == 'P') || (line[ij + 1] == 'R')) && ((line[ij + 2] == 'O') || (line[ij + 2] == 'E')) && ((line[ij + 3] == 'R') || (line[ij + 3] == 'L')) && ((line[ij + 4] == 'T') || (line[ij + 4] == 'A')) && ((line[ij + 5] == 'B') || (line[ij + 5] == 'I')) && ((line[ij + 6] == ' ') || (line[ij + 6] == 'S'))) { ij ++; ik = 0; MsgBuffer[0] = 'W'; MsgBuffer[1] = 'A'; MsgBuffer[2] = 'T'; MsgBuffer[3] = 'C'; MsgBuffer[4] = 'H'; MsgBuffer[5] = ':'; // Copier la commande while (line[ij] >= SPACE) { cmdwatch[ik] = line[ij]; MsgBuffer[ik + 6] = line[ij]; ij++; ik++; } cmdwatch[ik] = '\0'; MsgBuffer[ik + 6] = '\0'; watchdog = u32tmp; SendString(MsgBuffer); SendString(MsgCRLF); done = TRUE; } } } } break; #endif } ij = 0; if (done) { MsgBuffer[ij++] = 'O'; MsgBuffer[ij++] = 'K'; #ifdef WATCHDOG silence = 0L; #endif } else { MsgBuffer[ij++] = 'E'; MsgBuffer[ij++] = 'R'; MsgBuffer[ij++] = 'R'; } MsgBuffer[ij] = '\0'; SendString(MsgBuffer); SendString(MsgCRLF); } Prompt(); return(FALSE); } // #ifdef EXTENSION_TIMER // ---------------------------------------------------------- I n i t _ L e d // void Init_Led(void) { // Activer Pin 0 du port B en output // DDRB |= (1 << 0); // } // #endif // ------------------------------------------------------ R e s e t _ L i n e void Reset_Line(void) { for (inde = 0; inde < 32; inde ++) line[inde] = '\0'; inde = 0; } // ------------------------------------------------------ I n i t _ P o r t B void Init_PortB(void) { // Activer les pins du port B en input DDRB = 0x00; PORTB = 0x00; } #ifdef EXTENSION_TIMER // ------------------------------------------------------ I n i t _ T i m e r void Init_Timer(void) { // Configurer le Timer en CTC mode TCCR1B |= (1 << WGM12); // Activation de l'interrupt CTC TIMSK |= (1 << OCIE1A); // Pour une interruption toutes les 1/10e seconde OCR1A = 12500; // Timer a Frequence CPU / 64 TCCR1B |= ((1 << CS10) | (1 << CS11)); sei(); } #endif // -------------------------------------------------------- I n i t _ C o m m void Init_Comm(int diviseur) { // Set Baud rate - Cast High byte UBRRH = (u8)(diviseur >> 8); // Set Baud rate - Cast Low byte UBRRL = (u8) diviseur; // Enable Receiver & Transmitter UCSRB = (1<= 97) && (ch <= 122)) ch -= 32; if (debug) { if (ch < 0x20) { if ((ch != 13) && (ch != 8)) { line[inde++] = '^'; ch +=64; } } } } if ((ch > 0x20) && (ch < 127)) { line[inde++] = ch; inde %= 0x1f; } else { // Les blancs de debut de ligne sont ignores if (ch == 0x20) { if (inde) { line[inde++] = ch; inde &= 0x3f; } } else { if (ch == 13) { if (inde == 0) { Banniere(); } else { // Traiter la ligne dans le buffer Traitement_Ligne(); Reset_Line(); } } else { if (((ch == 8) || (ch == 127)) && (inde > 0)) { inde --; } } } } if (inde >= 60) { Reset_Line(); } line[inde] = 0; } #ifdef EXTENSION_TIMER // Traiter les delais en attente if (seconds != timer) { seconds = timer; if (portsflg) { for (ij = 0; ij < 8; ij ++) { if (portsflg & (1 << ij)) { if (portbend[ij] <= seconds) { if (portbeta[ij]) PORTB &= (~(1 << ij)); else PORTB |= (1 << ij); // Resetter le flag portsflg &= (~(1 << ij)); } } } } #ifdef WATCHDOG if (watchdog > 0L) { if (silence >= watchdog) { ij = 0; while (cmdwatch[ij] >= SPACE) { line[ij] = cmdwatch[ij]; ij++; } line[ij] = '\0'; inde = ij - 1; Traitement_Ligne(); Reset_Line(); } } #endif #ifdef MESURE_CONTINUE if (time_mesure >= INTERVALLE) { // Limiter a deux mesures for (ij = rm; ij < (rm + 2); ij ++) { ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1)| (1 << ADPS0); // Choix du Canal et de la reference de tension // ADMUX = 0xE0 | Canal; ADMUX = (1 << REFS1) | (1 << REFS0) | ij; // Activer la conversion ADCSRA = ADCSRA | ( 1 << ADSC); // Attendre le bit ADIF while (! (ADCSRA & (1 << ADIF))); val = ADCL; val |= (ADCH << 8); // Decalage des mesures precedentes ik = ij * 8; im = ik + (lissage - 1); while (ik < im) { mesures[ik] = mesures[ik + 1]; ik ++; } mesures[ik] = val; } rm += 2; if (rm >= 8) { time_mesure = 0; rm = 0; } } #endif } #endif } return(0); } /* -------- End of lndk_avr006.c -------- That's All, Folks -------- */