#include "msp.h" #include #include #include #include // ==========Definizione costanti========== typedef enum {false=0, true=1} bool; // definizione tipo bool // costanti dei tempi di acquisizione #define STEP 10 // 10 us tempo dell'interrupt #define TIME_ON 50 // 200 us led IR on, signal = 0 V #define TIME_ADC_START 0 // 100 us inizio istante di acquisizione #define TIME_OFF 450 // 650 us led IR off, signal = 3,3 V #define TIME_ADC_END 1000 // 800 us fine istante di acquisizione #define TIME_SAVE 1200 // 900 us controllo fine ciclo #define TIME_RESET 10000 // 1.000 us periodo del segnale generato // costanti comandi protocollo trasmissione seriale #define com_PING 'P' // ping #define com_T 'T' // parametro T (periodo in minuti) #define com_N 'N' // parametro N (numero campioni per periodo) #define com_UTC 'U' // sincronizzazione data/ora #define com_MODE 'A' // 0 (off) - 1 (auto) - 2 (manual) #define com_START 'S' // inizio acquisizione degli N valori #define com_RESET 'R' // provoca reset #define com_VALUE 'D' // invio di N valori #define com_END 'E' // fine invio valori #define com_LOG 'L' // stringa di log // ==========Dichiarazione variabili globali========== // parametri modificabili via seriale a run-time int T = 5; // min // Periodo globale di acquisizione [N/100/60 < T < 32767] int N = 100; // Numero di campioni memorizzati per periodo [ 1 < N < 16384] // variabili tempi int microsecondi = 0; // contatore di microsecondi del timer A0 [0 - 10.000] int minuti = 0; // contatore di minuti del Real Time Clock [0 - T] // indici contatori array int index_N = 0; // contatore campioni [0 - N] int index_Singola = 0; // variabili acquisizione uint16_t values[16384]; // array che contiene tutti gli N valori di un periodo uint16_t values_Singola[50]; char micro[8]; // variabili ricezione seriale char RXData[32]; // buffer che contiene la stringa ricevuta char RXByte; // ultimo byte ricevuto int index_RX; // indice del ciclo che riempie il buffer RXData int indice; int somma = 0; int media = 0; // ==========Funzioni in/out========== void IR_off() {P4OUT |= BIT2;} void IR_on() {P4OUT &= ~BIT2;} //void fan_on() {P4OUT |= BIT4;} //void fan_off() {P4OUT &= ~BIT4;} void led_on() {P1OUT |= BIT0;} void led_off() {P1OUT &= ~BIT0;} void TA0_on() {TA0CCTL0 |= CCIE;} void TA0_off() {TA0CCTL0 &= ~CCIE;} void auto_on(){ //fan_on(); RTCCTL0_H = RTCKEY_H; RTCCTL0_L |= RTCTEVIE; RTCCTL0_H = 0;} void auto_off(){ //fan_off(); RTCCTL0_H = RTCKEY_H; RTCCTL0_L &= ~RTCTEVIE; RTCCTL0_H = 0;} // ===========================Funzioni Real Time Clock=========================== void get_now(char *now){ // legge i registri del 'Real Time Clock' e scrive la data in now sprintf(now , "%04x-", RTCYEAR); sprintf(now + 5, "%02x-", RTCMON); sprintf(now + 8, "%02x ", RTCDAY); sprintf(now + 11, "%02x:", RTCHOUR); sprintf(now + 14, "%02x:", RTCMIN); sprintf(now + 17, "%02x\n", RTCSEC); } void set_rtc(char *date){ // riceve una data in formato stringa 'YYYY-MM-DD hh:mm:ss' e scrive i registri del 'Real Time Clock' RTCCTL0_H = RTCKEY_H; // Unlock RTC key protected registers RTCYEAR = strtol(&date[ 0], NULL, 16); RTCMON = strtol(&date[ 5], NULL, 16); RTCDAY = strtol(&date[ 8], NULL, 16); RTCHOUR = strtol(&date[11], NULL, 16); RTCMIN = strtol(&date[14], NULL, 16); RTCSEC = strtol(&date[17], NULL, 16); RTCCTL0_H = 0; // Lock RTC key protected registers } // ===========================Funzioni Protocollo Seriale=========================== void send_char(char c){ // invia un carattere sulla seriale while(!(UCA0IFG&UCTXIFG)); //finchè c' da trasmettere UCA0TXBUF = c; //riempie il buffer di trasmissione } int send(char command, char *text){ send_char(command); // invio comando int i=0; while (text[i] != 10){ // finchè è diverso da 'a capo \n' send_char(text[i]); i++; } // invio testo send_char(10); // invio '\n' return i+2; // restituisce il numero di caratteri inviati } void send_all_values(){ int i, i_N; int n=0; int samples_per_row = 20; //sono il numero di campioni su gni riga stampati su monitor (10000/20=500 righe di campioni adc) char TXData[32]; char UTC[32]; get_now(UTC); for (i_N=0; i_N 00b = Minute changed event // RTC enable, BCD mode, RTC hold // enable RTC read ready interrupt // enable RTC time event interrupt RTCCTL1 &= ~(RTCHOLD); // Start RTC calendar mode RTCCTL0_H = 0; // Lock the RTC registers NVIC_ISER0 = 1 << ((INT_RTC_C - 16) & 31); // ==========Inizializzazione========== //fan_off(); led_off(); // Led msp spento (si accende solo alle acquisizioni) IR_off(); // Led IR spento set_rtc("2000-01-01 00:00:00"); // Setto rtc __sleep(); //while(1); } // ===========================Interrupt Service Routines=========================== void ADC14_IRQHandler(void) { if (ADC14IFGR0 & ADC14IFG0) { values[index_N] = ADC14MEM0; // Scrive valore buffer nell'array index_N++; } } // Timer A0 interrupt service routine void TimerA0_0IsrHandler(void) { TA0CCTL0 &= ~CCIFG; /* STEP = 20; Tempo di campionamento compreso tra adc_start, adc_end; Riempio array e invio su seriale */ if(microsecondi > TIME_ADC_START && microsecondi <= TIME_ADC_END) { ADC14CTL0 |= ADC14SC; // Start sampling/conversion; Enable and start conversion. //sprintf(micro, "%07d\n", microsecondi); // Converto da intero a stringa dentro variabile micro //send(com_LOG, micro); // ---------->USED TO CONTROL TIMERA AND FREQUENCY //while(!(ADC14IFGR0 & BIT0)); // Controlla che non abbia finito //values[index_N] = ADC14MEM0; // Scrive valore buffer nell'array //index_N++; // Incrementa indice array } switch (microsecondi){ case TIME_ON: // Accendo IR IR_on(); //send(com_LOG, "IR_ON\n"); break; case TIME_OFF: // Spengo IR IR_off(); //send(com_LOG, "IR_OFF\n"); break; case TIME_SAVE: // Invio valori /* QUI DENTRO FACCIO IL CALCOLO MEDIA DELL'ARRAY2 per metterlo in quello principale ovvero la values[index_N] = "media calcolata da values[index_M]" */ /*for(indice = 0; indice < index_Singola; indice ++) { somma += values_Singola[indice]; } media = somma/index_Singola; values[index_N] = media; index_N++; media = 0; somma = 0; index_Singola = 0;*/ if (index_N >= N){ index_N = 0; microsecondi = 0; TA0_off(); led_off(); send_all_values(); } default: break; } microsecondi += STEP; // Interrupt ogni STEP if (microsecondi >= TIME_RESET){ microsecondi = 0; } } // UART interrupt service routine (Seriale) void eUSCIA0IsrHandler(void) { /* Eseguita quando viene ricevuto un byte sulla seriale. * Se il byte e' 10 (\n) chiama received che elabora il messaggio ricevuto */ if (UCA0IFG & UCRXIFG) { while(!(UCA0IFG & UCTXIFG)); RXByte = UCA0RXBUF; RXData[index_RX++] = RXByte; if(RXByte==10) { index_RX=0; received(); } } } // RTC interrupt service routine (essendo in real time VA IN MINUTI vedi configurazione SOPRA rtc) void RtcIsrHandler(void) { if (RTCCTL0 & RTCTEVIFG) { // Evento abilitato in modalita' automatica, accade ogni minuto if (minuti == 0){ TA0_on(); led_on(); } // Se T e' maggiore di 5 minuti, spengo la ventola e la riaccendo un minuto prima di ricominciare /*if (T > 5){ if (minuti == 4){ //fan_off(); } if (minuti >= T-1){ //fan_on(); } }*/ minuti++; if (minuti >= T) { minuti = 0; microsecondi = 0; } } // Chiudo l'interrupt flag RTCCTL0_H = RTCKEY_H; RTCCTL0_L &= ~RTCTEVIFG; RTCCTL0_H = 0; }