SPI驱动OLED问题,SPI读写需要加延时。

2019-07-21 00:32发布

如题,SPI读写函数如下,
void SpiSendCmd(u8 cmd)
{
        OLED_CS(LOW);
        OLED_DC(LOW);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1,cmd);
//        delay_us(50);
        OLED_CS(HIGH);
}

void SpiSendData(u8 data)
{
        OLED_CS(LOW);
        OLED_DC(HIGH);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1,data);
//        delay_us(50);
        OLED_CS(HIGH);
        OLED_DC(LOW);
}

加上延时后,就可以显示,但是刷屏速度会很慢,如果注释带延时,就不会正常显示。不知道哪里出了问题。SPI初始化如下。
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
        SPI_InitStructure.SPI_CRCPolynomial = 7;//
       
        SPI_Init(SPI1,&SPI_InitStructure);
        SPI_Cmd(SPI1,ENABLE);

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
edmund1234
1楼-- · 2019-07-21 00:37
这是因为发完(其实没完)命令后, CD由0转1, 因为判断的是TXE标志位, 它代表你已经把最后一个Command送到SPI_DR, 但SPI还没把它发送完成, 但这时你就把CD由0转1, 所以LCD会出错
要不就加Delay, 要不就多加一条判断SPI_Busy标志位, 才把CD由0转1发数据

同理发完数据如果紧接着再发Command情况也是一样的
wangmingwei093
2楼-- · 2019-07-21 03:45
 精彩回答 2  元偷偷看……
wangmingwei093
3楼-- · 2019-07-21 08:06
edmund1234 发表于 2018-9-19 01:11
这是因为发完(其实没完)命令后, CD由0转1, 因为判断的是TXE标志位, 它代表你已经把最后一个Command送到 ...

我加了一句判断,没啥用啊,我又把发送数据后面的DC和CS去掉,结果就可以了,当然,先去判断了下有没有发送完成,如下
static void SpiSendData(u8 data)
{
        OLED_CS(LOW);
        OLED_DC(HIGH);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1,data);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
//        delay_ms(1);
//        OLED_CS(HIGH);
//        OLED_DC(LOW);
}
正如你所说,DC和CS变化速度太快导致数据没发送完就变化了。所以我直接把下面的两句去掉了。
然而问题是,OLED刷屏速度还是太慢,虽然看不出来一行行的更新,但是我刷新某个数时,我想先去清一下局部的区域,就这样刷屏还是很明显有闪屏的现象。不知道有什么好的解决方法。我用了一种比较笨的方法,但是显示效果不是我想要的,例如显示两位数字,我就显示01,02,03,这样后面的覆盖了前面的,可是我想不显示前面的0。
支持者2400
4楼-- · 2019-07-21 14:04
帮  顶
wangmingwei093
5楼-- · 2019-07-21 17:27
 精彩回答 2  元偷偷看……
飞觞醉月1998
6楼-- · 2019-07-21 22:32
感谢,OLED从软件SPI转到硬件SPI不能显示,加了延时可以显示了

一周热门 更多>