взаимодействие ssd1306 с stm32f103 в регистрах, i2 c 'режим данных' не работает - PullRequest
0 голосов
/ 26 мая 2020

Я хочу сделать свое первое приложение, использующее i2 c на stm32, для работы с ssd1306. Все коммуникации в «командном режиме» работают, и дисплей реагирует на 1-байтовые команды. Я думаю, что проблема в «режиме данных», когда количество байтов в одном пакете увеличивается.

Basi c функция для отправки данных через i2 c

void i2c1_send(uint8_t address, uint8_t *command, uint16_t length)
{
    while(I2C1->SR2 & I2C_SR2_BUSY);
    I2C1->CR1 |= I2C_CR1_START;
    while(!(I2C1->SR1 & I2C_SR1_SB));
    I2C1->DR=address;                   //7 bit address in this byte is already shifted left by one
    while(!(I2C1->SR1 & I2C_SR1_ADDR)|!(I2C1->SR2));    //waiting for address match

    for (uint16_t i=0;i<length;i++)
    {
        I2C1->DR=command[i];                    //filling buffer with command or data
        while(!(I2C1->SR1 & I2C_SR1_BTF));      //from RM: Note: The BTF bit is not set after a NACK reception
                                                //i think i need here to wait for ack response
    }
    I2C1->CR1 |= I2C_CR1_STOP;
}

Функция для отправки команд это работает нормально, он отправляет в итоге 3 байта данных без запуска / остановки - [startBit, Address, ControlByte, CommandByte, stopBit]

и код:

void ssd1306_sendCommand(uint8_t toSend_u8){
    uint8_t frame_u8[2] = {0, toSend_u8};
    i2c1_send((OLED_ADDRESS<<1)|0, frame_u8,2); //sending frame
}

Управляющий байт в командном режиме равен 0x0, согласно таблице данных ssd1306, он будет показан на изображении позже.

Наконец функция для отправки данных , которая не работает

void ssd1306_sendData(uint8_t* toSend_u8p,uint8_t data_lenght)
{
    uint8_t frame_u8[256];  //making frame buffor to send
    frame_u8[0] = 0x40;     //control byte with D/C = 1 ---> 0b01000000 = 0x40

    for(uint16_t i=0; i <= data_lenght; i++){
        frame_u8[1+i] = toSend_u8p[i];
    }

    i2c1_send((OLED_ADDRESS<<1)|0, frame_u8, data_lenght+1);  //data_lenght+1 because we have additional control byte
}

i2 c формат данных drom ssd1306 datasheet

full ssd1306 datasheet

My i2 c init fx

void i2c1_init()
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //enabling gpios
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; //clock for i2c1
    __DSB();__DSB();__DSB();

    //i2c pins : PB6 - SCL ; PB7 - SDA

    GPIOB->CRL &= ~(GPIO_CRL_CNF6|GPIO_CRL_CNF7);
    GPIOB->CRL |= GPIO_CRL_CNF6_1|GPIO_CRL_CNF7_1|
                    GPIO_CRL_MODE7|GPIO_CRL_MODE6;      //AF function push pull for gpios

    I2C1->CR2 |= 50;
    I2C1->CCR |= I2C_CCR_FS;
    I2C1->CCR |= 30;
    I2C1->TRISE |= 51;
    I2C1->CR1 |= I2C_CR1_ACK;
    I2C1->CR1 |= I2C_CR1_PE;

}

Я не совсем понимаю, в чем проблема и почему этот «режим данных» не работает

...