OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3320|回复: 7

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

[复制链接]

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2018-9-18 22:32:35 | 显示全部楼层 |阅读模式
1金钱
如题,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);

最佳答案

查看完整内容[请看2#楼]

这是因为发完(其实没完)命令后, CD由0转1, 因为判断的是TXE标志位, 它代表你已经把最后一个Command送到SPI_DR, 但SPI还没把它发送完成, 但这时你就把CD由0转1, 所以LCD会出错 要不就加Delay, 要不就多加一条判断SPI_Busy标志位, 才把CD由0转1发数据 同理发完数据如果紧接着再发Command情况也是一样的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-18 22:32:36 | 显示全部楼层
这是因为发完(其实没完)命令后, CD由0转1, 因为判断的是TXE标志位, 它代表你已经把最后一个Command送到SPI_DR, 但SPI还没把它发送完成, 但这时你就把CD由0转1, 所以LCD会出错
要不就加Delay, 要不就多加一条判断SPI_Busy标志位, 才把CD由0转1发数据

同理发完数据如果紧接着再发Command情况也是一样的
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-9-18 22:33:15 | 显示全部楼层
应该说去掉延时,就不会显示了,去掉延时就不会正确的读写数据到OLED了。
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-9-19 10:06:01 | 显示全部楼层
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。
回复

使用道具 举报

210

主题

773

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2018-3-26
在线时间
288 小时
发表于 2018-9-19 10:11:08 | 显示全部楼层
帮  顶
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2018-9-19 10:48:38 | 显示全部楼层
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2019-5-20
在线时间
39 小时
发表于 2019-6-1 21:45:51 | 显示全部楼层
感谢,OLED从软件SPI转到硬件SPI不能显示,加了延时可以显示了
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2019-5-20
在线时间
39 小时
发表于 2019-6-1 22:02:11 | 显示全部楼层
void SPI2_WriteByte(u8 TxData)
{               
        u8 retry=0;                                        
        while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET)//检查指定的SPI标志位设置与否:发送缓存空标志位
        {
                retry++;
                if(retry>200)return ;
        }
        SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据          
        while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);
}

使用这个函数并且把SPI速度开到最快的2分频,IO口速度设置为100M,可以正常显示,刷新很快
(关键词 STM32F407   硬件SPI OLED)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-17 05:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表