很难理解为什么 DSP 低通滤波器在 M4 上工作不再在 M7 上工作。
我最近从STM32L432KC切换到STM32H753ZI。
除了从 L4 切换到 H7 之外,我还在使用P2MODI2S2和 H7,而不是像使用 L4 时那样使用内部 ADC。
唯一想到的是采样率的差异。我在 L4 上使用 44.410kHz 采样率,现在我在使用 PMODI2S2 的 H7 上使用 96kHz 采样率。所以我重新做了离散函数并输入了新的 IIR 系数并且没有雪茄。
使用带有 PMODI2S2 的 H7 作为直通:
代码:
#define ARM_MATH_CM7
#include "main.h"
#include "arm_math.h"
void init_Clock(void);
void init_I2S(void);
void init_Debugging(void);
void init_Interrupt(void);
void init_SpeedTest(void);
uint32_t RxBuff[4];
uint32_t TxBuff[4];
uint8_t TC_Callback = 0;
uint8_t HC_Callback = 0;
char uartBuff[8];
float iir_coeffs[5] = {0.00102, 0.002041, 0.00102, 1.908, -0.9116}; //B0, B1, B2, A1, A2
float iir_mono_state[4];
float Rx_Buff_f[8];
float Rx_Buff_f_out[8];
arm_biquad_casd_df1_inst_f32 monoChannel;
void DMA1_Stream0_IRQHandler(void) {
if (((DMA1 -> LISR) & (DMA_LISR_TCIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CTCIF0;
TC_Callback = 1;
}
else if (((DMA1 -> LISR) & (DMA_LISR_HTIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CHTIF0;
HC_Callback = 1;
}
}
int main(void) {
init_Clock();
init_I2S();
//init_Debugging();
init_Interrupt();
//init_SpeedTest();
arm_biquad_cascade_df1_init_f32(&monoChannel, 1, iir_coeffs, iir_mono_state);
while (1)
{
if (HC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BS3_HIGH;
for (int i = 0; i < 2; i++){
TxBuff[i] = RxBuff[i];
}
HC_Callback = 0;
} else if (TC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BR3_LOW;
for (int i = 2; i < 4; i++){
TxBuff[i] = RxBuff[i];
}
TC_Callback = 0;
}
}
}
H7 与 PMODI2S2 与 IIR 系数使用 96kHz 采样率:
代码:
#define ARM_MATH_CM7
#include "main.h"
#include "arm_math.h"
void init_Clock(void);
void init_I2S(void);
void init_Debugging(void);
void init_Interrupt(void);
void init_SpeedTest(void);
uint32_t RxBuff[4];
uint32_t TxBuff[4];
uint8_t TC_Callback = 0;
uint8_t HC_Callback = 0;
char uartBuff[8];
float iir_coeffs[5] = {0.00102, 0.002041, 0.00102, 1.908, -0.9116}; //B0, B1, B2, A1, A2
float iir_mono_state[4];
float Rx_Buff_f[8];
float Rx_Buff_f_out[8];
arm_biquad_casd_df1_inst_f32 monoChannel;
void DMA1_Stream0_IRQHandler(void) {
if (((DMA1 -> LISR) & (DMA_LISR_TCIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CTCIF0;
TC_Callback = 1;
}
else if (((DMA1 -> LISR) & (DMA_LISR_HTIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CHTIF0;
HC_Callback = 1;
}
}
int main(void) {
init_Clock();
init_I2S();
//init_Debugging();
init_Interrupt();
//init_SpeedTest();
arm_biquad_cascade_df1_init_f32(&monoChannel, 1, iir_coeffs, iir_mono_state);
while (1)
{
if (HC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BS3_HIGH;
for (int i = 0; i < 2; i++){
Rx_Buff_f[i] = (float)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, Rx_Buff_f, Rx_Buff_f_out, 2);
for (int i = 0; i < 2; i++){
TxBuff[i] = (uint32_t)Rx_Buff_f_out[i];
}
HC_Callback = 0;
} else if (TC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BR3_LOW;
for (int i = 2; i < 4; i++){
Rx_Buff_f[i] = (float)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, &Rx_Buff_f[2], &Rx_Buff_f_out[2], 2);
for (int i = 2; i < 4; i++){
TxBuff[i] = (uint32_t)Rx_Buff_f_out[i];
}
TC_Callback = 0;
}
}
}
所以我心想,因为我使用的是 I2S 协议,并且由于它的立体声,我尝试使用 192kHz 的采样率来看看会发生什么:
代码:
#define ARM_MATH_CM7
#include "main.h"
#include "arm_math.h"
void init_Clock(void);
void init_I2S(void);
void init_Debugging(void);
void init_Interrupt(void);
void init_SpeedTest(void);
uint32_t RxBuff[4];
uint32_t TxBuff[4];
uint8_t TC_Callback = 0;
uint8_t HC_Callback = 0;
char uartBuff[8];
float iir_coeffs[5] = {0.0002507, 0.0005013, 0.0002507, 1.955, -0.9557}; //B0, B1, B2, A1, A2
float iir_mono_state[4];
float Rx_Buff_f[8];
float Rx_Buff_f_out[8];
arm_biquad_casd_df1_inst_f32 monoChannel;
void DMA1_Stream0_IRQHandler(void) {
if (((DMA1 -> LISR) & (DMA_LISR_TCIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CTCIF0;
TC_Callback = 1;
}
else if (((DMA1 -> LISR) & (DMA_LISR_HTIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CHTIF0;
HC_Callback = 1;
}
}
int main(void) {
init_Clock();
init_I2S();
//init_Debugging();
init_Interrupt();
//init_SpeedTest();
arm_biquad_cascade_df1_init_f32(&monoChannel, 1, iir_coeffs, iir_mono_state);
while (1)
{
if (HC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BS3_HIGH;
for (int i = 0; i < 2; i++){
Rx_Buff_f[i] = (float)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, Rx_Buff_f, Rx_Buff_f_out, 2);
for (int i = 0; i < 2; i++){
TxBuff[i] = (uint32_t)Rx_Buff_f_out[i];
}
HC_Callback = 0;
} else if (TC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BR3_LOW;
for (int i = 2; i < 4; i++){
Rx_Buff_f[i] = (float)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, &Rx_Buff_f[2], &Rx_Buff_f_out[2], 2);
for (int i = 2; i < 4; i++){
TxBuff[i] = (uint32_t)Rx_Buff_f_out[i];
}
TC_Callback = 0;
}
}
}
有任何想法吗?我不确定它是 M7 还是有问题的外围设备。这是在L4上工作的,没问题。
更新 1:我在调试器模式下记录了变量以查看发生了什么。我拍了三张照片。第一次迭代是索引 0-2,第二次迭代是 2-4,第三张图片是之后的多次迭代。
我注意到的是 RxBuffer 和 RxBuffer_f 不同步。我还注意到,经过多次迭代,RxBuffer_f_out 只是变成了类似 int 的数据类型,不再包含任何类型的小数。
更新 2:
我还注意到我正在使用一个 I2S 设备来输出立体声音频,我可能没有将系数正确地添加到缓冲区中。我的意思是,当缓冲区进入时,我是否需要调整缓冲区,比如对它们进行位移或任何类似的事情?关于 PMODI2S2,我唯一知道的是,我相信它会在 32 个数据帧中输出 24 位,所以我假设它用零填充,为什么不填充。
更新 3:
在放入 TxBuffer 之前只是将 RxBuffer 相乘,它所做的是增加信号的 PK - PK,但是增加它更多会导致:
将 RxBuffer 乘以 2^0(直通)
将 RxBuffer 乘以 2^1
将 RxBuffer 乘以 2^2
最后一张图片看起来像我遇到的问题,这可能是溢出问题吗?
更新 4:
在与一位关心的公民交谈时,他提到 I2S 协议是一个 2 的补码数据编码。我知道 2 的补码是什么,但我不确定 TxBuff 或 Rxbuff 是否需要补码。无论如何,我将 TxBuff 和 Rxbuff 的数据类型都更改为 int32_t 数据类型,但问题仍然存在。
更新 5:尝试使用 2 的补码或只是将其转换为 int32_t。没运气。
代码:
#define ARM_MATH_CM7
#include "main.h"
#include "arm_math.h"
void init_Clock(void);
void init_I2S(void);
void init_Debugging(void);
void init_Interrupt(void);
void init_SpeedTest(void);
int32_t RxBuff[4];
int32_t TxBuff[4];
uint8_t TC_Callback = 0;
uint8_t HC_Callback = 0;
char uartBuff[8];
float32_t iir_coeffs[5] = {0.00102, 0.002041, 0.00102, 1.908, -0.9116}; //B0, B1, B2, A1, A2
float32_t iir_mono_state[4];
float32_t Rx_Buff_f[4];
float32_t Rx_Buff_f_out[4];
arm_biquad_casd_df1_inst_f32 monoChannel;
void DMA1_Stream0_IRQHandler(void) {
if (((DMA1 -> LISR) & (DMA_LISR_TCIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CTCIF0;
TC_Callback = 1;
}
else if (((DMA1 -> LISR) & (DMA_LISR_HTIF0)) != 0){
DMA1 -> LIFCR |= DMA_LIFCR_CHTIF0;
HC_Callback = 1;
}
}
int main(void) {
init_Clock();
init_I2S();
//init_Debugging();
init_Interrupt();
//init_SpeedTest();
arm_biquad_cascade_df1_init_f32(&monoChannel, 1, iir_coeffs, iir_mono_state);
while (1)
{
if (HC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BS3_HIGH;
for (int i = 0; i < 2; i++){
Rx_Buff_f[i] = (float32_t)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, Rx_Buff_f, Rx_Buff_f_out, 2);
for (int i = 0; i < 2; i++){
TxBuff[i] = Rx_Buff_f_out[i];
}
HC_Callback = 0;
} else if (TC_Callback == 1){
// GPIOA->BSRR |= GPIO_BSRR_BR3_LOW;
for (int i = 2; i < 4; i++){
Rx_Buff_f[i] = (float32_t)RxBuff[i];
}
arm_biquad_cascade_df1_f32(&monoChannel, &Rx_Buff_f[2], &Rx_Buff_f_out[2], 2);
for (int i = 2; i < 4; i++){
TxBuff[i] = Rx_Buff_f_out[i];
}
TC_Callback = 0;
}
}
}








