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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 226|回復(fù): 2
收起左側(cè)

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

[復(fù)制鏈接]
ID:86421 發(fā)表于 2025-4-19 16:01 | 顯示全部樓層 |閱讀模式
偶得一塊3264雙色的點陣屏,想用STC15的單片機做一個音樂頻譜,頻率24M。可整了幾天也整不出來,煩請老師幫忙看一下問題出在哪?該如何改?代碼中:ADC讀取部分移植于12864音樂頻譜顯示,好用,顯示部分就簡單了。可到一起就不好用了。之所以沒有用定時器控制顯示,是不會計算ADC的時序,怕程序出現(xiàn)問題。另:本論壇中也有音樂頻譜的相關(guān)資料,可沒有一個上機能用的,為此我還專門買了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. }
復(fù)制代碼


回復(fù)

使用道具 舉報

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

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

使用道具 舉報

ID:86421 發(fā)表于 2025-4-20 07:57 | 顯示全部樓層
622323wjl 發(fā)表于 2025-4-19 22:31
### 代碼問題分析
1. **頭文件包含與編譯器兼容性**
    - 代碼中包含了`STC15.h`頭文件,該頭文件用于ST ...

感謝!謝謝你的指導(dǎo),分析的很有道理。比DeepSeek分析的還好。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产精品成人 | 亚洲精品视频在线看 | 日韩aⅴ片 | 久久宗合色 | 91中文字幕在线观看 | 日本中出视频 | 久久国产精品精品国产色婷婷 | 久久久久国产一区二区三区不卡 | 国产1区2区在线观看 | 国产午夜视频 | 精品国产乱码久久久久久丨区2区 | 日韩高清中文字幕 | 国产在线精品一区二区三区 | 香蕉视频91 | 国产精品国产三级国产aⅴ中文 | 奇米影视77 | 久久男人 | 欧美福利精品 | 国产成人精品综合 | 91精品国产欧美一区二区 | 99精彩视频| 中文无码日韩欧 | 亚洲国产欧美一区二区三区久久 | 国产精品久久久久一区二区三区 | 一区视频 | 国产一级毛片视频 | 黄色av网站在线免费观看 | 国产区视频在线观看 | 国产在线观看一区二区 | 欧美成人免费 | 久久国产精彩视频 | 在线欧美 | 伊人网综合在线观看 | 亚洲精品高清视频在线观看 | 一区二区三区四区在线视频 | 午夜精品一区二区三区在线观看 | 国产视频久久久 | 国产一区二区电影 | 91秦先生艺校小琴 | 日韩电影免费在线观看中文字幕 | 天天天操天天天干 |