ZL27ARM: obsługa cyfrowego termometru TC77
Odczytywanie zmierzonej wartości temperatury z układu TC77 i wysyłanie danych do wyświetlacza LCD odbywa się podczas obsługi przerwania SysTick. Na listingu 2 zamieszczono funkcję obsługi tego przerwania. Odczyt temperatury jest realizowany przez funkcję TC77_GetTemp. Należy pamiętać, że wartość temperatury jest zapisana w 13 bardziej znaczących bitach, gdzie najstarszy to bit znaku. Należy więc wykonać przesunięcie o 3 bity w prawo, dodatkowo 2 najmniej znaczące bity są zerowane. W wyniku tych operacji uzyskiwana jest dokładność 0,25°C. Do przechowywania wartości zmierzonej temperatury w °C jest wykorzystywana ta sama zmienna, do której wcześniej była odczytywana wartość temperatury z układu TC77. Obliczenie temperatury jest realizowane przez iloczyn rejestru i liczby 625 w wyniku czego zmienna temp_tc77 przechowuje wartość temperatury postaci 10-4°C. Wcześniej jest sprawdzane, czy rejestr nie ma ustawionego bitu informującego o temperaturze ujemnej. W przypadku temperatur poniżej zera, aby uzyskać poprawny wynik, należy wartość zanegować i dodać 1 oraz usunąć wyzerować bit znaku.
List. 2
void SysTick_Handler(void) { extern uint32_t temp_tc77; //odczyt temperatury temp_tc77 = TC77_GetTemp(); //wyznaczenie temperatury temp_tc77 = temp_tc77 >> 3; //temp dodatnia if((temp_tc77 & 0x1000) == 0) { temp_tc77 = temp_tc77 & (~0x3); temp_tc77 = temp_tc77 * 625; PCD8544_LCDWriteSignDouble(' ', 0, 2); } //temp ujemna else { temp_tc77 = (~temp_tc77 + 1) & 0x0FFC; temp_tc77 = temp_tc77 * 625; PCD8544_LCDWriteSignDouble('-', 0, 2); } //zapisanie temperatury PCD8544_LCDWriteSignDouble(temp_tc77 % 1000000 / 100000 + 0x30, 12, 2); PCD8544_LCDWriteSignDouble(temp_tc77 % 100000 / 10000 + 0x30, 24, 2); PCD8544_LCDWriteSignDouble(',', 36, 2); PCD8544_LCDWriteSignDouble(temp_tc77 % 10000 / 1000 + 0x30, 48, 2); PCD8544_LCDWriteSignDouble(temp_tc77 % 1000 / 100 + 0x30, 60, 2); PCD8544_LCDWriteSignDouble(0x5C, 72, 2); //zapis wyświetlacz danymi PCD8544_LCDWrite(); }
Dla zwiększenia przejrzystości w programie zastosowano trzy funkcje obsługi układu TC77. Pierwsza z nich (TC77_Init) służy do inicjalizacji układu, druga (TC77_GetTemp) do odczytania temperatury, trzecia funkcja (TC77_GetID) do pobrania ID układu. Funkcja pobrania ID układu jest niemal identyczna, jak pobrania wartości rejestru temperatury – różnica polega jedynie na tym, że w przypadku tej drugiej zaraz po pobraniu rejestru temperatury następuje zakończenie transmisji. Na listingu 3 przedstawiono funkcję pobrania ID układu TC77.
List. 3
uint16_t TC77_GetID(void) { uint16_t temp = 0; //ustawienie linii - stan niski Select_TC77; //włączenie spi SPI1->CR1 |= SPI_CR1_SPE; //oczekiwanie na zakończenie odbioru danych while (((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET)){}; //odczyt odebranych danych SPI1->DR; //ustawienie na wysyłanie SPI1->CR1 |= SPI_CR1_BIDIOE; //wysłanie danych SPI1->DR = 0xFFFF; //oczekiwanie na zakończenie pracy SPI while (((SPI1->SR & SPI_I2S_FLAG_BSY) != (uint16_t)RESET)){}; //przełączenie odbiór SPI1->CR1 &= ~SPI_CR1_BIDIOE; //oczekiwanie na zakończenie odbioru danych while (((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET)){}; //odczyt odebranych danych temp = SPI1->DR; //przełączenie w tryb wysyłania SPI1->CR1 |= SPI_CR1_BIDIOE; //wysłanie danych SPI1->DR = 0x0000; //oczekiwanie na zakończenie pracy SPI while (((SPI1->SR & SPI_I2S_FLAG_BSY) != (uint16_t)RESET)){}; //wyłączenie SPI SPI1->CR1 &= ~SPI_CR1_SPE; //przełączenie w tryb odbioru SPI1->CR1 &= ~SPI_CR1_BIDIOE; //ustawienie linii - stan wysoki Deselect_TC77; return temp; }
Interfejs SPI w mikrokontrolerze STM32 pracuje jako Master, tak więc w czasie odbioru na linię SCK jest wystawiany sygnał o określonej częstotliwości. W celu uniknięcia tego, program po zakończeniu transmisji wyłącza interfejs SPI wykorzystując polecenie SPI1->CR1 &= ~SPI_CR1_SPE (zerujące bit SPE). Natomiast rozpoczęcie transmisji wymaga ustawienia tego bitu, jest to realizowane przez polecenie SPI1->CR1 |= SPI_CR1_SPE. Należy także zwrócić uwagę na przełączanie z trybu odbioru do nadawania realizowane przez polecenie SPI1->CR1 |= SPI_CR1_BIDIOE, powodujące ustawienie bitu BIDIOE. Wyzerowanie tego bitu powoduje przejście do trybu odbioru, polecenie ma postać SPI1->CR1 &= ~SPI_CR1_SPE. Wartość rejestru jest zwracana poleceniem return.
Mariusz Dziębowski
m.dziebowski@interia.pl
Odnośniki:
Moduł wyświetlacza LCD KAmodLCD1
Zestaw uruchomieniowy ZL27ARM
Karta katalogowa układu TC77