Подключаем часовую микросхему DS3231 к микроконтроллеру STM32f103.

В данном уроке мы подключим часовую микросхему DS3231 по шине I2C к микроконтроллеру STM32f103.

Параметры микросхемы DS3231:

 Напряжение питания: 3.3В и 5В
Точность: ± 0.432 сек в день
Частота кварца:32.768 кГц
 Поддерживаемый протокол: I2C

Для вывода данных на экран воспользуемся уроком №5, где мы подключали и выводили данные на OLED экран.

Для подключение к данной микросхеме нам понадобиться информация с документации, где указан адрес для чтения и записи, а так же номера регистров, где лежат данные:

Мы напишем две функции: первая из них будет записывать данные в микросхему (она нам понадобиться когда мы захотим выставить время), вторая будет считывать данные с микросхемы.

Подключение данной микросхемы:

  • Контакт SCL  – к контакту PB10 микроконтроллера STM32F103.
  • Контакт SDA– к контакту PB11 микроконтроллера STM32F103.
  • Контакт VCC – подаем 3.3V.
  • Контакт GND – земля.

Настройка шины I2C (используем I2C2):

Программный код:

/* USER CODE BEGIN PV */
uint8_t aTxBuffer[20]; // переменная в которой хранятся наши данные.
char str[100]; // переменная для выводу данных на экран
uint32_t i=0;
uint8_t sec=0,min=0,hour=0,day=0,date=0,month=0,year=0;

// Запись данных по шине I2C в микросхему DS3231

void I2C_WriteBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf)
{
while(HAL_I2C_Master_Transmit(&hi, (uint16_t)DEV_ADDR,(uint8_t*)&aTxBuffer, (uint16_t)sizebuf, (uint32_t)1000)!= HAL_OK)
{
if (HAL_I2C_GetError(&hi) != HAL_I2C_ERROR_AF)
{
sprintf(str, «Buffer error»);
LCD_Goto(8, 0);
OLED_string(str);
}
}
}

//считываем данные по шине I2C с микросхемы DS3231

void I2C_ReadBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf)
{
while(HAL_I2C_Master_Receive(&hi, (uint16_t)DEV_ADDR, (uint8_t*) &aTxBuffer, (uint16_t)sizebuf, (uint32_t)1000)!= HAL_OK)
{
if (HAL_I2C_GetError(&hi) != HAL_I2C_ERROR_AF)
{
sprintf(str, «Buffer error»);
LCD_Goto(8, 0);
OLED_string(str);
}
}
}

// преобразуем в двоичный код из десятичного

uint8_t RTC_ConvertFromDec(uint8_t c)
{
uint8_t ch = ((c>>4)*10+(0x0F&c));
return ch;
}

// Преобразуем из двоичного в десятичный код

uint8_t RTC_ConvertFromBinDec(uint8_t c)
{
uint8_t ch = ((c/10)<<4)|(c%10);
return ch;
}

/* USER CODE END PV */

/* USER CODE BEGIN WHILE */

// начальные данные времени
aTxBuffer[0]=0x00;
aTxBuffer[1]=0x00; //cekond(0-59)
aTxBuffer[2]=0x20;//minuti(0-59)
aTxBuffer[3]=0x15;//houer(1-12+AM/PM ??? 00-23)
aTxBuffer[4]=0x03; //dey nedeli(1-7)
aTxBuffer[5]=0x17; //data(01-31)
aTxBuffer[6]=0x10;//mecac(01-12)
aTxBuffer[7]=0x18; //yaer(00-99)

//????????? ? ??????? I2C-????? DS3231(0xD0) ? ????? ??????? ???????? DS3231(0x00)
I2C_WriteBuffer(hi2c2,(uint16_t)0xD0,1);
//???????? ?????????? ??????????
while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY)
{
}
//????????? ? DS3231 ?????? 7 ???? ?? ??????
I2C_WriteBuffer(hi2c2,(uint16_t)0xD0,19);
while (1)
{
/* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
LCD_Goto(5,2);
I2C_ReadBuffer(hi2c2,(uint16_t)0xD1,19);
date=aTxBuffer[7];
date = RTC_ConvertFromDec(date);
OLED_num_to_str(date,2);
LCD_Char(‘:’);
month=aTxBuffer[6];
month = RTC_ConvertFromDec(month);
OLED_num_to_str(month,2);
LCD_Char(‘:’);
year=aTxBuffer[5];
year = RTC_ConvertFromDec(year);
OLED_num_to_str(year,2);
LCD_Char(‘:’);
day=aTxBuffer[4];
day = RTC_ConvertFromDec(day);
OLED_num_to_str(day,2);
LCD_Char(‘:’);
hour=aTxBuffer[3];
hour = RTC_ConvertFromDec(hour);
OLED_num_to_str(hour,2);
LCD_Char(‘:’);
min=aTxBuffer[2];
min = RTC_ConvertFromDec(min);
OLED_num_to_str(min,2);
LCD_Char(‘:’);
sec=aTxBuffer[1];
sec = RTC_ConvertFromDec(sec);
OLED_num_to_str(sec,2);

HAL_Delay(100);

}
/* USER CODE END 3 */