Aplikacja
Kod źródłowy programu pokazano na listingu 5.
List. 5. Funkcja main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
// "MSP430 z pamięcią FRAM" // konfiguracja "MSP-EXP430FR5739": // Zadanie numer 7.1. Obsługa analogowego wejścia. Termistor. // (ustawienia fabryczne) // // w programie wykorzystano // ACLK nieaktywny // zainstalowany w module // MCLK = SMCLK = DCOCLK ~1MHz // termistor NTC, 100 kOm // // do modułu podłączamy wyświetlacz // MSP430FR5739 // // ----------------- // działanie programu: // | | // raz na sekundę wykonywany jest pomiar // | P1.0 | -> LCD E // napięcia na wyjściu termistora NTC // | P1.1 | -> LCD RS // wynik pomiaru konwertowany jest na // | P2.0 | -> LCD D7 // wartość temperatury w st. Celsjusza // | P2.5 | -> LCD D6 // na ekranie LCD wyświetlane są: // A4 -> | P1.4 P2.6 | -> LCD D5 // wynik pomiaru binarnie i w Voltach // NTC on/off <- | P2.7 P2.1 | -> LCD D4 Ł.K.'13 // oraz temperatura w st. Celsjusza //------------------------------------------------------------------- // // pliki nagłówkowe #include "io430.h" // rejestry procesora #include "intrinsics.h" // instrukcje procesora #include "LCD_2x16.h" // procedury LCD #include "tlv.h" // struktura TLV #include // funkcje wejścia/wyjścia // // zmienne globalne unsigned int wPomiaruB; // wynik pomiaru (binarnie) float wPomiaruV; // wynik pomiaru (Volty) float wPomiaruC; // wynik pomiaru (stopnie Celsjusza) // void main(void) // program główny { // WDTCTL = WDTPW + WDTHOLD; // zatrzymaj układ Watchdog // unsigned char tekst[16 + 1]; // zmienna lokalna // bufor, tekst ekranu LCD // // konfiguracja linii we/wy P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; P4OUT = 0x00; // stan niski na liniach PJOUT = 0x00; // linie w kierunku wyjścia P1DIR = 0xff; P2DIR = 0xff; P3DIR = 0xff; P4DIR = 0xff; // wszystkie linie to: PJDIR = 0xff; // wyjścia w stanie niskim // // konfiguracja LCD LcdPiny(); // linie we/wy LcdSekwencjaStartowa4b3V(); // sekwencja startowa LcdInicjalizacja(); // inicjalizacja LCD // // konfiguracja generatora REF while(REFCTL0 & REFGENBUSY); // czekaj dopóki gen. jest zajęty REFCTL0 = REFVSEL_0 + REFTCOFF; // ustaw napięcie VREF = 1.5V // wyłącz czujnik temperatury // P1SELC |= BIT4; // konfiguracja P1SEL1 |= BIT4; // wejścia analogowego A4 P1SEL0 |= BIT4; // ustaw trzeci funkcyjny tryb pracy // // konfiguracja przetwornika ADC ADC10CTL0 &=~ ADC10ENC; // wyzeruj bit zezwolenia na konwersję // próbkowanie 32 takty ADC10CLK ADC10CTL0 = ADC10SHT_3; // ustaw tryb pojedynczego pomiaru ADC10CTL1 = ADC10SHP + ADC10SHS_0 + ADC10SSEL_0 + ADC10CONSEQ_0; // taktowanie pomiaru z wew. osc. 5MHz ADC10CTL2 = ADC10RES; // rozdzielczość pomiaru 10 bitów ADC10MCTL0 = ADC10SREF_1 + ADC10INCH_4; // potencjały referencyjne: // V(R+) = VREF, V(R-) = AVSS // obsługa zew. kanału pomiarowego nr. 4 // ADC10IFG &=~ ADC10IFG0; // wyzeruj flagę przerwania ADC10IE |= ADC10IE0; // włącz obsługę przerwań // od zakończenia pomiaru napięcia // __bis_SR_register(GIE); // odblokuj obsługę // przerwań maskowalnych // while(1) // pętla główna programu { // while(REFCTL0 & REFGENBUSY); // czekaj dopóki gen. REF jest zajęty REFCTL0 |= REFON; // włącz generator P2OUT |= BIT7; // włącz zasilanie termistora NTC ADC10CTL0 |= ADC10ON; // włącz przetwornik ADC10 // __delay_cycles(100); // czekaj 100us // ADC10CTL0 |= ADC10ENC; // ustaw bit zezwolenia na konwersję ADC10CTL0 |= ADC10SC; // rozpocznij pomiar napięcia // (programowe wyzwalanie pomiaru) // __bis_SR_register(CPUOFF); // przejdź w tryb uśpienia LPM0 // koniec pomiaru, wyjście z uśpienia // P2OUT &=~ BIT7; // wyłącz zasilanie termistora NTC ADC10CTL0 &=~ ADC10ENC; // wyzeruj bit zezwolenia na konwersję ADC10CTL0 &=~ ADC10ON; // wyłącz przetwornik ADC10 while(REFCTL0 & REFGENBUSY); // czekaj dopóki gen. REF jest zajęty REFCTL0 &=~ REFON; // wyłącz generator nap. referencyjnego // // kalibracja binarnej wartości pomiaru wPomiaruB = (unsigned int)(wPomiaruB * (float)(sTlvRef.CAL_ADC_15VREF_FACTOR / 32768)); // (wzór 7.9) wPomiaruB = (unsigned int)(wPomiaruB * (float)(sTlvAdc10.CAL_ADC_GAIN_FACTOR / 32768)) + sTlvAdc10.CAL_ADC_OFFSET; // wPomiaruV = (float)(wPomiaruB * 1.5) / 1023; // obliczenie wartości w Voltach (wzór 7.4) wPomiaruC = (float)(0.4542 - wPomiaruV)/0.0088; // obliczenie wartości w st. Celsjusza (wzór 7.16) // // prezentacja wyniku // LcdWyczyscEkran(); // wyczyść ekran LCD LcdUstawKursorWK(0,0); // ustaw kursor na początku 1 linii snprintf((char*)tekst,17,"B: %.4d A: %.2fV",wPomiaruB,wPomiaruV);// wypisz wynik pomiaru prezentowany LcdPiszTekst(tekst); // binarnej oraz w Voltach // następnie LcdUstawKursorWK(1,0); // ustaw kursor na początku 2 linii snprintf((char*)tekst,17,"Temp: %.1f%cC",wPomiaruC,223); // wypisz wynik pomiaru prezentowany LcdPiszTekst(tekst); // w stopniach Celsjusza // __delay_cycles(1000000); // czekaj 1 sekundę }; // } // // #pragma vector=ADC10_VECTOR // procedura obsługi przerwania __interrupt void ADC10_ISR(void) // przetwornika A/C, moduł ADC10 { // switch(__even_in_range(ADC10IV,12))// odczytaj rejestr ADC10IV { // case 0: break; // brak przerwań case 2: break; // nadpisanie sekwencji pomiarowej case 4: break; // nadpisanie wyniku pomiaru case 6: break; // komparator analogowy, próg w górę case 8: break; // komparator analogowy, próg w dół case 10: break; // komparator analogowy, próg pomiędzy // case 12: // zakończenia pomiaru wPomiaruB = ADC10MEM0; // odczytaj wynik pomiaru __bic_SR_register_on_exit(CPUOFF); // wyjdź z trybu uśpienia break; // default: break; // brak obsługi } // } // |
W programie głównym zatrzymywana jest pracy układu Watchdog:
1 |
WDTCTL = WDTPW + WDTHOLD; |
Następnie konfigurowane są linie wejścia/wyjścia mikrokontrolera. Wszystkie linie wejścia/wyjścia ustawiane są jako wyjścia w stanie niskim. Najpierw ustawiany jest stan niski na liniach, następnie zmieniany jest kierunek linii z wejścia na wyjście:
1 2 |
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; P4OUT = 0x00; PJOUT = 0x00; P1DIR = 0xff; P2DIR = 0xff; P3DIR = 0xff; P4DIR = 0xff; PJDIR = 0xff; |