LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Digilent Pmod i STM32 (cz. 8) – PmodMTDS, PmodRTCC i PmodCMPS2

PmodRTCC

Drugi z prezentowanych w tej części modułów to PmodRTCC zawierający zegar czasu rzeczywistego z kalendarzem oparty o układ Microchip MCP79410. Układ ten umożliwia dodatkowo ustawienie dwóch alarmów, generację fali prostokątnej, a także korzystanie z pamięci EEPROM (128 B) i SRAM (64 B). Do obsługi modułu PmodRTCC została udostępniona biblioteka RTCCI2C dostępna na stronie producenta: https://reference.digilentinc.com/pmod/pmod/rtcc/example_code. Jest ona przeznaczona dla środowiska MPIDE, dlatego na potrzeby opisywanego przykładu musiała ona zostać modyfikowana tak, aby mogła być użyta w środowisku Atollic z mikrokontrolerem STM32L496ZGT6.

Fotografia 4. Moduł PmodRTCC

Połączenie z modułem KAmeleon

Moduł PmodRTCC posiada 8-pinowe złącze dla interfejsu I2C (J2) i 2-pinowe złącze J1 zawierające piny MFP (Multi-Function Pin), a także GND. Pin MFP może pełnić różne funkcje, zależnie od konfiguracji układu – w prezentowanym przykładzie będzie on źródłem przerwań wywołanych wystąpieniem alarmu. Sygnały modułu PmodRTCC podłączono do złącza oznaczonego jako ARDUINO CONNECTOR na płytce KAmeleon zgodnie z tabelą 4 i fotografią 5.

Tabela 4. Sposób podłączenia modułu PmodRTCC do złącza ARDUINO CONNECTOR zestawu KAmeleon

Sygnał Numer pinu PmodRTCC Numer pinu KAmeleon ARDUINO CONNECTOR Pin mikrokontrolera
SCL 1 (J2) D15 PF14
SDA 2 (J2) D14 PF15
MFP 1 (J1) D13 PB10

Fotografia 5. Moduł PmodRTCC podłączony do płytki KAmeleon

Kod przykładu

Za obsługę interfejsu I2C odpowiadają trzy zmodyfikowane metody klasy RTCCI2C: begin, readValue i writeValue. Pierwsza z nich, przedstawiona na listingu 5, odpowiada za konfigurację interfejsu I2C4, a także pinu PB10 do obsługi przerwania. Przerwanie jest wykrywane na zboczu opadającym sygnału MFP w momencie wystąpienia alarmu. Dla komunikacji I2C konfigurowane są dwa piny – PF14 i PF15 oraz interfejs I2C4. Dla tego ostatniego konieczne jest podanie wartości rejestru TIMINGR, przedstawionego na rysunku 6. Jest on odpowiedzialny za generację odpowiednich przebiegów czasowych na liniach SDA i SCL: SCLL i SCLH definiują długość stanu niskiego i wysokiego sygnału SCL, SCLDEL oznacza opóźnienie pomiędzy ustawieniem wartości na linii danych a zboczem narastającym sygnału zegarowego, natomiast SDADEL opóźnienie pomiędzy zboczem opadającym zegara, a zmiana stanu na linii danych. Pole PRESC wyznacza dzielnik sygnału zegarowego taktującego układ I2C mikrokontrolera.

Kod programu z plikami projektowymi środowiska Atollic można pobrać w sekcji „Do pobrania”

Listing 5. Konfiguracja interfejsu I2C do komunikacji z modułem PmodRTCC

void RTCCI2C::begin()
{
	__HAL_RCC_I2C4_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOF_CLK_ENABLE();
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Pin = GPIO_PIN_10;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);
	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
	GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF4_I2C4;
	GPIO_InitStruct.Pin = GPIO_PIN_14 | GPIO_PIN_15;
	HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
	this->i2c.Instance = I2C4;
	this->i2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
	this->i2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
	this->i2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
	this->i2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
	this->i2c.Init.OwnAddress1 = 0x01;
	this->i2c.Init.Timing = 0x10563046;
	HAL_I2C_Init(&this->i2c);
}

Rysunek 6. Definicja rejestru I2C_TIMINGR (źródło: dokumentacja mikrokontrolera STM32L496ZG)

Funkcje odpowiedzialne za komunikację z modułem PmodRTCC przedstawiono na listingu 6. Wykorzystują one blokujące wywołania HAL_I2C_Master_Transmit i HAL_I2C_Master_Receive biblioteki STM32Cube.

Listing 6. Funkcje realizujące odczyt i zapis rejestru.

{
	uint8_t value = 0;
	HAL_I2C_Master_Transmit(&this->i2c, RTCC_I2C_ADDR, &address, 1, 100);
	HAL_I2C_Master_Receive(&this->i2c, RTCC_I2C_ADDR, &value, 1, 100);
	return value;
}

void RTCCI2C::writeValue(uint8_t address, uint8_t value)
{
	uint8_t data[2] = {address, value};
	HAL_I2C_Master_Transmit(&this->i2c, RTCC_I2C_ADDR, data, 2, 100);
}

Konfiguracja rejestrów MCP79410

Oprócz wymienionych funkcji, klasa RTCCI2C zawiera także metody konfigurujące poszczególne rejestry układu MCP79410. W tabeli 5 wymieniono funkcje użyte w kodzie przykładu. Wszystkie wartości są zapisywane i odczytywane w kodzie BCD.

Tabela 5. Metody klasy RTCCI2C użyte w przykładzie

Metoda klasy RTCCI2C Opis
startClock/stopClock Uruchomienie/zatrzymanie zegara przez włączenie/wyłączenie oscylatora.
setSec/getSec Zapis/odczyt sekund zegara lub alarmu.
setMin/getMin Zapis/odczyt minut zegara lub alarmu.
setHour/getHour Zapis/odczyt godziny zegara lub alarmu.
setDay/getDay Zapis/odczyt dnia tygodnia (0x01 – 0x07) zegara lub alarmu.
setDate/getDate Zapis/odczyt dnia miesiąca (0x01 – 0x32) zegara lub alarmu.
setMonth/getMonth Zapis/odczyt miesiąca (0x01 – 0x12) zegara lub alarmu.
setYear/getYear Zapis/odczyt roku (0x00 – 0x99) zegara lub alarmu.
enableAlarm Włączenie alarmu
getAmPm Czas dla zegara 12-godzinnego (AM/PM).

Funkcja main

Funkcję main przykładowej aplikacji przedstawiono na listingu 7. Konfiguruje ona moduł PmodRTCC i ustawia datę: Niedziela, 4. marca 2018 23:15:30. Następnie ustawiany jest alarm na 10 sekund od zdefiniowanej daty. Pętla główna, za pomocą funkcji pomocniczej printTime, co sekundę odczytuje datę i godzinę. Odczytane wartości są od razu wysyłane na port szeregowy LPUART1. Alarm jest sygnalizowany przez zapalenie diody LED1 podłączonej do pinu PC7. Port szeregowy LPUART1 jest konfigurowany i obsługiwany za pomocą kodu znajdującego się w pliku serial.c, natomiast sterownik diody został umieszczony w pliku led.c.

Listing 7. Kod główny przykładowej aplikacji

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  Serial_Config();
  Led_Config();
  RTCCI2C myRTCC;
  myRTCC.begin();
  //set the real time clock
  myRTCC.stopClock();
  myRTCC.setSec(RTCC_RTCC, 0x30);
  myRTCC.setMin(RTCC_RTCC, 0x15);
  myRTCC.setHour(RTCC_RTCC, 0x11, RTCC_PM);
  myRTCC.setDay(RTCC_RTCC, 0x07);
  myRTCC.setDate(RTCC_RTCC, 0x04);
  myRTCC.setMonth(RTCC_RTCC, 0x03);
  myRTCC.setYear(0x18);
  // Set the alarm for 10 seconds after written time.
  myRTCC.setSec(RTCC_ALM0, 0x40);
  myRTCC.setMin(RTCC_ALM0, 0x15);
  myRTCC.setHour(RTCC_ALM0, 0x11, RTCC_PM);
  myRTCC.setDay(RTCC_ALM0, 0x07);
  myRTCC.setDate(RTCC_ALM0, 0x04);
  myRTCC.setMonth(RTCC_ALM0, 0x03);
  myRTCC.enableAlarm(RTCC_ALM0, RTCC_ALMC2 | RTCC_ALMC1 | RTCC_ALMC0);
  myRTCC.startClock();
  while(1) {
    HAL_Delay(1000);
    printTime(&myRTCC, RTCC_RTCC);
  }
}
Moduły PmodMTDS, PmodRTCC i PmodCMPS2, a także zestaw KAmeleon oraz wiele innych płytek ewaluacyjnych i modułów rozszerzających można znaleźć w ofercie Kamami.pl