數學和實際問題的關係.

很難明白的解釋, 需要時間消化, 基本上是 FIRST ORDER SYSTEM 的模型演變出來, 原文的資料 C 源碼不是很正確, 但是基本讀得出來, 最後的一行, output 應該改作 filter_output.

另外, ANALOG 有比較詳細的教科書解釋 DIGITAL SINGAL PROCESSING
http://www.analog.com/en/embedded-processing-dsp/adsp-21xx/products/books-seminars/scientist_engineers_guide/resources/fca.html

直接看需 FILTER 的部份
http://www.analog.com/static/imported-files/tech_docs/dsp_book_Ch14.pdf


很難明白的解釋 - 整數的 LOW PASS FILTER 設計原文.
http://www.edn.com/contents/images/6335310.pdf
//--------------------------
//simple software filter
#define FILTER_SHIFT 4           // Parameter K
#define sint32 (signed long)     // Specify 32-bit integer
#define sint16 (signed short)    // Specify 16-bit integer

sint32 filter_reg;                  // Delay element – 32 bits
sint16 filter_input;               // Filter input – 16 bits
sint16 filter_output;             // Filter output – 16 bits

// Update filter with current sample.
filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;

// Scale output for unity gain.
output = filter_reg >> FILTER_SHIFT;
//--------------------------



實際改正後, 以 AVR GCC 順利編譯的版本如下
MCU ATTINY13, 12MHz

//--------------------------
// http://hk.myblog.yahoo.com/xiao-laba/article?mid=2613
// APR/30/2010

//simple software filter, AVR GCC, complie successful
//

// AVR GCC data type           
//            
// Type    Size (bits)    min    max
// bit    1    0    1
// char    8    -128    127
// unsigned char    8    0    255
// signed char    8    -128    127
// int    16    -32768    32767
// short int    16    -32768    32767
// unsigned int    16    0    65535
// signed int    16    -32768    32767
// long    32    -2147483648    2147483647
// unsigned long int    32    0    4294967295
// signed long int    32    -2147483648    2147483647
// float    32    +/-1.175E-38    +/-3.402E+38
// double    32    +/-1.175E-38    +/-3.402E+38


// // http://www.edn.com/contents/images/6335310.pdf
// //
// // simple software filter
// //                                                     
// //                                                     
// // #define FILTER_SHIFT 4           // Parameter K     
// // #define sint32 (signed long)     // Specify 32-bit integer
// // #define sint16 (signed short)    // Specify 16-bit integer
// //                                                     
// // sint32 filter_reg;                  // Delay element – 32 bits
// // sint16 filter_input;               // Filter input – 16 bits
// // sint16 filter_output;             // Filter output – 16 bits
// //                                                     
// // // Update filter with current sample.               
// // filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;
// //                                                     
// // // Scale output for unity gain.                     
// // output = filter_reg >> FILTER_SHIFT;   <<< typo error         



// http://hk.myblog.yahoo.com/xiao-laba/article?mid=2613
// APR/30/2010

//simple software filter, AVR GCC, complie successful

#define FILTER_SHIFT 4          // Parameter K
#define sint32 signed long int  // Specify 32-bit integer
#define sint16 signed short int // Specify 16-bit integer

/*
sint32 filter_reg = 0x50;     // Delay element – 32 bits
sint16 filter_input = 0x100 ; // Filter input – 16 bits
sint16 filter_output;         // Filter output – 16 bits
*/

// try with 8 bit model, to simply the reading for ASM.
signed char filter_reg = 0x50;    // Delay element – 8 bits
signed char filter_input = 0x20 ; // Filter input – 8 bits
signed char filter_output;        // Filter output – 8 bits

int main(void)
{

   
    // Update filter with current sample.
    filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;

    //
    // Scale output for unity gain.
    filter_output = filter_reg >> FILTER_SHIFT;

    return 0;

}
//--------------------------



精華的兩行, 其使用的 MNEMONIC 如下, 為了方便了解, 只用 8 BIT 實驗. 方便觀察 C 源碼和 ASM 編碼的關係, 實際就是 CPU 執行運算的順序
//--------------------------
int main(void)
{

    // Update filter with current sample.
    filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;

行號   CODE             MNEMONIC          ;俺的注解
--------------------------------------------------------
  48:    90 91 60 00     lds    r25, 0x0060    ;filter_register
  4c:    80 91 61 00     lds    r24, 0x0061    ;filter_input
  50:    89 0f           add    r24, r25    ;filter_register + filter_input
  52:    95 95           asr    r25            ;filter_register >> 4
  54:    95 95           asr    r25
  56:    95 95           asr    r25
  58:    95 95           asr    r25
  5a:    89 1b           sub    r24, r25    ;-(filter_register >> 4)
  5c:    80 93 60 00     sts    0x0060, r24    ;store the result to filter_register

    // Scale output for unity gain.
    filter_output = filter_reg >> FILTER_SHIFT;
  60:    85 95           asr    r24
  62:    85 95           asr    r24
  64:    85 95           asr    r24
  66:    85 95           asr    r24
  68:    80 93 62 00     sts    0x0062, r24



    return 0;

//--------------------------
文章標籤
全站熱搜
創作者介紹
創作者 xiaolabaDIY 的頭像
xiaolabaDIY

xiaolabaDIY 的部落格

xiaolabaDIY 發表在 痞客邦 留言(0) 人氣(98)