OpenEdv-开源电子网

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

STM32F103RC单片机硬件SPI+DMA刷ST7789驱动的1.3寸LCD屏中景圆的屏幕刷不了

[复制链接]

29

主题

167

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1011
金钱
1011
注册时间
2021-7-26
在线时间
184 小时
发表于 2022-10-9 15:12:57 来自手机 | 显示全部楼层 |阅读模式
STM32F103RC单片机硬件SPI+DMA刷ST7789驱动的1.3寸LCD屏中景圆的屏幕刷不了,想学一下刷屏,但是屏幕始终没有反应,有时候有反应了也只是花屏。代码是从网上找的一个32驱动2.4寸的lcd的代码,移的时候感觉也注意寄存器地址的配置了。
scl接pb3,sda接pb5,dc接pb11,res接pa2,blk接3v3,其中res我不知道有什么用,但是加了res脚才会有显示,软件spi驱动时候也必须使用res,而res的代码也就是初始化时候拉高拉低几毫秒,滞空还不行就直接不显示。
lcd的函数除了初始化都改成spi+dma外,函数只改了一个lcd_clear用来刷屏。有好心人给一个硬件SPI或硬件SPI+DMA刷ST7789驱动的1.3寸LCD屏的代码么,想学习一下,如果没有分享的话有人愿意帮我看一下代码么
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2020-12-26
在线时间
25 小时
发表于 2023-2-17 16:37:17 | 显示全部楼层
给你一个代码:

void SPI1_Init(void)                              //  1 时钟,GPIO引脚,2 硬件SPI1
{
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef  SPI_InitStructure;                  //SPI结构体

/* 使能 SPI1 时钟 */                        
/* Enable SPI1 and GPIOA GPIOB clocks */

/* ---------LCD7789 控制I/O初始化----------------*/
/* PB3CD_RST*/                                        
/* PB4CD_DC*/                   
/* PA4-SPI1-NSS: CS */                
/* PA5-SPI1-SCK: SCL */                
/* PA6-SPI1-MISO:SDO */                
/* PA7-SPI1-MOSI:SDA */
/* PA11CD_BACKLIGHT:BL*/               
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//PORTA时钟使能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//PORTB时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //APB2=216M
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;           //SPI FLASH片选
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
   
        GPIO_SetBits(GPIOA,GPIO_Pin_4);//SPI FLASH不选中
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               // AF复用输出
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);  //PA5/6/7上拉

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;                           //BL
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           //推挽输出
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA, GPIO_Pin_11);                                       //这个是背光电源
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; //RST DC
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           //推挽输出
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
    SPI_I2S_DeInit(SPI1);
   
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;          //设置 SPI 双线收发
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                    //设置 SPI 工作模式:设置为主 SPI                        
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                // 8 位帧结构        
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            //选择了串行时钟的稳态:时钟低        
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                    //数据捕获于第一个时钟沿       
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                            //NSS 信号由硬件管理  这个可以获得高速
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //预分频 216/4=54M
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;          //数据传输从 MSB 位开始                        
        SPI_InitStructure.SPI_CRCPolynomial = 7;                    //CRC 值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);                         //②根据指定的参数初始化外设 SPIx 寄存器
    SPI_Cmd(SPI1, ENABLE); //使能SPI外设

}
void SPI1_DMA_Config(void) //
{
        DMA_InitTypeDef  DMA_InitStructure;                         //DMA结构体     
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);                //DMA时钟开启
    /*********************  DMA_Tx  *********************/  
        DMA_DeInit(DMA1_Channel3);                                  //将dma1的3通道复位
        DMA1_MEM_LEN=6;                                             //传递来的长度保存
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;  //dma 要搬运到的外设地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;       //dma要搬运的内存的地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;          //搬运方向, 从内存到外设
        DMA_InitStructure.DMA_BufferSize = 6;                       //要搬运的内存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //传输过程中外设的基地址不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;             //传输过程中内存地址递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; //外设数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;     //内存数据宽度为8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;               //正常传输模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;     //优先级设置
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //没有内存到内存的传输
        DMA_Init(DMA1_Channel3, &DMA_InitStructure);                      //按定义初始化DMA
   
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);                            //使能DMA Tx通道3
    DMA_Cmd(DMA1_Channel3, DISABLE);
    /*********************  DMA_Rx  *********************/
        DMA_DeInit(DMA1_Channel2);                                  //将dma1的2通道复位
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;  //dma 要搬运到的外设地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RecvBuff;       //dma要搬运的内存的地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;          //搬运方向, 从外设到内存
        DMA_InitStructure.DMA_BufferSize = 6;                       //要搬运的内存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //传输过程中外设的基地址不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;             //传输过程中内存地址递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; //外设数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;     //内存数据宽度为8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;               //正常传输模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;     //优先级设置
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //没有内存到内存的传输
        DMA_Init(DMA1_Channel2, &DMA_InitStructure);                //按定义初始化DMA
   
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE);  
        DMA_Cmd(DMA1_Channel2, DISABLE);
}
void SPI1_transmission(u8 *rx_buf,u8 *tx_buf,u16 NumByte)
{
       
        DMA_SetCurrDataCounter(DMA1_Channel2,NumByte);                //设定通道内存宽度
        DMA_SetCurrDataCounter(DMA1_Channel3,NumByte);
       
        DMA1_Channel2->CCR |= (1<<7);                        //打开地址自增
        DMA1_Channel3->CCR |= (1<<7);
       
        DMA1_Channel2->CMAR =(u32)rx_buf;
        DMA1_Channel3->CMAR =(u32)tx_buf;
       
        SPI1->DR;                //清空SPI DR寄存器
       
        while((SPI1->SR&1<<1)==0);        //等待清除
       
        DMA_Cmd(DMA1_Channel2,ENABLE);        //开启DMA
        DMA_Cmd(DMA1_Channel3,ENABLE);
       
        while( DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET);        //等待传输完成
        while( DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);
       
        DMA_Cmd(DMA1_Channel3,DISABLE);                //关闭DMA
        DMA_Cmd(DMA1_Channel2,DISABLE);
       
        DMA_ClearFlag(DMA1_FLAG_TC3);                //清空传输完成flag
        DMA_ClearFlag(DMA1_FLAG_TC2);
}

void SPI1_SetSpeed(u8 SpeedSet)
{
        SPI_Cmd(SPI1,DISABLE);
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SpeedSet));//判断有效性
        SPI1->CR1&=0XFFC7;//位3-5清零,用来设置波特率
        SPI1->CR1|=SpeedSet;        //设置SPI1速度
        SPI_Cmd(SPI1,ENABLE);
}

u32 Read_ID(u8 cmd)
{
    u8 tmp;
    u32 temp=0;
    SPI1_SetSpeed(SPI_BaudRatePrescaler_32);    //216/32=6.75M ***读时钟周期最小150ns***
    SPI_DC_0;                   //这个是命令
    SPI_CS_0;                   //选择LCD
    SPI1_ReadWriteByte(cmd);    //发送命令字节
    SPI_DC_1;                   //这个是数据

    SendBuff[0]=0xff;
    SendBuff[1]=0xff;
    SendBuff[2]=0xff;
    SendBuff[3]=0xff;
    SPI1_transmission(RecvBuff,SendBuff,4);
    tmp=RecvBuff[1];
    temp|=tmp;
    tmp=RecvBuff[2];
    temp=temp<<8;
    temp|=tmp;
    tmp=RecvBuff[3];
    temp=temp<<8;
    temp|=tmp;
    SPI_CS_1;                   //取消片选
    return temp;
}

回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 15:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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