/* P9_3.c - I2C burst write to a DS3231 * * This program initializes the I2C and write the * initialization data to a DS3231. * No errors or acknowledgement are checked. * * The connections * I2C1_SCL - PB8 * I2C1_SDA - PB9 * * This program was tested with Keil uVision v5.23 with DFP v2.0.0 */ #include "stm32f0xx.h" #define SLAVE_ADDR 0x68 /* 1101 000. DS3231 */ void delayMs(int n); void I2C1_init(void); int I2C1_burstWrite(char saddr, char maddr, int n, char* data); int Main(void) { /* 00 01 02 03 04 05 06 */ char timeDateToSet[15] = {0x55, 0x58, 0x10, 0x03, 0x26, 0x09, 0x17, 0}; /* 2017 September 26, Tuesday, 10:58:55 */ I2C1_init(); I2C1_burstWrite(SLAVE_ADDR, 0, 7, timeDateToSet); while (1) { } } void I2C1_init(void) { RCC->AHBENR |= 0x00040000; /* Enable GPIOB clock */ RCC->APB1ENR |= 0x00200000; /* Enable I2C1 clock */ /* configure PB8, PB9 pins for I2C1 */ GPIOB->MODER &= ~0x000F0000; /* PB8, PB9 use alternate function */ GPIOB->MODER |= 0x000A0000; GPIOB->AFR[1] &= ~0x000000FF; /* PB8, PB9 I2C1 SCL, SDA */ GPIOB->AFR[1] |= 0x00000011; GPIOB->OTYPER |= 0x00000300; /* output open-drain */ GPIOB->PUPDR &= ~0x000F0000; /* with pull-ups */ GPIOB->PUPDR |= 0x00050000; I2C1->CR1 = 0; /* software reset I2C1 */ I2C1->TIMINGR = 0x10420F13; /* 100 KHz, peripheral clock is 8 MHz */ I2C1->CR1 = 0x00000001; /* enable I2C1 module */ } /* this function writes multiple bytes of data to the memory location maddr of * a device with I2C slave device address saddr. * For simplicity, no error checking or error report is done. */ int I2C1_burstWrite(char saddr, char maddr, int n, char* data) { int i; while (I2C1->ISR & 0x8000); /* wait until bus not busy */ I2C1->CR2 = 0x02002000 | /* generate start, set byte count, */ ((n + 1)<< 16) | (saddr << 1); /* set auto end, and send slave address */ while (!(I2C1->ISR & 0x02)); /* wait until TXIS is set */ I2C1->TXDR = maddr; /* send memory address */ for (i = 0; i < n; i++) /* send n bytes of data */ { while (!(I2C1->ISR & 0x02)); /* wait until TXIS is set */ I2C1->TXDR = *data++; /* send a byte of data */ } while (!(I2C1->ISR & 0x20)); /* wait until stop flag is set */ I2C1->ICR = 0x20; /* clear stop flag */ I2C1->CR2 = 0x02000000; /* clear configuration register 2 */ return 0; }