久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 53|回復: 1
打印 上一主題 下一主題
收起左側

求助3264雙色點陣音樂頻譜的問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:86421 發表于 2025-4-19 16:01 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
偶得一塊3264雙色的點陣屏,想用STC15的單片機做一個音樂頻譜,頻率24M。可整了幾天也整不出來,煩請老師幫忙看一下問題出在哪?該如何改?代碼中:ADC讀取部分移植于12864音樂頻譜顯示,好用,顯示部分就簡單了?傻揭黄鹁筒缓糜昧恕V詻]有用定時器控制顯示,是不會計算ADC的時序,怕程序出現問題。另:本論壇中也有音樂頻譜的相關資料,可沒有一個上機能用的,為此我還專門買了STC12的單片機,不知問題出在哪。
  1. #include<math.h>

  2. #include <STC15.h>

  3. #include "intrins.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int



  6. #define ADC_POWER   0x80     
  7. #define ADC_FLAG    0x10     
  8. #define ADC_START   0x08     
  9. #define ADC_SPEEDLL 0x00     
  10. #define ADC_SPEEDL  0x20     
  11. #define ADC_SPEEDH  0x40     
  12. #define ADC_SPEEDHH 0x60     

  13. struct compx                                                                           
  14. {
  15.         float real;
  16.         float imag;
  17. };

  18. xdata struct compx s[ 64 ];                                                      
  19. struct compx EE(struct compx,struct compx);   
  20. void FFT(struct compx xin[],int N);                                    


  21. sbit  R1=P3^6;   
  22. sbit  R2=P3^7;   
  23. sbit  G1=P2^4;   
  24. sbit  G2=P2^5;   

  25. sbit  STB=P2^6;   
  26. sbit  SCK=P2^7;   
  27. sbit  OE=P3^5;         

  28. sbit  IA=P2^0;   
  29. sbit  IB=P2^1;   
  30. sbit  IC=P2^2;   
  31. sbit  ID=P2^3;   


  32. uchar data row;                        


  33. void xianshi();      
  34. void hang();         


  35. void InitADC()
  36. {
  37.           P1ASF =0x01;              
  38.           P1M0 = 0x01;                    
  39.           P1M1 = 0x01;              
  40.     ADC_RES = 0;               
  41.           ADC_RESL = 0;                  
  42.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;         
  43. }


  44. unsigned int  GetADCResult(unsigned char  ch)
  45. {
  46.     ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ch | ADC_START;
  47.     _nop_();                        
  48.     _nop_();
  49.     _nop_();
  50.     _nop_();
  51.     while (!(ADC_CONTR & ADC_FLAG));
  52.     ADC_CONTR &= ~ADC_FLAG;         
  53.     return (ADC_RES<<2+ADC_RESL);               
  54. }


  55. struct compx EE(struct compx a1,struct compx b2)        
  56. {
  57.         struct compx b3;
  58.         b3.real=a1.real*b2.real-a1.imag*b2.imag;
  59.         b3.imag=a1.real*b2.imag+a1.imag*b2.real;
  60.         return(b3);
  61. }

  62. void FFT(struct compx xin[],int N)                                 
  63. {
  64.         int f,m,nv2,nm1,i,k,j=1,l;
  65.         struct compx v,w,t;
  66.         nv2=N/2;
  67.         f=N;
  68.         for(m=1;(f=f/2)!=1;m++){;}
  69.         nm1=N-1;
  70.         for(i=0;i<nm1;i++)                                          
  71.         {
  72.                 if(i<j)
  73.                 {
  74.                         t=xin[j];
  75.                         xin[j]=xin[i];
  76.                         xin[i]=t;
  77.                 }
  78.                 k=nv2;                                                      
  79.                 while(k<j)
  80.                 {
  81.                         j=j-k;
  82.                         k=k/2;
  83.                 }
  84.                 j=j+k;
  85.         }
  86.         {
  87.                 int le,lei,ip;
  88.                   float pi;
  89.                   for(l=1;l<=m;l++)
  90.                    {
  91.                 le=pow(2,l);                                                
  92.                     lei=le/2;
  93.                     pi=3.14159265;
  94.                     v.real=1.0;
  95.                 v.imag=0.0;  
  96.                    w.real=cos(pi/lei);                                          
  97.                     w.imag=-sin(pi/lei);
  98.                   
  99.                 for(j=1;j<=lei;j++)                                          
  100.                      {
  101.                         for(i=j-1;i<N;i=i+le)                                         
  102.                               {
  103.                                     ip=i+lei;
  104.                                        t=EE(xin[ ip ],v);
  105.                                        xin[ ip ].real=xin[ i ].real-t.real;   
  106.                                        xin[ ip ].imag=xin[ i ].imag-t.imag;
  107.                                        xin[ i ].real=xin[ i ].real+t.real;
  108.                                        xin[ i ].imag=xin[ i ].imag+t.imag;
  109.                               }
  110.                               v=EE(v,w);   
  111.                       }     
  112.                    }
  113.           }
  114. }


  115. void main (void)
  116. {

  117.         int N=64,i;                                                            
  118.         float offset;

  119.         P1M0=0x00;
  120.   P1M1=0x00;
  121.   P3M0=0x00;
  122.   P3M1=0x00;
  123.   P2M0=0x00;
  124.   P2M1=0x00;

  125.   InitADC();         
  126.         offset=GetADCResult(0);
  127.       
  128.         while (1)         
  129.         {
  130.                         for(i=0;i<N;i++)                                      
  131.                   {
  132.                                 ADC_CONTR=0xC8;                                         

  133.                                 while(!(ADC_CONTR&0x10));
  134.                                    s[i].real=((float)ADC_RES*4+(float)(ADC_RESL%0x04)-offset)/4;  
  135.                                    s[i].imag=0;
  136.                   }
  137.                        
  138.                           FFT(s,N);        
  139.                     xianshi();
  140.         }
  141. }



  142. void hang(unsigned char Value)
  143. {
  144.         switch(Value)
  145.         {
  146.                                         case  0: {IA=0;IB=0;IC=0;ID=0;}break;
  147.                       case  1: {IA=1;IB=0;IC=0;ID=0;}break;
  148.                       case  2: {IA=0;IB=1;IC=0;ID=0;}break;
  149.                       case  3: {IA=1;IB=1;IC=0;ID=0;}break;
  150.           case  4: {IA=0;IB=0;IC=1;ID=0;}break;
  151.                       case  5: {IA=1;IB=0;IC=1;ID=0;}break;
  152.                       case  6: {IA=0;IB=1;IC=1;ID=0;}break;
  153.                       case  7: {IA=1;IB=1;IC=1;ID=0;}break;
  154.           case  8: {IA=0;IB=0;IC=0;ID=1;}break;
  155.                       case  9: {IA=1;IB=0;IC=0;ID=1;}break;
  156.                       case 10: {IA=0;IB=1;IC=0;ID=1;}break;
  157.                       case 11: {IA=1;IB=1;IC=0;ID=1;}break;
  158.           case 12: {IA=0;IB=0;IC=1;ID=1;}break;
  159.                       case 13: {IA=1;IB=0;IC=1;ID=1;}break;
  160.                        case 14: {IA=0;IB=1;IC=1;ID=1;}break;
  161.                 case 15: {IA=1;IB=1;IC=1;ID=1;}break;
  162.         }
  163.                                        
  164. }


  165. void xianshi()
  166. {
  167.   unsigned char i,j;
  168.         unsigned char dis_rdata[16];

  169.         for(i=0;i<16;i++)         
  170.         {
  171.                 float t0=0;
  172.                 t0=sqrt(pow((s[i  ].real+s[i+1].real),2)+pow((s[i  ].imag+s[i+1].imag),2))/2;
  173.                 dis_rdata[i]=(unsigned char)t0;
  174.         }

  175.                          for(j=0;j<64;j++)           
  176.                         {                                       
  177.                                 SCK=0;
  178.                                 SCK=1;

  179.                                 if(dis_rdata[j]<=row+16) R1=1;
  180.                                 else R1=0;
  181.                                 if(dis_rdata[j]<=row) R2=1;
  182.                                 else R2=0;
  183.                         }

  184.                 STB=1;
  185.                 STB=0;                                

  186.                 row++;
  187.                         if(row>15)row=0;
  188.                         OE=1;
  189.                 hang(row);                        
  190.                 OE=0;
  191. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1137639 發表于 2025-4-19 22:31 | 只看該作者
### 代碼問題分析
1. **頭文件包含與編譯器兼容性**
    - 代碼中包含了`STC15.h`頭文件,該頭文件用于STC15系列單片機,對寄存器等進行定義。確保該頭文件與所使用的編譯器版本兼容,不同編譯器對頭文件的支持和解析可能存在差異。如果編譯器對某些寄存器定義識別有誤,可能導致程序運行異常。
    - 雖然包含了`math.h`用于運算(如在`FFT`函數中使用`pow`、`cos`、`sin`等函數),但在單片機開發中,`math.h`庫函數的實現可能會消耗較多資源(如代碼空間和運行時間)。對于資源有限的單片機(如STC15 ),可能需要考慮使用簡化的運算替代方案,或者優化庫函數的使用。
2. **ADC部分**
    - 在`InitADC`函數中,對`P1ASF`、`P1M0`、`P1M1`進行設置,用于配置ADC相關引腳的功能。確保這些設置與實際硬件連接匹配,例如所選的ADC通道引腳是否正確配置為模擬輸入功能。
    - 在`GetADCResult`函數中,通過設置`ADC_CONTR`寄存器啟動ADC轉換,并等待轉換完成標志位。這里存在一個潛在問題,在等待轉換完成標志位時,只是簡單地循環檢測,沒有添加超時機制。如果ADC轉換出現異常,可能導致程序進入死循環?梢蕴砑右粋計數器,在一定次數檢測后跳出循環并進行錯誤處理。
3. **FFT(快速傅里葉變換)部分**
    - `FFT`函數實現較為復雜,在計算過程中涉及到大量的復數運算(通過`EE`函數實現復數乘法 )。需要仔細檢查復數運算邏輯是否正確,例如`EE`函數中復數乘法的計算是否符合數學定義,確保在運算過程中不會出現精度丟失或計算錯誤,影響FFT結果的準確性。
    - 在`FFT`函數中,一些變量的初始化和計算邏輯可能存在問題。例如`for(m = 1;(f = f/2) != 1;m++){;}`這部分代碼用于計算FFT的級數,要確保計算結果正確,否則后續的蝶形運算可能會出現錯誤。
4. **顯示部分**
    - 在`xianshi`函數中,計算頻譜數據并控制點陣屏顯示。這里計算頻譜數據的方式是根據FFT結果進行簡單處理,需要確認這種處理方式是否能準確反映音樂頻譜。例如,計算平方根等操作是否符合實際頻譜顯示需求。
    - 點陣屏的顯示控制邏輯較為簡單,通過`SCK`、`STB`、`OE`等引腳控制數據傳輸和顯示。需要檢查這些引腳的時序是否與點陣屏的硬件要求嚴格匹配。如果時序出現偏差,可能導致顯示異常,如顯示亂碼、部分區域不顯示等問題。同時,在控制`R1`、`R2`等引腳時,判斷條件和邏輯可能需要進一步優化,以實現更準確的頻譜顯示效果。
5. **整體時序與資源管理**
    - 由于沒有使用定時器控制顯示,而是在主循環中不斷進行ADC讀取、FFT計算和顯示操作,可能導致各部分操作的時序混亂。例如,ADC讀取頻率可能與FFT計算和顯示頻率不匹配,影響最終的頻譜顯示效果。建議使用定時器來精確控制各部分操作的時間間隔,確保程序運行的穩定性和準確性。
    - STC15單片機資源有限,在進行ADC讀取、FFT計算和點陣屏顯示等操作時,要注意資源管理。例如,代碼中定義了較多的變量(如`xdata struct compx s[64]` ),需要確保這些變量的存儲不會超出單片機的內存限制。同時,FFT計算等操作可能會占用較多的計算資源和時間,要合理優化算法,避免程序運行過于緩慢或出現死機現象。

### 改進建議
1. **ADC部分改進**
    - 在`GetADCResult`函數中添加超時機制。例如:
```c
unsigned int GetADCResult(unsigned char ch)
{
    int timeout = 100; // 設置超時次數
    ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ch | ADC_START;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG) && timeout > 0) {
        timeout--;
    }
    if (timeout == 0) {
        // 處理超時錯誤,例如返回一個錯誤值
        return 0xFFFF;
    }
    ADC_CONTR &= ~ADC_FLAG;
    return (ADC_RES<<2+ADC_RESL);
}
```
2. **FFT部分改進**
    - 對`FFT`函數中的變量初始化和計算邏輯進行詳細驗證。可以通過打印中間變量的值等方式,檢查每一步計算是否正確。例如,在計算級數的部分:
```c
for(m = 1;(f = f/2) != 1;m++){;}
// 可以添加打印語句,查看m和f的值是否符合預期
// 如:printf("m = %d, f = %d\n", m, f);
```
    - 優化復數運算部分的代碼,提高計算精度和效率?梢詤⒖家恍┏墒斓腇FT算法實現,對比檢查代碼中的運算邏輯是否正確。
3. **顯示部分改進**
    - 重新評估頻譜數據的計算方式,可以參考相關的音樂頻譜顯示算法資料,確保計算出的數據能準確反映音樂頻譜。
    - 使用示波器等工具測量點陣屏控制引腳的時序,與點陣屏的硬件手冊進行對比,精確調整時序邏輯。例如,確保`SCK`、`STB`等信號的脈沖寬度、上升沿和下降沿時間等符合要求。
4. **整體時序與資源管理改進**
    - 使用定時器來控制程序的運行時序。例如,設置一個定時器中斷,每隔一定時間(如根據音樂信號的頻率和采樣要求確定 )觸發一次ADC讀取操作,然后進行FFT計算和顯示操作。在STC15單片機中,可以通過配置定時器相關寄存器來實現。
    - 對代碼中的變量進行優化,合理分配內存資源。如果內存緊張,可以考慮減少不必要的變量定義,或者對一些變量進行復用。同時,對FFT等復雜算法進行優化,減少計算資源的消耗。例如,可以使用定點運算替代部分浮點運算,以提高運算速度和減少資源占用。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级h片| 资源首页二三区 | av一级久久| 亚洲一区二区日韩 | 欧美成人在线影院 | 成人午夜激情 | 一区二区三区福利视频 | 久久久.com | 成人av免费 | 亚洲一区视频在线 | 日韩欧美国产一区二区三区 | 国产在线视频一区 | 国产你懂的在线观看 | 国产精品久久亚洲 | 国产婷婷综合 | 鸡毛片| 91精品国产欧美一区二区 | 男人天堂午夜 | 中文字幕亚洲在线 | 欧美久久久网站 | 亚洲一区在线播放 | 国产欧美一级 | 成人午夜毛片 | 亚洲欧美综合精品久久成人 | 一区二区免费 | 国产精品www | www.887色视频免费 | 伊人网一区| 在线免费激情视频 | 在线免费亚洲视频 | 一级黄色毛片子 | 久久久久久亚洲精品 | 男女免费视频网站 | 久久成人精品 | 91玖玖| 久久精品一区二区三区四区 | 国产在线精品一区二区三区 | 中文在线观看视频 | 久久国产精品亚洲 | 精品久久久久国产 | 一区二区三区视频在线 |