Я хочу сделать свое первое приложение, использующее 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;
}
Я не совсем понимаю, в чем проблема и почему этот «режим данных» не работает