1. 程式人生 > 其它 >【STM32F429的DSP教程】第50章 STM32F429的樣條插補實現,波形擬合絲滑順暢

【STM32F429的DSP教程】第50章 STM32F429的樣條插補實現,波形擬合絲滑順暢

完整版教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547

第50章 STM32F429的樣條插補實現,波形擬合絲滑順暢

本章節講解樣條插補,主要用於波形擬合,平滑過渡。

50.1 初學者重要提示

50.2 樣條插補介紹

50.3 樣條插補實現

50.4 實驗例程說明(MDK)

50.5 實驗例程說明(IAR)

50.6 總結

50.1 初學者重要提示

DSP庫支援了樣條插補,雙線性插補和線性插補,我們這裡主要介紹樣條插補的實現。

50.2 樣條插補介紹

在數學學科數值分析中,樣條是一種特殊的函式,由多項式分段定義。樣條的英語單詞spline來源於可變形的樣條工具,那是一種在造船和工程製圖時用來畫出光滑形狀的工具。在中國大陸,早期曾經被稱做“齒函式”。後來因為工程學術語中“放樣”一詞而得名。在插值問題中,樣條插值通常比多項式插值好用。用低階的樣條插值能產生和高階的多項式插值類似的效果,並且可以避免被稱為龍格現象的數值不穩定的出現。並且低階的樣條插值還具有“保凸”的重要性質。在電腦科學的計算機輔助設計和計算機圖形學中,樣條通常是指分段定義的多項式引數曲線。由於樣條構造簡單,使用方便,擬合準確,並能近似曲線擬合和互動式曲線設計中複雜的形狀,樣條是這些領域中曲線的常用表示方法

50.3 樣條插補實現

樣條插補主要通過下面兩個函式實現。

50.3.1 函式arm_spline_init_f32

函式原型:

void arm_spline_init_f32(
        arm_spline_instance_f32 * S,
        arm_spline_type type,
  const float32_t * x,
  const float32_t * y,
        uint32_t n, 
        float32_t * coeffs,
        float32_t * tempBuffer)

函式描述:

此函式用於樣條函式初始化。

函式引數:

  • 第1個引數是arm_spline_instance_f32型別結構體變數。
  • 第2個引數是樣條型別選擇:
    • ARM_SPLINE_NATURAL 表自然樣條。
    • ARM_SPLINE_PARABOLIC_RUNOUT 表示拋物線樣條。
  • 第3個引數是原始資料x軸座標值。
  • 第4個引數是原始資料y軸座標值。
  • 第5個引數是原始資料個數。
  • 第6個引數是插補因數快取。
  • 第7個引數是臨時緩衝。

注意事項:

  • x軸座標資料必須是遞增方式。
  • 第6個引數插補因數快取大小問題,如果原始資料個數是n,那麼插補因數個數必須要大於等於3*(n-1)。
  • 第7個引數臨時緩衝大小問題,如果原始資料個數是n,那麼臨時緩衝大小必須大於等於2*n - 1

50.3.2 函式arm_spline_f32

函式原型:

void arm_spline_f32(
        arm_spline_instance_f32 * S, 
  const float32_t * xq,
        float32_t * pDst,
        uint32_t blockSize)

函式描述:

此函式用於樣條插補實現。

函式引數:

  • 第1個引數是arm_spline_instance_f32型別結構體變數。
  • 第2個引數是插補後的x軸座標值,需要使用者指定,注意座標值一定是遞增的。
  • 第3個引數是經過插補計算後輸出的y軸數值
  • 第4個引數是資料輸出個數

50.3.3 使用樣條插補函式的關鍵點

樣條插補的主要作用是使得波形更加平滑。比如一幀是128點,步大小是8個畫素,我們可以通過插補實現步長為1, 1024點的波形,本質是你的總步長大小不能變,我們這裡都是1024,這個不能變,在這個基礎上做插補,效果就出來了。

這個認識非常重要,否則無法正常使用插補演算法。

50.3.4 自然樣條插補測試

樣條測試程式碼的實現如下:

#define INPUT_TEST_LENGTH_SAMPLES     128  /* 輸入資料個數 */
#define OUT_TEST_LENGTH_SAMPLES       1024   /* 輸出資料個數 */

#define SpineTab OUT_TEST_LENGTH_SAMPLES/INPUT_TEST_LENGTH_SAMPLES  /* 插補末尾的8個座標值不使用 */


float32_t xn[INPUT_TEST_LENGTH_SAMPLES];   /* 輸入資料x軸座標 */
float32_t yn[INPUT_TEST_LENGTH_SAMPLES];   /* 輸入資料y軸座標 */

float32_t coeffs[3*(INPUT_TEST_LENGTH_SAMPLES - 1)];     /* 插補係數緩衝 */  
float32_t tempBuffer[2 * INPUT_TEST_LENGTH_SAMPLES - 1]; /* 插補臨時緩衝 */  

float32_t xnpos[OUT_TEST_LENGTH_SAMPLES];  /* 插補計算後X軸座標值 */
float32_t ynpos[OUT_TEST_LENGTH_SAMPLES];  /* 插補計算後Y軸數值 */

/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程式入口
*    形    參: 無
*    返 回 值: 錯誤程式碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint32_t i;
    uint32_t idx2;
    uint8_t ucKeyCode;    
    arm_spline_instance_f32 S;
    

    bsp_Init();        /* 硬體初始化 */
    PrintfLogo();    /* 列印例程名稱和版本等資訊 */
    PrintfHelp();    /* 列印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重灌的定時器 */
    
    
    /* 原始x軸數值和y軸數值 */
    for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
    {
        xn[i] = i*SpineTab;
        yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
    }
    
    /* 插補後X軸座標值,這個是需要使用者設定的 */
    for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
    {
        xnpos[i] = i;
    }
    
    while (1)
    {
        bsp_Idle();        /* 這個函式在bsp.c檔案。使用者可以修改這個函式實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:  /* K1鍵按下,自然樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_NATURAL ,
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;
                
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

程式碼裡面的幾個關鍵地方:

  • 原始座標陣列xn和yn是128組,而我們通過插補生成的是1024組xnpos和ynpos,其中1024組的xnpos需要使用者設定初值,這點不能忽略。
  • 函式arm_spline_init_f32用於樣條函式初始化,這裡特別注意,此函式主要是對原始資料的操作。自然樣條插補用的ARM_SPLINE_NATURAL。
  • 函式arm_spline_f32用於樣條函式計算。

實際輸出效果如下:

50.3.5 拋物線樣條插補測試

樣條測試程式碼的實現如下:

#define INPUT_TEST_LENGTH_SAMPLES     128  /* 輸入資料個數 */
#define OUT_TEST_LENGTH_SAMPLES       1024   /* 輸出資料個數 */

#define SpineTab OUT_TEST_LENGTH_SAMPLES/INPUT_TEST_LENGTH_SAMPLES  /* 插補末尾的8個座標值不使用 */


float32_t xn[INPUT_TEST_LENGTH_SAMPLES];   /* 輸入資料x軸座標 */
float32_t yn[INPUT_TEST_LENGTH_SAMPLES];   /* 輸入資料y軸座標 */

float32_t coeffs[3*(INPUT_TEST_LENGTH_SAMPLES - 1)];     /* 插補係數緩衝 */  
float32_t tempBuffer[2 * INPUT_TEST_LENGTH_SAMPLES - 1]; /* 插補臨時緩衝 */  

float32_t xnpos[OUT_TEST_LENGTH_SAMPLES];  /* 插補計算後X軸座標值 */
float32_t ynpos[OUT_TEST_LENGTH_SAMPLES];  /* 插補計算後Y軸數值 */

/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程式入口
*    形    參: 無
*    返 回 值: 錯誤程式碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint32_t i;
    uint32_t idx2;
    uint8_t ucKeyCode;    
    arm_spline_instance_f32 S;
    

    bsp_Init();        /* 硬體初始化 */
    PrintfLogo();    /* 列印例程名稱和版本等資訊 */
    PrintfHelp();    /* 列印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重灌的定時器 */
    
    
    /* 原始x軸數值和y軸數值 */
    for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
    {
        xn[i] = i*SpineTab;
        yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
    }
    
    /* 插補後X軸座標值,這個是需要使用者設定的 */
    for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
    {
        xnpos[i] = i;
    }
    
    while (1)
    {
        bsp_Idle();        /* 這個函式在bsp.c檔案。使用者可以修改這個函式實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K2:            /* K2鍵按下,拋物線樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_PARABOLIC_RUNOUT , 
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;
                
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

程式碼裡面的幾個關鍵地方:

  • 原始座標陣列xn和yn是128組,而我們通過插補生成的是1024組xnpos和ynpos,其中1024組的xnpos需要使用者設定初值,這點不能忽略。
  • 函式arm_spline_init_f32用於樣條函式初始化,這裡特別注意,此函式主要是對原始資料的操作。拋物線樣條插補用的ARM_SPLINE_PARABOLIC_RUNOUT。
  • 函式arm_spline_f32用於樣條函式計算。

實際輸出效果如下:

50.4 實驗例程說明(MDK)

配套例子:

V6-235_樣條插補,波形擬合絲滑順暢

實驗目的:

  1. 學習樣條插補的實現。

實驗內容:

  1. 啟動一個自動重灌軟體定時器,每100ms翻轉一次LED2。
  2. K1鍵按下,自然樣條插補測試。
  3. K2鍵按下,拋物線樣插補測試。

使用AC6注意事項

特別注意附件章節C的問題

上電後串列埠列印的資訊:

波特率 115200,資料位 8,奇偶校驗位無,停止位 1。

RTT方式列印資訊:

程式設計:

系統棧大小分配:

硬體外設初始化

硬體外設的初始化是在 bsp.c 檔案實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬體裝置。該函式配置CPU暫存器和外設的暫存器並初始化一些全域性變數。只需要呼叫一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 
       STM32F429 HAL 庫初始化,此時系統用的還是F429自帶的16MHz,HSI時鐘:
       - 呼叫函式HAL_InitTick,初始化滴答時鐘中斷1ms。
       - 設定NVIC優先順序分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鐘到168MHz
       - 切換使用HSE。
       - 此函式會更新全域性變數SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於程式碼執行時間測量,MDK5.25及其以上版本才支援,IAR不支援。
       - 預設不開啟,如果要使能此選項,務必看V5開發板使用者手冊第8章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串列埠 */
    bsp_InitExtIO();   /* 初始化擴充套件IO */
    bsp_InitLed();        /* 初始化LED */
}

主功能:

主程式實現如下操作:

  • 啟動一個自動重灌軟體定時器,每100ms翻轉一次LED2。
  • K1鍵按下,自然樣條插補測試。
  • K2鍵按下,拋物線樣插補測試。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程式入口
*    形    參: 無
*    返 回 值: 錯誤程式碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint32_t i;
    uint32_t idx2;
    uint8_t ucKeyCode;    
    arm_spline_instance_f32 S;
    

    bsp_Init();        /* 硬體初始化 */
    PrintfLogo();    /* 列印例程名稱和版本等資訊 */
    PrintfHelp();    /* 列印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重灌的定時器 */
    
    
    /* 原始x軸數值和y軸數值 */
    for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
    {
        xn[i] = i*SpineTab;
        yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
    }
    
    /* 插補後X軸座標值,這個是需要使用者設定的 */
    for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
    {
        xnpos[i] = i;
    }
    
    while (1)
    {
        bsp_Idle();        /* 這個函式在bsp.c檔案。使用者可以修改這個函式實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:  /* K1鍵按下,自然樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_NATURAL ,
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;

                case KEY_DOWN_K2:            /* K2鍵按下,拋物線樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_PARABOLIC_RUNOUT , 
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;
                
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

50.5 實驗例程說明(IAR)

配套例子:

V6-235_樣條插補,波形擬合絲滑順暢

實驗目的:

  1. 學習樣條插補的實現。

實驗內容:

  1. 啟動一個自動重灌軟體定時器,每100ms翻轉一次LED2。
  2. K1鍵按下,自然樣條插補測試。
  3. K2鍵按下,拋物線樣插補測試。

上電後串列埠列印的資訊:

波特率 115200,資料位 8,奇偶校驗位無,停止位 1。

RTT方式列印資訊:

程式設計:

系統棧大小分配:

硬體外設初始化

硬體外設的初始化是在 bsp.c 檔案實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬體裝置。該函式配置CPU暫存器和外設的暫存器並初始化一些全域性變數。只需要呼叫一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 
       STM32F429 HAL 庫初始化,此時系統用的還是F429自帶的16MHz,HSI時鐘:
       - 呼叫函式HAL_InitTick,初始化滴答時鐘中斷1ms。
       - 設定NVIC優先順序分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鐘到168MHz
       - 切換使用HSE。
       - 此函式會更新全域性變數SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於程式碼執行時間測量,MDK5.25及其以上版本才支援,IAR不支援。
       - 預設不開啟,如果要使能此選項,務必看V5開發板使用者手冊第8章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串列埠 */
    bsp_InitLed();        /* 初始化LED */        
}

主功能:

主程式實現如下操作:

  • 啟動一個自動重灌軟體定時器,每100ms翻轉一次LED2。
  • K1鍵按下,自然樣條插補測試。
  • K2鍵按下,拋物線樣插補測試。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程式入口
*    形    參: 無
*    返 回 值: 錯誤程式碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint32_t i;
    uint32_t idx2;
    uint8_t ucKeyCode;    
    arm_spline_instance_f32 S;
    

    bsp_Init();        /* 硬體初始化 */
    PrintfLogo();    /* 列印例程名稱和版本等資訊 */
    PrintfHelp();    /* 列印操作提示 */
    
    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重灌的定時器 */
    
    
    /* 原始x軸數值和y軸數值 */
    for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
    {
        xn[i] = i*SpineTab;
        yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
    }
    
    /* 插補後X軸座標值,這個是需要使用者設定的 */
    for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
    {
        xnpos[i] = i;
    }
    
    while (1)
    {
        bsp_Idle();        /* 這個函式在bsp.c檔案。使用者可以修改這個函式實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:  /* K1鍵按下,自然樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_NATURAL ,
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;

                case KEY_DOWN_K2:            /* K2鍵按下,拋物線樣條插補 */
                    /* 樣條初始化 */
                    arm_spline_init_f32(&S,
                                        ARM_SPLINE_PARABOLIC_RUNOUT , 
                                        xn,
                                        yn,
                                        INPUT_TEST_LENGTH_SAMPLES,
                                        coeffs,
                                        tempBuffer);
                    /* 樣條計算 */
                    arm_spline_f32    (&S,
                                     xnpos,
                                     ynpos,
                                     OUT_TEST_LENGTH_SAMPLES);

                
                    /* 列印輸出輸出 */
                    idx2 = 0;
                    for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
                    {    
                            if ((i % SpineTab) == 0)
                            {
                                    printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
                            }
                            else
                            {
                                    printf("%f,\r\n", ynpos[i]);
                            }
                    }
                    break;
                
                default:
                    /* 其它的鍵值不處理 */
                    break;
            }
        }
    }
}

50.6 總結

本章節主要講解了樣條插補的實現,實際專案比較實用,有興趣可以深入原始碼瞭解。

微信公眾號:armfly_com 安富萊論壇:www.armbbs.cn 安富萊淘寶:https://armfly.taobao.com