搜索
bottom↓
回复: 29

全彩LED点阵屏,H750驱动,超了点频,远看还是有点闪【使用大字体,封锁ID一星期】

[复制链接]

出0入0汤圆

发表于 2022-4-28 18:24:25 | 显示全部楼层 |阅读模式
用H750VBT6驱动四块64*32,已经榨干了,还是闪


u16 OeTime[8]={128,64,32,16,8,4,2,1};

....
Stm32_Clock_Init(240,5,2,4);        //设置时钟,4xxMhz
delay_init(480);                                //延时初始化
.....


void DisplayScreen(void)
{

                                for(int DisplayRowNumber=0;DisplayRowNumber<16;DisplayRowNumber++)        //16扫
                                {       

                                                for(int xxx=0;xxx<8;xxx++)//每行扫8次,根据RGB值确定OE时间
                                                {
       

                                                                OE_SETH;                //高电平息屏
                                                                DispLine(DisplayRowNumber);
                                                       
                                                         

                                                                for(int kkk=0;kkk<256;kkk++)                                //每行256点,每点三个字节,代表RGB,灰度8级每色256色
                                                                {

                                                                                GPIOD->BSRRH=0X00FF;


                                                                                if( (DisplayArea[DisplayRowNumber*3*256+3*kkk+0]<< xxx)&0x80) //上屏
                                                                                                GPIOD->BSRRL|=1<<0;
                                                                                if( (DisplayArea[DisplayRowNumber*3*256+3*kkk+1]<<xxx)&0x80) //
                                                                                                GPIOD->BSRRL|=1<<1;                                                                                       
                                                                                if(( DisplayArea[DisplayRowNumber*3*256+3*kkk+2]<<xxx)&0x80) //
                                                                                                GPIOD->BSRRL|=1<<2;                                                                                       
                                                                                if( (DisplayArea[DisplayRowNumber*3*256+16*256*3+3*kkk+0]<<xxx)&0x80) //下屏  
                                                                                                        GPIOD->BSRRL|=1<<3;
                                                                                if( (DisplayArea[DisplayRowNumber*3*256+16*256*3+3*kkk+1]<<xxx)&0x80) //
                                                                                                        GPIOD->BSRRL|=1<<4;
                                                                                if( (DisplayArea[DisplayRowNumber*3*256+16*256*3+3*kkk+2]<<xxx)&0x80) //
                                                                                                        GPIOD->BSRRL|=1<<5;
               
                                                                                CLK_SETL;               
                                                                                CLK_SETH;                `                       
       
                                                                }               
                       

                                                                LAT_SETL;                //低电平锁存
                                                                LAT_SETH;                //高电平并出
                                                                OE_SETL;                        //低电平亮屏                               
                                       
                                                                delay_us(OeTime[xxx]);

                                                               
                                                }
                                       
                               
                                }                                               
       
       
}

后来把解码放在外面
变成

void DisplayScreen(void)
{

                                for(int DisplayRowNumber=0;DisplayRowNumber<16;DisplayRowNumber++)        //16扫
                                {       

                                                for(int xxx=0;xxx<8;xxx++)//每行扫8次,根据RGB值确定OE时间
                                                {
       

                                                                OE_SETH;                //高电平息屏
                                                                DispLine(DisplayRowNumber);
                                                       
                                                         

                                                                for(int kkk=0;kkk<256;kkk++)                                //每行256点
                                                                {

                                                                                GPIOD->BSRRH=0X00FF;
                                                                                GPIOD->BSRRL|=DisplayArea[DisplayRowNumber*8*256+kkk];               
                                                                                CLK_SETL;               
                                                                                CLK_SETH;                        `                       
       
                                                                }               
                       

                                                                LAT_SETL;               
                                                                LAT_SETH;               
                                                                OE_SETL;                                       
                                       
                                                                delay_us(OeTime[xxx]);
                                                               
                                                }
                               
                                }                                               

}

不闪了
但是距离3米一看还是有点微闪,这已经是没法再优化了

有人说能驱动1024*64,8级灰度,我是怎么也试不出来,加多一块板根本就显示不了
有高手看看还能优化不

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2022-4-28 18:32:02 | 显示全部楼层
#define AIN  (1<<8)// PD8
#define AIN_SET(x) GPIOD->ODR=(GPIOD->ODR&~AIN)|(x ? AIN:0)
。。。
//行扫描                LineNumber(ABCDE)
void DispLine(u8 LineNumber)
{
                AIN_SET(LineNumber&0x01);               
                BIN_SET(LineNumber&0x02);
                CIN_SET(LineNumber&0x04);
                DIN_SET(LineNumber&0x08);
//                EIN_SET(LineNumber&0x10);
}

这个怎么优化为BSRRL(H)?可能会提高点效率

出140入158汤圆

发表于 2022-4-28 20:46:25 | 显示全部楼层
额。。。。您这样不闪才怪呢,哈哈
先开个缓冲区,缓冲区放的是要移出的点,然后DMA到硬件SPI出数据,DMA中断后(注意DMA TC中断并不代表移位完成,有FIFO存在)完成后Latch,OE时间根据灰度来决定, 在DMA时间还有OE时间内,计算好下一OE时间的点数据填充到缓冲区2,循环此过程。 合理协调好,CPU其实还有大把空闲时间做其它事情呢。

出0入0汤圆

 楼主| 发表于 2022-4-28 23:55:14 | 显示全部楼层
amigenius 发表于 2022-4-28 20:46
额。。。。您这样不闪才怪呢,哈哈
先开个缓冲区,缓冲区放的是要移出的点,然后DMA到硬件SPI出数据,DMA中 ...
(引用自3楼)

太复杂了 目前我只知道,就是一直刷某个地方的数据,数据有变动,也是刷这个地方

出0入224汤圆

发表于 2022-4-29 00:48:10 | 显示全部楼层
这离榨干还远着呢

出0入34汤圆

发表于 2022-4-29 00:56:40 | 显示全部楼层
我怎感觉楼主自己会闪呐?估计选用字体的 Size 貌似有点问题哈!~

出0入59汤圆

发表于 2022-4-29 04:08:25 | 显示全部楼层
amigenius 发表于 2022-4-28 20:46
额。。。。您这样不闪才怪呢,哈哈
先开个缓冲区,缓冲区放的是要移出的点,然后DMA到硬件SPI出数据,DMA中 ...
(引用自3楼)

他是1个时钟6个数据信号,用SPI驱动不了的

出0入984汤圆

发表于 2022-4-29 06:32:14 | 显示全部楼层
本帖最后由 Himem 于 2022-4-29 06:43 编辑
polarbear 发表于 2022-4-29 04:08
他是1个时钟6个数据信号,用SPI驱动不了的
(引用自7楼)





dual bank qspi可以的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2022-4-29 09:32:58 | 显示全部楼层
本帖最后由 WUJIANLING 于 2022-4-29 09:35 编辑
xyz543 发表于 2022-4-29 00:56
我怎感觉楼主自己会闪呐?估计选用字体的 Size 貌似有点问题哈!~
(引用自6楼)

不好意思,我放大字体是第一次,想试试效果,效果不错

出0入59汤圆

发表于 2022-4-29 09:42:58 | 显示全部楼层
Himem 发表于 2022-4-29 06:32
dual bank qspi可以的
(引用自8楼)

多谢指导, 没想到现在的STM32 的SPI 支持 8位传送了

出10入46汤圆

发表于 2022-4-30 09:27:48 | 显示全部楼层
距离榨干,还太遥远呢

出0入0汤圆

 楼主| 发表于 2022-5-3 11:06:53 | 显示全部楼层
我在想,我这种直接操作GPIO模式,跟QSPI应该差别不大吧,差别大应该是在没有用DMA,但是,这种经常操作显示区域的,在DMA处理中,显得比较麻烦,如果用双DMA,是切换DMA1的QSPI到DMA2的QSPI,还是DMA2->DMA1的QSPI

出140入158汤圆

发表于 2022-5-3 15:41:10 | 显示全部楼层
WUJIANLING 发表于 2022-5-3 11:06
我在想,我这种直接操作GPIO模式,跟QSPI应该差别不大吧,差别大应该是在没有用DMA,但是,这种经常操作显 ...
(引用自12楼)

直接操作IO跟QPI差别是天和地,而且H7的IO频率很低,还不及F4。另, DMA有双缓冲

出0入0汤圆

 楼主| 发表于 2022-5-4 09:45:26 | 显示全部楼层
本帖最后由 WUJIANLING 于 2022-5-4 09:46 编辑

这个地方不会填,我愿意是要发指令,指定无指令、无地址、无交叉、无空周期,只传输数据,麻烦看一下
QSPI_Send_CMD(0,NULL,0XF0,4);//????????




void QSPI_Send_CMD(u8 cmd,u32 addr,u8 mode,u8 dmcycle)
{
        u32 tempreg=0;       
        u8 status;
        if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)        //等待BUSY空闲
        {
                tempreg=0<<31;                                                //禁止DDR模式
                tempreg|=0<<28;                                                //每次都发送指令
                tempreg|=0<<26;                                                //间接写模式
                tempreg|=((u32)mode>>6)<<24;                //设置数据模式
                tempreg|=(u32)dmcycle<<18;                        //设置空指令周期数
                tempreg|=((u32)(mode>>4)&0X03)<<12;        //设置地址长度
                tempreg|=((u32)(mode>>2)&0X03)<<10;        //设置地址模式
                tempreg|=((u32)(mode>>0)&0X03)<<8;        //设置指令模式
                tempreg|=cmd;                                                //设置指令
                QUADSPI->CCR=tempreg;                                //设置CCR寄存器
                if(mode&0X0C)                                                //有指令+地址要发送
                {
                        QUADSPI->AR=addr;                                //设置地址寄存器
                }
                if((mode&0XC0)==0)                                        //无数据传输,等待指令发送完成
                {
                        status=QSPI_Wait_Flag(1<<1,1,0XFFFF);//等待TCF,即传输完成
                        if(status==0)
                        {
                                QUADSPI->FCR|=1<<1;                        //清除TCF标志位
                        }
                }
        }       
}


//QSPI发送指定长度的数据
//buf:发送数据缓冲区首地址
//datalen:要传输的数据长度
//返回值:0,正常
//其他,错误代码
u8 QSPI_Transmit(u8* buf,u32 datalen)
{
        u32 tempreg=QUADSPI->CCR;
        u32 addrreg=QUADSPI->AR;
        u8 status;
        vu32 *data_reg=&QUADSPI->DR;
        QUADSPI->DLR=datalen-1;                                        //设置数据传输长度
        tempreg&=~(3<<26);                                                //清除FMODE原来的设置
        tempreg|=0<<26;                                                        //设置FMODE为间接写入模式
        QUADSPI->FCR|=1<<1;                                                //清除TCF标志位
        QUADSPI->CCR=tempreg;                                        //回写CCR寄存器
        while(datalen)
        {
                status=QSPI_Wait_Flag(1<<2,1,0XFFFF);//等到FTF
                if(status!=0)                                                //等待成功
                {
                        break;
                }
                *(vu8 *)data_reg=*buf++;
                datalen--;
        }
        if(status==0)
        {
                QUADSPI->CR|=1<<2;                                                        //终止传输
                status=QSPI_Wait_Flag(1<<1,1,0XFFFF);                //等待TCF,即数据传输完成
                if(status==0)
                {
                        QUADSPI->FCR|=1<<1;                                                //清除TCF标志位
                        status=QSPI_Wait_Flag(1<<5,0,0XFFFF);        //等待BUSY位清零
                }
        }
        return status;
}
//初始化 QSPI 接口
//返回值:0,成功; 1,失败;
u8 QSPI_Init(void)
{
        u32 tempreg=0;
        RCC->AHB4ENR|=0B11111;        //使能PORTABCDE时钟        

       
        RCC->AHB3ENR|=1<<14;                   //QSPI时钟使能
       
        GPIO_Set(GPIOA,1<<1,  GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PA1复用功能输出                BK1-IO3
        GPIO_Set(GPIOB,1<<2,  GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PB2复用功能输出                CLK
        GPIO_Set(GPIOB,1<<10, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PB10复用功能输出                BK1-NCS               
        GPIO_Set(GPIOC,1<<10, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PC10复用功能输出                BK1-IO1
        GPIO_Set(GPIOD,1<<11, GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PD11复用功能输出                BK1-IO0       
        GPIO_Set(GPIOE,1<<2,  GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PE2        复用功能输出                BK1-IO2       
        GPIO_Set(GPIOE,0XF<<7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);                //PE7~10复用功能输出        BK2-IO0-IO3       
       
  GPIO_AF_Set(GPIOA,1,9);                //PA1,AF9
        GPIO_AF_Set(GPIOB,2,9);                //PB2,AF9
        GPIO_AF_Set(GPIOB,10,9);        //PB10,AF9
        GPIO_AF_Set(GPIOC,10,9);        //PC10,AF9
        GPIO_AF_Set(GPIOD,11,9);        //PD10,AF9
        GPIO_AF_Set(GPIOE,2,9);                //PE2,AF9
        GPIO_AF_Set(GPIOE,7,10);        //PE7,AF10
        GPIO_AF_Set(GPIOE,8,10);        //PE8,AF10
        GPIO_AF_Set(GPIOE,9,10);        //PE9,AF10
        GPIO_AF_Set(GPIOE,10,10);        //PE10,AF10
       
               
        RCC->AHB3RSTR|=1<<14;                        //复位QSPI
        RCC->AHB3RSTR&=~(1<<14);        //停止复位QSPI
        if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0)//等待BUSY空闲
        {
                //QSPI时钟默认来自rcc_hclk3(由RCC_D1CCIPR的QSPISEL[1:0]选择)
                tempreg=(2-1)<<24;                //设置QSPI时钟为AHB时钟的1/2,即200M/2=100Mhz,10ns
                tempreg|=(4-1)<<8;                //设置FIFO阈值为4个字节(最大为31,表示32个字节)
                tempreg|=0<<7;                                //选择FLASH1
                tempreg|=1<<6;                                //双闪存模式
                tempreg|=1<<4;                                //采样移位半个周期(DDR模式下,必须设置为0)
                QUADSPI->CR=tempreg;        //设置CR寄存器
                tempreg=(8-1)<<16;                //设置FLASH大小为2^8=256
                tempreg|=(5-1)<<8;                //片选高电平时间为5个时钟(10*5=50ns),即手册里面的tSHSL参数
                tempreg|=1<<0;                                //Mode3,空闲时CLK为高电平
                QUADSPI->DCR=tempreg;        //设置DCR寄存器
                QUADSPI->CR|=1<<0;                //使能QSPI
        }
       
        else return 1;
        return 0;
}


int main(void)
{
       
.....
                        QSPI_Init();       
       
                        GPIO_Set(GPIOD,PIN3|PIN4|PIN5|PIN6|PIN7|PIN8|PIN9,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_LOW,GPIO_PUPD_PU);//PD3-PD7 行信号  PD8为LAT PD9-OE       
       
                        QSPI_Send_CMD(0,NULL,0XF0,4);//????????

                        while(1)
                        {
                               
                                for(int DisplayRowNumber=0;DisplayRowNumber<16;DisplayRowNumber++)        //16扫
                                {       

       

                                                                OE_SETH;                //息屏
                                                                DispLine(DisplayRowNumber);
                                       
                                                                QSPI_Transmit(DisplayArea+DisplayRowNumber*256,256);//送一行数据
                                                                LAT_SETL;                //低电平锁存
                                                                LAT_SETH;                //高电平并出
                                                                OE_SETL;                //亮屏                               
               
                                                                delay_us(20);
                                                               
                                                }

                               

               
               
                        }
       
}

出0入4汤圆

发表于 2022-5-5 09:23:02 | 显示全部楼层
DisplayArea[DisplayRowNumber*3*256+3*kkk+0]
这样的读取用指针试下吧. 看着这样密集的运算, 我都替CPU觉得"生活艰辛"

出100入312汤圆

发表于 2022-5-5 10:04:10 来自手机 | 显示全部楼层
3楼大神正解

出0入0汤圆

 楼主| 发表于 2022-5-5 16:00:04 | 显示全部楼层
qinxg 发表于 2022-5-5 09:23
DisplayArea[DisplayRowNumber*3*256+3*kkk+0]
这样的读取用指针试下吧. 看着这样密集的运算, 我都替CPU觉 ...
(引用自15楼)

已经优化成后面那一段了,现在在试DUAL QSPI

出15入178汤圆

发表于 2022-5-5 16:20:02 | 显示全部楼层
SetReset寄存器还用&=或|=就多余:
  1. GPIOD->BSRRL |=
复制代码

出0入0汤圆

 楼主| 发表于 2022-5-5 18:42:52 | 显示全部楼层
2nd 发表于 2022-5-5 16:20
SetReset寄存器还用&=或|=就多余:
(引用自18楼)

也是,直接赋值就行

出0入0汤圆

 楼主| 发表于 2022-5-6 16:56:08 | 显示全部楼层
哪位兄弟帮我看看,我看了很久的qpi,设定命令格式后,就发数据,驱动6个RGB信号,可是一直没有正确的RGB信号,这个命令格式,我不知道怎么弄,试了很久都不成功
QSPI_Send_CMD(0,NULL,0XF0,4);//????????

出16170入6148汤圆

发表于 2022-5-7 02:31:42 来自手机 | 显示全部楼层
【使用大字体,封锁ID一星期】



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出215入118汤圆

发表于 2022-5-7 07:44:45 来自手机 | 显示全部楼层
为什么不加片cpld

出0入0汤圆

 楼主| 发表于 2022-5-16 14:22:03 | 显示全部楼层
可能跑偏了,结贴,用DUAL QSPI不可能驱动LED,看时序!另外,我就使用几个大字体,居然被锁贴一个星期,太坑了,我大量使用大字体了吗?真是岂有此理,大量少量由你们自己定的?你们也没有说多少是大量啊,真是什么都是你们说了算啊

出0入17汤圆

发表于 2022-5-16 14:41:13 | 显示全部楼层
WUJIANLING 发表于 2022-5-16 14:22
可能跑偏了,结贴,用DUAL QSPI不可能驱动LED,看时序!另外,我就使用几个大字体,居然被锁贴一个星期,太 ...
(引用自23楼)

不知道那里惯的臭脾气,你来提问,网友免费认真的帮忙解答,你遵守一下论坛规则,不过分吧。
也许你刚来不清楚规则,禁言一周又不是什么大不了的处罚,以后知道就是了。
再者,论坛管理员说了不算,谁说了算? 不会跟两个十万哥一样,认为你发帖求助还是论坛的荣幸,论坛还得供着你活跃气氛?

出0入0汤圆

 楼主| 发表于 2022-5-16 15:34:42 | 显示全部楼层
你是不是搞错问题本质,首先,我感谢网友们的回答,你哪里看到我说不遵守论坛的规则,我只是表达我对论坛对我几个大字就处罚,也没有提醒,是你臭脾气还是我臭脾气?我哪臭脾气了?你管理员规则不清楚,怪我?还说惯的

出0入0汤圆

 楼主| 发表于 2022-5-16 15:48:53 | 显示全部楼层
本帖最后由 WUJIANLING 于 2022-5-16 15:50 编辑

你好像也不是管理员,轮到你在这啰里啰唆,居高临下,一开口就是谁惯的臭脾气,就算你是,你封我帐号啊

出0入0汤圆

 楼主| 发表于 2022-5-17 16:04:24 | 显示全部楼层
改用树莓派PICO,实现目标无压力,树莓派的IO翻转速度不是盖的,结帖

出16170入6148汤圆

发表于 2022-5-17 16:13:17 | 显示全部楼层
WUJIANLING 发表于 2022-5-16 15:48
你好像也不是管理员,轮到你在这啰里啰唆,居高临下,一开口就是谁惯的臭脾气,就算你是,你封我帐号啊 ...
(引用自26楼)

“你好像也不是管理员,轮到你在这啰里啰唆,居高临下,一开口就是谁惯的臭脾气,就算你是,你封我帐号啊””  21楼的截图已经告诉你,论坛发帖的界面已经有提醒,不得大量使用大号字体。谩骂坛友,永久封锁ID

出16170入6148汤圆

发表于 2022-5-18 15:10:15 来自手机 | 显示全部楼层
此人来骂街了:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入984汤圆

发表于 2022-5-18 20:58:18 | 显示全部楼层
本帖最后由 Himem 于 2022-5-18 21:16 编辑
WUJIANLING 发表于 2022-5-16 14:22
可能跑偏了,结贴,用DUAL QSPI不可能驱动LED,看时序!另外,我就使用几个大字体,居然被锁贴一个星期,太 ...
(引用自23楼)


>> 不可能驱动LED,看时序
位序么?提前在内存里调换完再写
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 20:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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