OpenEdv-开源电子网

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

搞了个音乐频谱,但刷屏很慢,显示是一屏一屏的,没有跳动感

[复制链接]

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
发表于 2018-1-18 12:11:32 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 rjx007 于 2018-1-20 14:34 编辑

折腾了好久,好不容易才调出来,可是刷屏很慢,显示示是一屏一屏的,完全没有跳动感。很失败,很伤心、很沮丧。。。。。。
用的是一个STM32F103C8T6的小系统板,驱动一个串口的SPI的OLED屏。
用的是ST提供的DSP函数做FFT,256点 ,ADC采样是用定时器2中断实现,定时器中断的频率是40K。取模后从中挑出25个频点做显示。方式是每个频点用一根柱条。诚心求教,应该怎么搞才行?
while(1)
         {               
                 if(ADC_TimeOutFlag)
                        {
                        
                           ADC_TimeOutFlag=0;
                           if(ADC_DataNum<NPT)   //采样点没有达到所要求的点
                                  {            
                                    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
                                    while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
                                    /* Clear channel1 transfer complete flag */
                                     DMA_ClearFlag(DMA1_FLAG_TC1);            
                                    ADC_SoftwareStartConvCmd(ADC1, DISABLE);
                                    lBUFIN[ADC_DataNum]=ADCConvertedValue<<16;
                                    ADC_DataNum++;
                                                
                                  }
                          else
                                 {
                                     TIM_Cmd(TIM2, DISABLE);
                                     ADC_DataNum=0;
                                     cr4_fft_256_stm32(lBUFOUT,lBUFIN,NPT);//调用STM32的DSP库作FFT变换
                                     powerMag(NPT);    //计算频点幅值      
                                     arctan();               //挑选25个频点,0-4K为主,4-8K次之,8K-18K最少。幅度较大的予以压缩。                                                
                                     dsp_column();      //显示25根柱条。
                                                
                                    TIM_Cmd(TIM2, ENABLE);
                           }
                  }               
          }



//显示各频点的柱条
void dsp_column(void)
{
   u8 i,j=2;
         
         for(i=0;i<25;i++)
           {
                OLED_Fill(j,0,j+3,COLUMN1,1);
                j=j+5;                                       
        
   }
                OLED_Refresh_Gram();                  
}


显示效果请见下面附件中的视频:


00010.rar

7.74 MB, 下载次数: 3324

最佳答案

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

刷屏慢的问题解决了。高兴!!!感谢5楼的提醒。 方法是两个: 1、将OLED原来的显示条柱的函数里的更新显存的的语句去掉,等所有数据都传递完了后再刷显存。 //x1,y1,x2,y2 填充区域的对角坐标 //确保x1
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-1-18 12:11:33 | 显示全部楼层
本帖最后由 rjx007 于 2018-1-20 18:51 编辑

刷屏慢的问题解决了。高兴!!!感谢5楼的提醒。
方法是两个:
1、将OLED原来的显示条柱的函数里的更新显存的的语句去掉,等所有数据都传递完了后再刷显存。

//x1,y1,x2,y2 填充区域的对角坐标
//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63                  
//dot:0,清空;1,填充         
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)  
{  
        u8 x,y;  
        for(x=x1;x<=x2;x++)
        {
                for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);
        }                                                                                                            
        //OLED_Refresh_Gram();//更新显示,这句去掉
}

2、更新每根柱条高度时,不能将前一屏全屏都刷掉,那样会浪费太多的时间,而是那个频点有变化,在原来的高度上做增减即可。
void dsp_column_1(void)
{
   u8 x,i,j=2;
         
         for(i=0;i<26;i++)
           {
                     if(COLUMN1>COLUMN1_LOD)  //新值大于老值,在原高度上增加
                            {
                                 x=COLUMN1-COLUMN1_LOD;
                                 OLED_Fill(j,COLUMN1_LOD,j+3,COLUMN1_LOD+x,1);                                 
                           }
                    if(COLUMN1<COLUMN1_LOD)  //新值小于老值,将高度超过的部分去掉
                           { OLED_Fill(j,COLUMN1,j+3,COLUMN1_LOD,0);}               
                   j=j+5;        
                  COLUMN1_LOD =COLUMN1;  
         }   
      OLED_Refresh_Gram();     //在这里更新显存            
      delay_ms(100);   //稍作延时,不然刷屏太快,有闪烁感
}

另外,硬件部分还要完善:
1、要增加自动增益控制,以免输入信号过大损坏ADC的输入端,再则输入过大会死机。
2、增加电瓶平移电路,因为输入的信号是交流信号,有负值部分,要抬高到全部为正值。
3、增加低通滤波电路,因大于20K的高频信号会带来干扰,导致频谱叠加和栅栏效应。
还要继续折腾,到完善为止。
视频拍的不好,意思能表达就行了。






VID_20180120_145918.rar

11.02 MB, 下载次数: 537

回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-1-18 17:30:29 | 显示全部楼层
诚心求教,顶起!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-1-19 01:53:27 | 显示全部楼层
帮顶
回复

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2018-1-19 08:50:26 | 显示全部楼层
感觉刷屏速度很慢?
可以在ram开辟一个显存,更新显示数据先在显存处理完成,再一次性刷屏出去,这样就不会有刷屏的过程。
让我们的思维驾驭在电的速度之上!
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-1-19 09:03:18 | 显示全部楼层
本帖最后由 rjx007 于 2018-1-19 09:09 编辑

楼上能具体说说该怎么做吗?这个函数好像就是你说的意思:OLED_Refresh_Gram();   但我不太会用,请指教。




u8 OLED_GRAM[128][8];         

//更新显存到LCD                 
void OLED_Refresh_Gram(void)
{
        u8 i,n;                    
        for(i=0;i<8;i++)  
        {  
                OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
                OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
                OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
                for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n],OLED_DATA);
        }   
}

回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-1-19 11:53:42 | 显示全部楼层
本帖最后由 rjx007 于 2018-1-19 14:54 编辑

虽然基本搞定了,但仍有改进的地方,所以继续征求好的建议,谢谢。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-1-20 14:27:44 | 显示全部楼层
本帖最后由 rjx007 于 2018-1-20 14:32 编辑

要想取得更好的效果,最好加上如图的电路:该电路可由功放或前级放大器引出信号。
2018-01-20_143349.jpg
2018-01-20_142755.jpg
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2018-6-14
在线时间
8 小时
发表于 2018-6-27 10:45:38 | 显示全部楼层
大神我最近也在做频谱分析,有许多问题想请教您,不知道您是否乐意指点一下
回复

使用道具 举报

28

主题

174

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
336
金钱
336
注册时间
2016-1-1
在线时间
153 小时
发表于 2018-6-27 14:15:57 | 显示全部楼层
本帖最后由 154648875 于 2018-6-27 14:24 编辑

AGC电路可以用吗
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2018-6-27 16:42:31 | 显示全部楼层
没有时间试,应该是可以用的。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-26 12:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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