OpenEdv-开源电子网

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

使用硬件SPI驱动LCD,手里有块使用三线SPI接口的屏幕,没有数据命令控制位,用ILI9341驱动的,

[复制链接]

5

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-7-9
在线时间
6 小时
发表于 2015-12-28 17:09:34 | 显示全部楼层 |阅读模式
使用软件模拟SPI可以成功点亮屏幕,但是显示比较慢,所以打算用硬件SPI,但是硬件SPI就不能够点亮,开始发现是写数据和命令时,使用硬件SPI没有判断发送的是命令还是数据,就在每次写数据前把SPI口设置为推挽输出模式,再使用SCK,SI,模拟控制信号,在配置SPI口为复用推挽输出,使用硬件SPI传输数据和命令,在示波器上看了下,SCK,SI的时序和所发送的数据一致,但就是不能够在屏幕上显示出来。
以下是SPI读写函数,
void SPI_WriteByte(uint8_t byte)
{
#ifdef USE_HW_SPI
        /* Send byte through the SPI2 peripheral */
    SPI_I2S_SendData(SPI2, byte);
        /* Loop while DR register in not emplty */
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
#else
        uint8_t i, value = byte;

        for(i=0; i<8; i++)
        {
                SPI_CLK_L;
                if(value & 0x80)        SPI_SI_H;
                else                                SPI_SI_L;
                SPI_CLK_H;
                value = value<<1;//_crol_(value, 1);
        }
#endif

void LCD_WR_REG(u8 regval)
{
#ifdef USE_HW_SPI

        GPIOB->CRH&=0X0F0FFFFF;
        GPIOB->CRH|=0X30300000;
        SPI_CS_L;

        SPI_CLK_L;
        SPI_SI_L;
          __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        SPI_CLK_H;
        GPIOB->CRH&=0X000FFFFF;
        GPIOB->CRH|=0XBBB00000;        //PB13/14/15&#184;′ó&#195;             
        //GPIOB->ODR|=0X7<<13;           //PB13/14/15é&#207;à-
        SPI_WriteByte(regval);
        SPI_CS_H;
#else

        GPIOB->CRH&=0X0F0FFFFF;
        GPIOB->CRH|=0X30300000;
        SPI_CS_L;
        SPI_CLK_L;
        SPI_SI_L;
        SPI_CLK_H;
        SPI_WriteByte(regval);

        SPI_CS_H;
#endif
}

void LCD_WR_DATA(u8 data)
{
#ifdef USE_HW_SPI

        GPIOB->CRH&=0X0F0FFFFF;
        GPIOB->CRH|=0X30300000;
        SPI_CS_L;

        SPI_CLK_L;
  __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        __asm("NOP");
        SPI_SI_H;
        SPI_CLK_H;
        GPIOB->CRH&=0X000FFFFF;
        GPIOB->CRH|=0XBBB00000;        //PB13/14/15&#184;′ó&#195;             
        //GPIOB->ODR|=0X7<<13;           //PB13/14/15é&#207;à-
        SPI_WriteByte(data);
        SPI_CS_H;       
#else
        GPIOB->CRH&=0X0F0FFFFF;
        GPIOB->CRH|=0X30300000;
        SPI_CS_L;
        SPI_CLK_L;
        SPI_SI_H;
        SPI_CLK_H;
        SPI_WriteByte(data);

        SPI_CS_H;
#endif
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2015-12-28 17:18:38 | 显示全部楼层
屏幕对SPI的速度有要求吧?
回复 支持 反对

使用道具 举报

5

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-7-9
在线时间
6 小时
 楼主| 发表于 2015-12-28 17:23:13 | 显示全部楼层

背光和片选初始化,SPI初始化,如下:
void LCD_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;        //GPIO
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_12;//背光和片选
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
       
        SPI2_Init();                           //初始化SPI
        SPI2_SetSpeed(SPI_BaudRatePrescaler_8);//设置为4.5M时钟
        ......//写IC
}
void SPI2_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
          SPI_InitTypeDef  SPI_InitStructure;

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
        RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

        GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI2, ENABLE); //使能SPI外设
       
//        SPI2_ReadWriteByte(0xff);//启动传输

}   
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   
//SPI_BaudRatePrescaler_8   8分频   
//SPI_BaudRatePrescaler_16  16分频  
//SPI_BaudRatePrescaler_256 256分频
  
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
          assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
        SPI2->CR1&=0XFFC7;
        SPI2->CR1|=SPI_BaudRatePrescaler;        //设置SPI2速度
        SPI_Cmd(SPI2,ENABLE);

}

回复 支持 反对

使用道具 举报

5

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-7-9
在线时间
6 小时
 楼主| 发表于 2015-12-28 17:24:30 | 显示全部楼层
ricefat 发表于 2015-12-28 17:18
屏幕对SPI的速度有要求吧?

SPI的速度设置的4.5MHz,在屏幕的承受范围内
回复 支持 反对

使用道具 举报

5

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-7-9
在线时间
6 小时
 楼主| 发表于 2015-12-28 17:26:28 | 显示全部楼层
fenglei_520 发表于 2015-12-28 17:24
SPI的速度设置的4.5MHz,在屏幕的承受范围内

开始设置的18MHZ,以为是这个的影响,就调小了
回复 支持 反对

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2015-12-28 18:48:30 | 显示全部楼层
fenglei_520 发表于 2015-12-28 17:26
开始设置的18MHZ,以为是这个的影响,就调小了

有些需要延时的地方时间放长点
回复 支持 反对

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2015-12-28 22:16:22 | 显示全部楼层
几个建议:
1、试着调低SPI速率,就是这个
       SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
2、对照数据手册,修改空闲时电平和采样跳变沿,我之前写一个传感器碰上的问题就是这个
       SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
至于说MSB还是LSB、引脚、时钟什么的设定,也可以检查一下
回复 支持 反对

使用道具 举报

0

主题

12

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2015-7-30
在线时间
1 小时
发表于 2016-1-28 20:56:49 | 显示全部楼层
楼主你好,数据命令控制位只能改复用去这么做吗?我也想用硬件SPI,但是也卡在了数据命令控制位这边了。。
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-6-21
在线时间
6 小时
发表于 2016-7-31 11:27:18 | 显示全部楼层
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
请问三线SPI也可以设置成全双工吗?
回复 支持 反对

使用道具 举报

36

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2015-12-13
在线时间
243 小时
发表于 2016-7-31 12:27:03 | 显示全部楼层
9341的频率也不低, SPI开到最大也完全可以。。点不亮那是因为你的代码有问题!
回复 支持 反对

使用道具 举报

5

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
271
金钱
271
注册时间
2014-8-7
在线时间
59 小时
发表于 2016-10-8 16:06:18 | 显示全部楼层
HER107 发表于 2016-7-31 12:27
9341的频率也不低, SPI开到最大也完全可以。。点不亮那是因为你的代码有问题!

请教一下你用SPI刷9341大概多长时间刷一屏?我现在是140ms左右,这算是正常速度吗
回复 支持 反对

使用道具 举报

36

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2015-12-13
在线时间
243 小时
发表于 2016-10-8 17:23:15 | 显示全部楼层
ndthome 发表于 2016-10-8 16:06
请教一下你用SPI刷9341大概多长时间刷一屏?我现在是140ms左右,这算是正常速度吗

我就没算过时间,反正是一闪,画面就出来了,还是挺快的!而且我的图片是存在25Q64里面的,一边读,一边写入LCD
回复 支持 反对

使用道具 举报

5

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
271
金钱
271
注册时间
2014-8-7
在线时间
59 小时
发表于 2016-10-8 17:32:34 | 显示全部楼层
有用到DMA吗?能否提供个例子参考一下?
回复 支持 反对

使用道具 举报

36

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2015-12-13
在线时间
243 小时
发表于 2016-10-8 17:33:37 | 显示全部楼层
2016-10-07 14.42.06.jpg

STM32F103C8T6驱动,屏幕上的三个数字是时钟!  

触摸,液晶,26Q64都是共用同一个SPI1~~
附上IO口和SPI的初始化代码,我向来都是直接操作寄存器,很少很少使用库函数!
[mw_shl_code=c,true]void Gpio_set(void)
{
        u16 temp=0;
        RCC->APB2ENR        |=        0x0000501D;        //′ò&#191;aSPI1,PA,PB,PC,AFIO,uart1ê±&#214;ó
        GPIOA->CRL        =        0;
        GPIOA->CRL        =        0xBBB33338;                //PA5.6.7_spi , PA4.3.2.1í&#198;íì. PA0.é&#207;à-ê&#228;è&#235;
        GPIOA->CRH        &=0xFFFF0000;
        GPIOA->CRH        |=0x000038b3;
        GPIOA->BSRR        =        0x0FFF;                                        //PAμí8&#206;&#187;&#214;&#195;1
       
        GPIOC->CRH        &=        0XFF0FFFFF;
        GPIOC->CRH        |=        0x00300000; //PC13
       
        temp        |=        0x01<<9;
        temp        |=        0x01<<2;
        temp        |=        0x01<<8;               
//        ò&#212;×&#238;&#184;&#223;&#203;ù&#182;è&#212;&#203;DD
        SPI1->CR1 =        temp;
        SPI1->CR1        |= 1<<6;
        SPI1->DR        =        0xFF;
       
        AFIO->MAPR        =        1<<25;                //&#189;&#171B3.4éè&#214;&#195;&#206;aí¨ó&#195;IO&#191;ú
       
        RCC->APB2ENR        &= 0xfffe;        //1&#216;±&#213;AFIOμ&#196;ê±&#214;ó
}[/mw_shl_code]
回复 支持 反对

使用道具 举报

5

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
271
金钱
271
注册时间
2014-8-7
在线时间
59 小时
发表于 2016-10-8 17:39:07 | 显示全部楼层
HER107 发表于 2016-10-8 17:33
STM32F103C8T6驱动,屏幕上的三个数字是时钟!  

触摸,液晶,26Q64都是共用同一个SPI1~~

谢谢,不过不太习惯寄存器操作。……
回复 支持 反对

使用道具 举报

4

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-9-4
在线时间
13 小时
发表于 2016-11-16 09:05:59 | 显示全部楼层
请问,在复用SPI模式下,不能再向IO口发送0/1命令了,然后您就每次发送前改为通用的IO口然后再操作,还有其他的方法吗? 感觉这样子很麻烦~
回复 支持 反对

使用道具 举报

1

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2016-11-22
在线时间
19 小时
发表于 2016-12-14 16:39:37 | 显示全部楼层
你好!你的.h文件有吗?后来可以运行了吗?
回复 支持 反对

使用道具 举报

4

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-9-4
在线时间
13 小时
发表于 2017-2-12 21:03:51 | 显示全部楼层
楼主,请问后来程序运行了吗》  硬件SPI
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-8-21
在线时间
18 小时
发表于 2019-10-16 20:49:56 | 显示全部楼层
最后解决了吗?什么原因?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-29 01:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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