1. настраиваем i2c, кормим дисплей строкой инициализации,
настраиваем dma, разрешаем прерывание transfer_complete 2. вызываем с периодом обновления дисплея:
static void update()
{
dma_set_number_of_data(DMA2, DMA_CHANNEL1, DISP_BUFSZ + 1);
dma_enable_channel(DMA2, DMA_CHANNEL1);
i2c_enable_dma(I2C1);
i2c_send_start(I2C1);
while (!((I2C_SR1(I2C1) & I2C_SR1_SB) &&
(I2C_SR2(I2C1) & I2C_SR2_MSL) &&
(I2C_SR2(I2C1) & I2C_SR2_BUSY)));
i2c_send_7bit_address(I2C1, DISP_ADDR, I2C_WRITE);
while (!(I2C_SR1(I2C1) & I2C_SR1_ADDR));
(void)I2C_SR2(I2C1);
}
в прерывании по концу передачи:
void dma2_channel1_isr()
{
i2c_disable_dma(I2C1);
dma_clear_interrupt_flags(DMA2, DMA_CHANNEL1, DMA_TCIF);
dma_disable_channel(DMA2, DMA_CHANNEL1);
while (!(I2C_SR1(I2C1) & (I2C_SR1_BTF)));
i2c_send_stop(I2C1);
}
это всё с использованием libopencm3, но вроде понять можно.