完整版教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547
第20章 DSP復數運算-模平方,乘法和復數乘實數
本期教程主要講解復數運算中的模平方,乘法和復數乘實數。
20.1 初學者重要提示
20.2 DSP基礎運算指令
20.3 復數模平方(ComplexMagSquared)
20.4 復數乘法(ComplexMultComplex)
20.5 復數乘實數(ComplexMultComplex)
20.6 實驗例程說明(MDK)
20.7 實驗例程說明(IAR)
20.8 總結
20.1 初學者重要提示
- 復數運算比較重要,后面FFT章節要用到,如果印象不深的話,需要溫習下高數知識了。
20.2 DSP基礎運算指令
本章用到的DSP指令在前面章節都已經講解過。
20.3 復數模平方(ComplexMagSquared)
這部分函數用於復數求模平方,公式描述如下:
for(n=0; n<numSamples; n++) {
pDst[n] = pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2;
}
用代數式來表示模平方:
a+bi模平方 = a2 + b2 。
20.3.1 函數arm_cmplx_mag_squared_f32
函數原型:
void arm_cmplx_mag_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於浮點數類型的復數求模平方。
函數參數:
- 第1個參數是源數據地址。
- 第2個參數是求模平方后的數據地址。
- 第3個參數是要求解的復數個數。
注意事項:
數組pSrc中存儲的數據格式是(實部,虛部,實部,虛部……………),一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而模值的結果存到pDst里面。
20.3.2 函數arm_cmplx_mag_squared_q31
函數原型:
void arm_cmplx_mag_squared_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於定點數Q31類型的復數求模平方。
函數參數:
- 第1個參數是源數據地址。
- 第2個參數是求模平方后的數據地址。
- 第3個參數是要求解的復數個數。
注意事項:
- 兩個1.31格式的定點數相乘為2.62,程序中將此結果做了放縮,此函數的最終結果轉換后為3.29。
- 數組pSrc中存儲的數據格式是(實部,虛部,實部,虛部……………),一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而模值的結果存到pDst里面。
20.3.3 函數arm_cmplx_mag_squared_q15
函數原型:
void arm_cmplx_mag_squared_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於定點數Q15類型的復數求模平方。
函數參數:
- 第1個參數是源數據地址。
- 第2個參數是求模平方后的數據地址。
- 第3個參數是要求解的復數個數。
注意事項:
- 兩個1.15格式的定點數相乘為2.30,程序中將此結果做了放縮,此函數的最終結果轉換后為3.13。
- 數組pSrc中存儲的數據格式是(實部,虛部,實部,虛部……………),一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而模值的結果存到pDst里面。
20.3.4 使用舉例
程序設計:
/* ********************************************************************************************************* * 函 數 名: DSP_MagSquared * 功能說明: 復數模的平方 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ static void DSP_MagSquared(void) { uint8_t i; float32_t pSrc[10] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f, 5.1f}; float32_t pDst[10]; q31_t pSrc1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456, 4*268435456, 4*268435456, 5*268435456, 5*268435456}; q31_t pDst1[10]; q15_t pSrc2[10] = {5000, 10000, 15000, 20000, 25000, 5000, 10000, 15000, 20000, 25000}; q15_t pDst2[10]; /***浮點數模平方*******************************************************************************/ arm_cmplx_mag_squared_f32(pSrc, pDst, 5); for(i = 0; i < 5; i++) { printf("pDst[%d] = %f\r\n", i, pDst[i]); } /***定點數模平方Q31*******************************************************************************/ arm_cmplx_mag_squared_q31(pSrc1, pDst1, 5); for(i = 0; i < 5; i++) { printf("pDst1[%d] = %d\r\n", i, pDst1[i]); } /***定點數模平方Q15*******************************************************************************/ arm_cmplx_mag_squared_q15(pSrc2, pDst2, 5); for(i = 0; i < 5; i++) { printf("pDst2[%d] = %d\r\n", i, pDst2[i]); } } /* ********************************************************************************************************* * 函 數 名: DSP_MatInit * 功能說明: 矩陣數據初始化 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ static void DSP_MatInit(void) { uint8_t i; /****浮點數數組******************************************************************/ float32_t pDataA[9] = {1.1f, 1.1f, 2.1f, 2.1f, 3.1f, 3.1f, 4.1f, 4.1f, 5.1f}; arm_matrix_instance_f32 pSrcA; //3行3列數據 /****定點數Q31數組******************************************************************/ q31_t pDataA1[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5}; arm_matrix_instance_q31 pSrcA1; //3行3列數據 /****定點數Q15數組******************************************************************/ q15_t pDataA2[9] = {1, 1, 2, 2, 3, 3, 4, 4, 5}; arm_matrix_instance_q15 pSrcA2; //3行3列數據 /****浮點數***********************************************************************/ printf("****浮點數******************************************\r\n"); arm_mat_init_f32(&pSrcA, 3,3, pDataA); for(i = 0; i < 9; i++) { printf("pDataA[%d] = %f\r\n", i, pDataA[i]); } /****定點數Q31***********************************************************************/ printf("****浮點數******************************************\r\n"); arm_mat_init_q31(&pSrcA1, 3,3, pDataA1); for(i = 0; i < 9; i++) { printf("pDataA1[%d] = %d\r\n", i, pDataA1[i]); } /****定點數Q15***********************************************************************/ printf("****浮點數******************************************\r\n"); arm_mat_init_q15(&pSrcA2, 3,3, pDataA2); for(i = 0; i < 9; i++) { printf("pDataA2[%d] = %d\r\n", i, pDataA2[i]); } }
實驗現象(按下K1按鍵后串口打印模平方):
20.4 復數乘法 (ComplexMultComplex)
這部分函數用於復數乘復數,公式描述如下:
for (n = 0; n < numSamples; n++) {
pDst[(2*n)+0] = pSrcA[(2*n)+0] * pSrcB[(2*n)+0] - pSrcA[(2*n)+1] * pSrcB[(2*n)+1];
pDst[(2*n)+1] = pSrcA[(2*n)+0] * pSrcB[(2*n)+1] + pSrcA[(2*n)+1] * pSrcB[(2*n)+0];
}
用代數式來表示復數乘法:
(a+bi)*(c+di)=(ac -bd)+(ad+bc)i。
20.4.1 函數arm_cmplx_mult_cmplx_f32
函數原型:
void arm_cmplx_mult_cmplx_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於浮點數的復數乘復位。
函數參數:
- 第1個參數是源數據A的地址。
- 第2個參數是源數據B的地址。
- 第3個參數是存儲數組A和數組B乘積地址。
- 第4個參數是要求解的復數個數。
注意事項:
數組pSrcA, pSrcB和pDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據A和B一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pDst里面。
20.4.2 函數arm_cmplx_mult_cmplx_q31
函數原型:
void arm_cmplx_mult_cmplx_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於Q31格式定點數的復數乘復數。
函數參數:
- 第1個參數是源數據A的地址。
- 第2個參數是源數據B的地址。
- 第3個參數是存儲數組A和數組B乘積地址。
- 第4個參數是要求解的復數個數。
注意事項:
- 兩個1.31格式的定點數相乘為2.62,程序中將此結果做了放縮,此函數的最終結果轉換后為3.29。
- 數組pSrcA, pSrcB和pDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據A和B一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pDst里面。
20.4.3 函數arm_cmplx_mult_cmplx_q15
函數原型:
void arm_cmplx_mult_cmplx_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t numSamples)
函數描述:
這個函數用於Q15格式定點數的復數乘復數。
函數參數:
- 第1個參數是源數據A的地址。
- 第2個參數是源數據B的地址。
- 第3個參數是存儲數組A和數組B乘積地址。
- 第4個參數是要求解的復數個數。
注意事項:
- 兩個1.15格式的定點數相乘為2.30,程序中將此結果做了放縮,此函數的最終結果轉換后為3.13。
- 數組pSrcA, pSrcB和pDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據A和B一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pDst里面。
20.4.4 使用舉例
程序設計:
/* ********************************************************************************************************* * 函 數 名: DSP_CmplxMult * 功能說明: 復數乘法 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ static void DSP_CmplxMult(void) { uint8_t i; float32_t pSrcA[10] = {1.1f, 1.2f, 2.1f, 2.2f, 3.1f, 3.2f, 4.1f, 4.2f, 5.1f, 5.2f}; float32_t pSrcB[10] = {1.2f, 1.2f, 2.2f, 2.2f, 3.2f, 3.2f, 4.2f, 4.2f, 5.2f, 5.2f}; float32_t pDst[10]; q31_t pSrcA1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456, 4*268435456, 4*268435456, 5*268435456, 5*268435456}; q31_t pSrcB1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456, 4*268435456, 4*268435456, 5*268435456, 5*268435456}; q31_t pDst1[10]; q15_t pSrcA2[10] = {5000, 10000, 15000, 20000, 25000, 5000, 10000, 15000, 20000, 25000}; q15_t pSrcB2[10] = {6000, 11000, 15000, 20000, 25000, 5000, 10000, 15000, 20000, 25000}; q15_t pDst2[10]; /***浮點數乘法*******************************************************************************/ arm_cmplx_mult_cmplx_f32(pSrcA, pSrcB, pDst, 5); for(i = 0; i < 5; i++) { printf("pDst[%d] = %f %fj\r\n", i, pDst[2*i], pDst[2*i+1]); } /***定點數乘法Q31*******************************************************************************/ arm_cmplx_mult_cmplx_q31(pSrcA1, pSrcB1, pDst1, 5); for(i = 0; i < 5; i++) { printf("pDst1[%d] = %d %dj\r\n", i, pDst1[2*i], pDst1[2*i+1]); } /***定點數乘法Q15*******************************************************************************/ arm_cmplx_mult_cmplx_q15(pSrcA2, pSrcB2, pDst2, 5); for(i = 0; i < 5; i++) { printf("pDst1[%d] = %d %dj\r\n", i, pDst2[2*i], pDst2[2*i+1]); } }
實驗現象(按下K2按鍵后串口打印復數乘法):
20.5 復數乘實數(ComplexMultReal)
這部分函數用於復數乘實數,公式描述如下:
for(n=0; n<numSamples; n++) {
pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n];
pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n];
}
用代數式來表示復數乘法:
a*(c+di)=ac+adi。
20.5.1 函數arm_cmplx_mult_real_f32
函數原型:
void arm_cmplx_mult_real_f32(
const float32_t * pSrcCmplx,
const float32_t * pSrcReal,
float32_t * pCmplxDst,
uint32_t numSamples)
函數描述:
這個函數用於浮點數的復數乘實數。
函數參數:
- 第1個參數是復數的源地址。
- 第2個參數是實數的源地址。
- 第3個參數是復數和實數乘積地址。
- 第4個參數是要進行復數乘實數的個數。
注意事項:
- 數組pSrcCmplx和pCmplxDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據pSrcCmplx一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pCmplxDst里面。
20.5.2 函數arm_cmplx_mult_real_q31
函數原型:
void arm_cmplx_mult_real_q31(
const q31_t * pSrcCmplx,
const q31_t * pSrcReal,
q31_t * pCmplxDst,
uint32_t numSamples)
函數描述:
這個函數用於Q31格式定點數的復數乘實數。
函數參數:
- 第1個參數是復數的源地址。
- 第2個參數是實數的源地址。
- 第3個參數是復數和實數乘積地址。
- 第4個參數是要進行復數乘實數的個數。
注意事項:
- 輸出結果做了飽和運算,輸出范圍[0x80000000 0x7FFFFFFF]。
- 數組pSrcCmplx和pCmplxDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據pSrcCmplx一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pCmplxDst里面。
20.5.3 函數arm_cmplx_mult_real_q15
函數原型:
void arm_cmplx_mult_real_q15(
const q15_t * pSrcCmplx,
const q15_t * pSrcReal,
q15_t * pCmplxDst,
uint32_t numSamples)
函數描述:
這個函數用於Q15格式定點數的復數乘實數。
函數參數:
- 第1個參數是復數的源地址。
- 第2個參數是實數的源地址。
- 第3個參數是復數和實數乘積地址。
- 第4個參數是要進行復數乘實數的個數。
注意事項:
- 輸出結果做了飽和運算,輸出范圍[0x8000 0x7FFF]。
- 數組pSrcCmplx和pCmplxDst中存儲的數據格式是(實部,虛部,實部,虛部……………),源數據pSrcCmplx一定要按照這個順序存儲數據,比如數據1-j,j,2+3j這個三個數在數組中的存儲格式就是:pSrc[6] = {1, -1, 0, 1, 2, 3}(注意第三個數據是0)。而乘積的結果存到pCmplxDst里面。
20.5.4 使用舉例
程序設計:
/* ********************************************************************************************************* * 函 數 名: DSP_CmplxMultReal * 功能說明: 復數乘實數 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ static void DSP_CmplxMultReal(void) { uint8_t i; float32_t pSrcCmplx[10] = {1.1f, 1.2f, 2.1f, 2.2f, 3.1f, 3.2f, 4.1f, 4.2f, 5.1f, 5.2f}; float32_t pSrcReal[5] = {1.2f, 1.2f, 2.2f, 2.2f, 3.2f}; float32_t pCmplxDst[10]; q31_t pSrcCmplx1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456, 3*268435456, 4*268435456, 4*268435456, 5*268435456, 5*268435456}; q31_t pSrcReal1[10] = {1*268435456, 1*268435456, 2*268435456, 2*268435456, 3*268435456}; q31_t pCmplxDst1[10]; q15_t pSrcCmplx2[10] = {14000, 16000, 20000, 20000, 30000, 31000, 12000, 13000, 14000, 25000}; q15_t pSrcReal2[10] = {15000, 17000, 20000, 20000, 30000}; q15_t pCmplxDst2[10]; /***浮點數*******************************************************************************/ arm_cmplx_mult_cmplx_f32(pSrcCmplx, pSrcReal, pCmplxDst, 5); for(i = 0; i < 5; i++) { printf("pCmplxDst[%d] = %f %fj\r\n", i, pCmplxDst[2*i], pCmplxDst[2*i+1]); } /***定點數Q31*******************************************************************************/ arm_cmplx_mult_cmplx_q31(pSrcCmplx1, pSrcReal1, pCmplxDst1, 5); for(i = 0; i < 5; i++) { printf("pCmplxDst1[%d] = %d %dj\r\n", i, pCmplxDst1[2*i], pCmplxDst1[2*i+1]); } /***定點數Q15*******************************************************************************/ arm_cmplx_mult_cmplx_q15(pSrcCmplx2, pSrcReal2, pCmplxDst2, 5); for(i = 0; i < 5; i++) { printf("pCmplxDst2[%d] = %d %dj\r\n", i, pCmplxDst2[2*i], pCmplxDst2[2*i+1]); } }
實驗現象(按下K3按鍵后串口打印實數乘復數):
20.6 實驗例程說明(MDK)
配套例子:
V6-215_DSP復數運算(模平方,復數乘復數和復數乘實數)
實驗目的:
- 學習DSP復數運算(模平方,復數乘復數和復數乘實數)
實驗內容:
- 啟動一個自動重裝軟件定時器,每100ms翻轉一次LED2。
- 按下按鍵K1,串口打函數DSP_MagSquared的輸出數據。
- 按下按鍵K2,串口打函數DSP_CmplxMult的輸出數據。
- 按下按鍵K3,串口打函數DSP_CmplxMultReal的輸出數據。
使用AC6注意事項
特別注意附件章節C的問題
上電后串口打印的信息:
波特率 115200,數據位 8,奇偶校驗位無,停止位 1。
詳見本章的3.4 4.4,5.4小節。
程序設計:
系統棧大小分配:
硬件外設初始化
硬件外設的初始化是在 bsp.c 文件實現:
/* ********************************************************************************************************* * 函 數 名: bsp_Init * 功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ void bsp_Init(void) { /* STM32F407 HAL 庫初始化,此時系統用的還是F407自帶的16MHz,HSI時鍾: - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。 - 設置NVIV優先級分組為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,串口打函數DSP_MagSquared的輸出數據。
- 按下按鍵K2,串口打函數DSP_CmplxMult的輸出數據。
- 按下按鍵K3,串口打函數DSP_CmplxMultReal的輸出數據。
/* ********************************************************************************************************* * 函 數 名: main * 功能說明: c程序入口 * 形 參: 無 * 返 回 值: 錯誤代碼(無需處理) ********************************************************************************************************* */ int main(void) { uint8_t ucKeyCode; /* 按鍵代碼 */ bsp_Init(); /* 硬件初始化 */ PrintfLogo(); /* 打印例程信息到串口1 */ PrintfHelp(); /* 打印操作提示信息 */ bsp_StartAutoTimer(0, 100); /* 啟動1個100ms的自動重裝的定時器 */ /* 進入主程序循環體 */ 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鍵按下,求模平方 */ DSP_MagSquared(); break; case KEY_DOWN_K2: /* K2鍵按下,求復數乘復數 */ DSP_CmplxMult(); break; case KEY_DOWN_K3: /* K3鍵按下,求復數乘實數 */ DSP_CmplxMultReal(); break; default: /* 其他的鍵值不處理 */ break; } } } }
20.7 實驗例程說明(IAR)
配套例子:
V6-215_DSP復數運算(模平方,復數乘復數和復數乘實數)
實驗目的:
- 學習DSP復數運算(模平方,復數乘復數和復數乘實數)
實驗內容:
- 啟動一個自動重裝軟件定時器,每100ms翻轉一次LED2。
- 按下按鍵K1,串口打函數DSP_MagSquared的輸出數據。
- 按下按鍵K2,串口打函數DSP_CmplxMult的輸出數據。
- 按下按鍵K3,串口打函數DSP_CmplxMultReal的輸出數據。
上電后串口打印的信息:
波特率 115200,數據位 8,奇偶校驗位無,停止位 1。
詳見本章的3.4 4.4,5.4小節。
程序設計:
系統棧大小分配:
硬件外設初始化
硬件外設的初始化是在 bsp.c 文件實現:
/* ********************************************************************************************************* * 函 數 名: bsp_Init * 功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次 * 形 參:無 * 返 回 值: 無 ********************************************************************************************************* */ void bsp_Init(void) { /* STM32F407 HAL 庫初始化,此時系統用的還是F407自帶的16MHz,HSI時鍾: - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。 - 設置NVIV優先級分組為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,串口打函數DSP_MagSquared的輸出數據。
- 按下按鍵K2,串口打函數DSP_CmplxMult的輸出數據。
- 按下按鍵K3,串口打函數DSP_CmplxMultReal的輸出數據。
/* ********************************************************************************************************* * 函 數 名: main * 功能說明: c程序入口 * 形 參: 無 * 返 回 值: 錯誤代碼(無需處理) ********************************************************************************************************* */ int main(void) { uint8_t ucKeyCode; /* 按鍵代碼 */ bsp_Init(); /* 硬件初始化 */ PrintfLogo(); /* 打印例程信息到串口1 */ PrintfHelp(); /* 打印操作提示信息 */ bsp_StartAutoTimer(0, 100); /* 啟動1個100ms的自動重裝的定時器 */ /* 進入主程序循環體 */ 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鍵按下,求模平方 */ DSP_MagSquared(); break; case KEY_DOWN_K2: /* K2鍵按下,求復數乘復數 */ DSP_CmplxMult(); break; case KEY_DOWN_K3: /* K3鍵按下,求復數乘實數 */ DSP_CmplxMultReal(); break; default: /* 其他的鍵值不處理 */ break; } } } }
20.8 總結
本期教程就跟大家講這么多,有興趣的可以深入研究下算法的具體實現。