bqgup

  • 2020-08-04
  • 发表了主题帖: 音频信号单回声效果处理

    本帖最后由 bqgup 于 2020-8-4 18:05 编辑 # 音频信号单回声效果处理 ## 一、回声信号原理 #### 声音信号在传播过程中,遇到障碍物体时,一部分声能会被吸收,另一部分则会被反射回来,且可以被人耳听到,这种由声波的反射引起声音的重复就叫做回声。单回声是由原始声音单次反射形成的,多回声则是由多次单回声叠加而成。有时我们对着山谷大喊,山谷另一头有回应,这就是回声的现象。实际中,声音在传播过程中会有能量的损耗,所以我们每次听到的回声声音都在减弱,并且存在延时,这些就是回声的大概原理。 ## 二、回声算法设计 ### 2.1 音频信号 #### 获取一端上个帖子讲过的音频文件,上个帖子的链接->[音频的左右声道信号差异探究](http://bbs.eeworld.com.cn/thread-1133721-1-1.html "音频的左右声道信号差异探究")

  • 2020-07-23
  • 回复了主题帖: 音频的左右声道信号差异探究

    littleshrimp 发表于 2020-7-22 20:56 左耳声大 右耳设声小 音质一般 使用软件提取视频文件音频效果是不是会更好一点
    您说的有道理,帖子中的音频是我用手机录音机录下来的,在声音提取中可能就引入了音量大小上的差异。

  • 2020-07-22
  • 发表了主题帖: 音频的左右声道信号差异探究

    本帖最后由 bqgup 于 2020-7-22 16:53 编辑 # 音频的左右声道信号差异探究 ## 一、获取音频 #### 通过智能设备获取一段电影《扫毒》中经典的音频——“段坤我吃定了”, ``` [y,Fs] = audioread('E:\8、matlab\回声变声处理\段坤我吃定了音频.mp3'); ``` #### 在MATLAB中运行后,结果显示如下: #### 其中,Fs代表采样率,为44100Hz,在信号的处理过程中,要想保持信号不失真,采样时就要满足奈奎斯特抽样定理,说的简单点,人说话的频率范围为300Hz-3400Hz,音频信号色频率范围为20Hz-20000Hz,我们日常音频信号的频率也就在20Hz-20000Hz,最大频率20000Hz,奈奎斯特采样定理就是采样频率至少要是最大频率的2倍,也就是说采样频率为 #### Fs=2*20000Hz=40000Hz, #### 实际采样过程中会有一定的冗余量,抽样定理就是这个意思。现在这个Fs的结果也就一目了然了;结果生成的y是个46425行2列的数组,这个两列分别代表左右声道,第一列就是左声道,第二列是右声道,46425表示在FS的采样率下这段音频的数据点数。 #### 通过命令可以听一下音频的质量,通过电脑播放。 ``` sound(y,Fs) ``` #### 如果改变Fs的大小,将会使声音发生变化,自己可以实验一下。 #### 为了处理掉音频的开头和结尾一些不需要的音频,我们可以通过命令将音频剪辑: ``` [y,Fs] = audioread('E:\8、matlab\回声变声处理\段坤我吃定了音频.mp3',[1000,420000]); ``` #### 剪辑完可以看出数据长度的确变小了一些: #### 下面通过命令将剪辑后的音频保存到文件夹下: ``` audiowrite('E:\8、matlab\回声变声处理\段坤我吃定了截取.wav',y,Fs) ``` #### 文件夹下多了一个新命名的音频文件: ## 二、左右声道信号差异 #### 我试听了一下左右声道的声音,感觉没什么不一样,只能看一下左右声道信号的细节了。我们就对截取后的音频直接处理。 ### 2.1时域探究 ``` %%%% 音频信号左右声道信号处理 %%%% function Audio_LR_Pro() [y,Fs] = audioread('E:\8、matlab\回声变声处理\段坤我吃定了截取.wav'); Length = length(y);     %% 信号长度 y_left = y(:,1);        %% 左声道信号 y_right = y(:,2);       %% 右声道信号 m = 1 : 1 : Length; subplot(211); plot(m/Fs,y_left); title('左声道时域变化'); xlabel('t'); ylabel('y_left') subplot(212); plot(m/Fs,y_right); title('右声道时域变化'); xlabel('t'); ylabel('y_right') ``` #### 时域对比结果如下: ### 频域探究 ``` %%%% 音频信号左右声道信号处理 %%%% function Audio_LR_Pro_Freq() [y,Fs] = audioread('E:\8、matlab\回声变声处理\段坤我吃定了截取.wav'); Length = length(y);     %% 信号长度 y_left = y(:,1);        %% 左声道信号 y_right = y(:,2);       %% 右声道信号 m = 1 : 1 : Length; subplot(211); plot((m-1)*Fs/Length,abs(fft(y_left))); title('左声道频域变化'); xlabel('f'); ylabel('A_y_left') subplot(212); plot((m-1)*Fs/Length,abs(fft(y_right))); title('右声道频域变化'); xlabel('f'); ylabel('A_y_right') ``` #### 频域结果对比如下图: #### 还要从哪些方面看差异呢???

  • 回复了主题帖: MATLAB读取txt文件数据与处理

    宋元浩 发表于 2020-7-21 21:56 读写操作文件,matlab没有标准read write接口?
    有标准的命令函数接口

  • 回复了主题帖: MATLAB读取txt文件数据与处理

    freebsder 发表于 2020-7-21 20:16 应该是比较常用的操作吧。
    是的是的,

  • 2020-07-21
  • 回复了主题帖: 请求大神帮忙分析一下这个三极管电路?这是并联电压负反馈还是并联电流负反馈?

    已经证实,电路为并联电压负反馈

  • 发表了主题帖: MATLAB读取txt文件数据与处理

    # MATLAB读取txt文件数据与处理 ## 一、获取txt文件原始数据 #### 利用串口接收到的数据保存为txt格式的文件,保存到PC端的文件夹下: #### E:\8、matlab\matlab读取txt文件数据 #### txt文件内容如下: #### 在MATLAB命令行输入下列代码即可将txt文件内容读取了 ``` TXT = textread('E:\8、matlab\matlab读取txt文件数据\raw_data.txt');%%读取到TXT ``` ## 二、对txt文件中的数据进行图形显示 #### 编写运行程序 ``` %%%% txt文件数据读取与处理 %%%% function Txt_Raw_data() TXT = textread('E:\8、matlab\matlab读取txt文件数据\raw_data.txt')%%读取到TXT Length = length(TXT);%%计算长度 m = 1:1:Length;      %%描点 plot(m,TXT)          %%画图 ``` #### 保存脚本文件后,将其添加到路径,点击下图中的运行 #### 图形结果就显示出来了: #### 在图形中,可以使用数据点观察图形上具体某一点的值。

  • 2020-06-10
  • 回复了主题帖: ESP8266WiFi模块(物联网开关)测试(AP模式)

    liushiming82 发表于 2020-6-8 20:51 楼主,能分享一下手机上的软件呀,谢谢
    好的,在网盘里,你下载一下吧。 链接:https://pan.baidu.com/s/1M8YSQ3cnOgRpzs3OP7ot1w  提取码:ff1q

  • 2020-05-20
  • 回复了主题帖: 互相关法求时延

    Smile丶 发表于 2020-5-18 14:10 大佬,请问最后phy的计算结果代表的是什么意思
    相位差

  • 2020-04-10
  • 回复了主题帖: STM32圆形遥控器——基础篇

    pcf2000 发表于 2020-4-9 17:15 有NRF24L01无线收发模块的例代码吗?
    有,快更新了

  • 2020-04-09
  • 发表了主题帖: STM32圆形遥控器——基础篇

    # STM32圆形遥控器——基础篇 #### 年前做了5块多功能STM32圆形mini遥控器PCB板,发过一次帖子分享了板子的工程图文件和实物图。现在时间充足,再和大家分享一下分别控制板子的程序。 # STM32圆形遥控器硬件 #### 上次分享了板子工程,有需要的话请大家找找去发工厂做板。 #### [DIY多功能STM32迷你遥控器(附工程文件,可直接做板使用)](http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1107415&fromuid=1014845 "DIY多功能STM32迷你遥控器(附工程文件,可直接做板使用)") #### STM32圆形遥控器上集成了STM32核心板,核心板STM32C8T6的原理图如下: #### #### 为什么直接用核心板呢?主要是懒,为了缩短研发周期,不用花功夫在PCB上,不用花功夫焊接芯片;芯片烧了可以直接换下来;当然也付出了价格略贵、占用空间大的代价。板子上还集成了稳压电源模块、NRF24L01无线收发模块、摇杆控制模块、OLED显示屏、按键、蜂鸣器、蓝牙等。 #### 程序下载方式采用SWD四线下载。原理图如下: #### # stm32圆形遥控器_蜂鸣器+OLED测试 ``` int main(void) {                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断优先级分组2         delay_init();                                                             //延时函数初始化                uart_init(115200);                                                         //默认串口1初始化为115200         JTAG_Set(JTAG_SWD_DISABLE);                                        //关闭JTAG接口         JTAG_Set(SWD_ENABLE);                                                //使能SWD接口         Buzzer_Init();                                                                //蜂鸣器初始化         LED_Init();                                                                        //LED初始化         OLED_Init();                                                                //初始化OLED //  NRF24L01_init();                                                //初始化NRF24L01         ADC1_GPIO_Config();                                              //初始化ADC IO                ADC1_Mode_Config();                                              //初始化ADC模式                                                                                                        //        KEY_Init();                                                                        //按键初始化                System_Start();                                                                //系统启动,蜂鸣器~滴~ //        TIM3_Int_Init(999,71);                                                //1ms定时器中断         while(1)         {                 OLED_ShowCHinese(0,0,0);                                //中                 OLED_ShowCHinese(18,0,1);                                //景                 OLED_ShowCHinese(36,0,2);                                //园                 OLED_ShowCHinese(54,0,3);                                //电                 OLED_ShowCHinese(72,0,4);                                //子                 OLED_ShowCHinese(90,0,5);                                //科                 OLED_ShowCHinese(108,0,6);                                //技                 OLED_ShowString(0,3,"0.96' OLED TEST");                 OLED_ShowString(20,6,"2020/04/09");                              }          } ``` #### 开机上电时遥控器会先发出一声“滴”,然后开始往下执行。执行结果如下: #### 程序与预期结果相符合,完整工程如下: #### # stm32圆形遥控器_定时器+LED测试 ```c int main(void) {                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组2         delay_init();                                                     //延时函数初始化                uart_init(115200);                                                 //默认串口1初始化为115200         JTAG_Set(JTAG_SWD_DISABLE);                                //关闭JTAG接口         JTAG_Set(SWD_ENABLE);                                        //使能SWD接口         Buzzer_Init();                                                        //蜂鸣器初始化         LED_Init();                                                                //LED初始化         OLED_Init();                                                        //初始化OLED //  NRF24L01_init();                                        //初始化NRF24L01         ADC1_GPIO_Config();                                      //初始化ADC IO                ADC1_Mode_Config();                                      //初始化ADC模式                                                                                                        //        KEY_Init();                                                                //按键初始化                System_Start();                                                        //系统启动,蜂鸣器~滴~         TIM3_Int_Init(999,71);                                        //1ms定时器中断 //        RC_INIT();         while(1)         {                 OLED_ShowCHinese(0,0,0);                                //中                 OLED_ShowCHinese(18,0,1);                                //景                 OLED_ShowCHinese(36,0,2);                                //园                 OLED_ShowCHinese(54,0,3);                                //电                 OLED_ShowCHinese(72,0,4);                                //子                 OLED_ShowCHinese(90,0,5);                                //科                 OLED_ShowCHinese(108,0,6);                                //技                 OLED_ShowString(0,3,"0.96' OLED TEST");                 OLED_ShowString(20,6,"2020/04/09");                              }          } ``` #### 中断服务函数如下: ```c void TIM3_IRQHandler(void)   //TIM3中断 {         static u16 i;         if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)         //检查指定的TIM中断发生与否:TIM 中断源         {                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);         //清除TIMx的中断待处理位:TIM 中断源                                 i++;                 if(i > 999)                 {                         i = 0;                         LED1 = ~LED1;                         LED2 = ~LED2;                         LED3 = ~LED3;                 }                         } } ``` #### LED灯一秒反转一次。动态效果图就不展示了。下面附上工程: #### # stm32圆形遥控器_按键测试 ```c //注意此函数有响应优先级,KEY0>KEY1>WK_UP!! /********************************************************************************************** *函数原型:u8 KEY_Scan(u8 mode) *函数功能:按键处理函数 *函数参数:mode:0,不支持连续按;1,支持连续按; *返 回 值: 0,没有任何按键按下;S1_PRES,S1按下;S2_PRES,S2按下 *函数作者:bqgup *完成日期:2017/12/14 *备    注: 注意此函数有响应优先级,S1>S2 **********************************************************************************************/ u8 KEY_Scan(u8 mode) {                  static u8 key_up=1;//按键按松开标志         if(mode)key_up=1;  //支持连按                if(key_up&&(K1==0||K2==0||K3==0||K4==0||KEY_LEFT==0||KEY_RIGHT==0))         {                 delay_ms(10);//去抖动                 key_up=0;                 if(K1==0)return K1_PRES;                 else if(K2==0)return K2_PRES;                 else if(K3==0)return K3_PRES;                 else if(K4==0)return K4_PRES;                 else if(KEY_LEFT==0)return KEY_LEFT_PRES;                 else if(KEY_RIGHT==0)return KEY_RIGHT_PRES;         }else if(K1==1&&K2==1&&K3==1&&K4==1&&KEY_LEFT==1&&KEY_RIGHT==1)key_up=1;                       return 0;// 无按键按下 } ``` ```c int main(void) {                u8 key_sta;                                                                                        //按键状态         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                //设置中断优先级分组2         delay_init();                                                                             //延时函数初始化                uart_init(115200);                                                                         //默认串口1初始化为115200         JTAG_Set(JTAG_SWD_DISABLE);                                                        //关闭JTAG接口         JTAG_Set(SWD_ENABLE);                                                                //使能SWD接口         Buzzer_Init();                                                                                //蜂鸣器初始化         LED_Init();                                                                                        //LED初始化         KEY_Init();                                                                                        //按键初始化                OLED_Init();                                                                                //初始化OLED //  NRF24L01_init();                                                                //初始化NRF24L01         ADC1_GPIO_Config();                                                              //初始化ADC IO                ADC1_Mode_Config();                                                              //初始化ADC模式                                                                                                                //校准摇杆数据初始化                 System_Start();                                                                                //系统启动,蜂鸣器~滴~         TIM3_Int_Init(999,71);                                                                //1ms定时器中断 //        RC_INIT();         while(1)         {                 key_sta = KEY_Scan(1);                                                        //得到键值                 OLED_ShowNum(0,0,key_sta,2,16);                                        //支持连续按                 if(key_sta)                 {                         if(1 == key_sta)                         {                                 LED2 = 0;                         }                                                 else if(2 == key_sta)                         {                                 LED2 = 1;                         }                                                 else if(3 == key_sta)                         {                                 LED3 = 0;                         }                                                 else if(4 == key_sta)                         {                                 LED3 = 1;                         }                 }                                 OLED_ShowString(0,3,"0.96' OLED TEST");                 OLED_ShowString(20,6,"2020/04/09");                              }          } ``` #### 按键函数支持连按和不连按,根据个人需要改变函数参数,本次测试测试按键是否起作用,规定的按键按下LED会实现规定的亮灭,键值会显示在OLED显示屏上。 #### 简短的显示一下测试效果,下面附上文件工程: #### # stm32圆形遥控器_串口测试 ```c /********************************************************************************************** * 函数原型:void Usart_Rec_2MCU(void) * 函数功能:串口接收数据给单片机 * 函数参数:无 * 函数作者:bqgup * 完成时间:2017.12.29   00:14 * 备    注;通过串口调试助手或者外部蓝牙设备发送字头一样的字符串均可被单片机                    接收,并按照一定方式译码 **********************************************************************************************/ void Usart_Rec_2MCU(void) {         u8 t;                 u8 len;         if(USART_RX_STA&0x8000)                                                                                                //接收中断到来         {                                                           len=USART_RX_STA&0x3fff;                                                                                //得到此次接收到的数据长度                                 for(t=0;tDR=USART_RX_BUF[t];                                                 if('S' == USART_RX_BUF[0])                                                                        //字头一级校验                         {                                 if('a' == USART_RX_BUF[1])                                                                //字头二级校验                                 {                                         Rec_data1 = (float)((USART_RX_BUF[2] - '0') * 1000 + (USART_RX_BUF[3] - '0') * 100 +                                                 (USART_RX_BUF[4] - '0') * 10 + (USART_RX_BUF[5] - '0')) / 100.0;                                         USART_RX_BUF[6] = '\0';                                 }                                                                 else if('b' == USART_RX_BUF[1])                                 {                                         Rec_data2 = (float)((USART_RX_BUF[2] - '0') * 1000 + (USART_RX_BUF[3] - '0') * 100 +                                                 (USART_RX_BUF[4] - '0') * 10 + (USART_RX_BUF[5] - '0')) / 100.0;                                         USART_RX_BUF[6] = '\0';                                 }                                                         }                                                         while((USART1->SR&0X40)==0);                                                                //等待发送结束                 }                 printf("\r\n\r\n");                                                                                                //插入换行                                 USART_RX_STA=0;                                                                                                        //状态清零         } } ``` ```c int main(void) {                u8 key_sta;                                                                                        //按键状态         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                //设置中断优先级分组2         delay_init();                                                                             //延时函数初始化                uart_init(115200);                                                                         //默认串口1初始化为115200         JTAG_Set(JTAG_SWD_DISABLE);                                                        //关闭JTAG接口         JTAG_Set(SWD_ENABLE);                                                                //使能SWD接口         Buzzer_Init();                                                                                //蜂鸣器初始化         LED_Init();                                                                                        //LED初始化         KEY_Init();                                                                                        //按键初始化                OLED_Init();                                                                                //初始化OLED //  NRF24L01_init();                                                                //初始化NRF24L01         ADC1_GPIO_Config();                                                              //初始化ADC IO                ADC1_Mode_Config();                                                              //初始化ADC模式                                                                                                                //校准摇杆数据初始化                 System_Start();                                                                                //系统启动,蜂鸣器~滴~         TIM3_Int_Init(999,71);                                                                //1ms定时器中断 //        RC_INIT();         while(1)         {                 Usart_Rec_2MCU();                 OLED_ShowNum(0,0,(int)(Rec_data1*100),5,16);                 OLED_ShowNum(0,3,(int)(Rec_data2*100),5,16);                 OLED_ShowString(20,6,"2020/04/09");                   printf("STM32圆形遥控器\n");                            }          } ``` #### 用USB转TTL工具连接电脑或者直接使用蓝牙,本次测试未使用蓝牙: #### 这时串口调试助手上一直打印字符串: #### 借助串口调试助手向单片机发送数据; #### 显示屏显示,未发送数据时为0: #### 接收到数据时: #### 工程文件如下: ####

  • 2020-04-08
  • 回复了主题帖: Chirp信号的基本原理与应用

    Handsomebj 发表于 2020-4-6 21:18 您好  请问 buffer(i)=((sin(fAngle*2*pi)+1)/2*1279)+256; buffer里存储的是什么呢 不太懂 希 ...
    buffer里面存储的是不同时刻chirp信号的幅度

  • 2020-03-27
  • 发表了主题帖: 离散序列的卷积运算和相关运算的快速傅里叶变换

    # 离散序列的卷积运算和相关运算的快速傅里叶变换 # 离散序列卷积运算与快速傅里叶变换 #### 离散序列信号f(n),g(n)的卷积为: #### 如果直接进行卷积运算,每个f(n)的值都必须与每个g(n)的值相乘,假如f(n)与g(n)的长度相同,也需要进行N的平方次乘法运算,这对处理器的性能有很高的的要求,并且还浪费时间。 ``` %%%% 普通方法求卷积 a = [1 2 3 4];      % 序列1 b = [4 6 8 2];      % 序列2 c = conv(a,b);      % 求两个序列的卷积和 c c =      4    14    32    52    52    38     8 ``` #### 如果将离散卷积改为离散圆卷积,前面帖子有讲:[信号的相关运算及在单片机程序运用中的算法分析(二)](http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1114861&fromuid=1014845 "信号的相关运算及在单片机程序运用中的算法分析(二)") 并借助FFT,可以减少直接卷积的工作量。 #### 大概流程: #### 1、分别求两个序列的傅里叶变换; #### 2、求频域相乘的乘积; #### 3、傅里叶反变换; ``` %%%% FFT求卷积 a = [1 2 3 4];       % 序列1 b = [4 6 8 2];       % 序列2 c = conv(a,b);       % 求两个序列的卷积和 a1 = [1 2 3 4 0 0 0];% 扩充维度与卷积结果的维度一致 b1 = [4 6 8 2 0 0 0];% 扩充维度与卷积结果的维度一致 a_f = fft(a1);       % 序列求傅里叶变换 b_f = fft(b1);       % 序列求傅里叶变换 c_f = a_f .* b_f;    % 频域相乘 C = ifft(c_f);       % 傅里叶反变换 C C =     4.0000   14.0000   32.0000   52.0000   52.0000   38.0000    8.0000 ``` #### 可以发现,普通方法和FFT法求得的c和C的结果是完全相同的,FFT的运算速度更快(这个可以在运算中感受到)。 # 离散序列相关运算与快速傅里叶变换 #### 离散序列信号f(n),g(n)的相关运算为: #### 与卷积运算相比,相关运算少了一个时间反转。 ``` %%%% 普通相关运算 a = [1 2 3 4];        % 序列1 b = [4 6 8 2];        % 序列2 c = xcorr(a,b);       % 求两个序列的相关运算 c c =     2.0000   12.0000   28.0000   48.0000   58.0000   36.0000   16.0000 ``` #### 下面借助FFT算法进行分析: #### 1、对两个序列做傅里叶变换得A(k)、B(k); #### 2、将A(k)、B(k)进行共轭相乘,A(k)B*(k); #### 3、傅里叶反变换; ``` %%%% FFT相关运算 a = [1 2 3 4];        % 序列1 b = [4 6 8 2];        % 序列2 c = xcorr(a,b);       % 求两个序列的相关运算 a1 = [1 2 3 4 0 0 0]; % 扩充维度与相关运算结果的维度一致 b1 = [4 6 8 2 0 0 0]; % 扩充维度与相关运算结果的维度一致 a_f = fft(a1);        % 序列求傅里叶变换 b_f = fft(b1);        % 序列求傅里叶变换 b_F = conj(b_f);      % 取共轭 c_f = a_f .* b_F;     % 频域相乘 C = ifft(c_f);        % 傅里叶反变换 C = fftshift(C);      % 移动零频点到频谱中间 >> C C =     2.0000   12.0000   28.0000   48.0000   58.0000   36.0000   16.0000 ``` #### 经验证,结果相同。 # 结论 #### 运算结果相同的前提下,FFT的运算速度会更快。 # 参考文献 [1]傅晓林.离散卷积和相关运算的快速傅立叶仿真研究[J].重庆交通学院学报,2003(04):76-79.

  • 2020-03-26
  • 回复了主题帖: 互相关法求时延

    littleshrimp 发表于 2020-3-26 11:52 谢谢分享,在玩声源定位吗?
    是的,感觉这个挺有意思的,还望大神指教

  • 发表了主题帖: 互相关法求时延

    # 互相关法求时延 #### 假设已知信号为起始频率为250Hz,终止频率为2000Hz的Chirp信号,接收信号为麦克风利用ADC采集到的在幅度上有一定衰减的Chirp信号。 # 互相关法求时延 ``` %%% 互相关法求时延 %%% N=2048;             % 长度 Fs=10000;           % 采样频率 n=0:N-1; t=n/Fs;             % 时间序列 %% Chirp信号 x = chirp(t,250,0.2047,2000); x = [x,zeros(1,2*N)];                     % 要保证时延在两倍信号长度之内,不然就调整2*N的2 %% 接收到的Chirp信号 ADC1 = 0.78 * chirp(t,250,0.2047,2000);                     % 接收后的信息假设存在幅度衰减 tao = 0.15;         % 延时 Ndelay = fix(tao*Fs);                     % 换算成延时点数 ADC1 = [zeros(1,Ndelay),ADC1,zeros(1,length(x)-Ndelay-length(ADC1))];%,zeros(1,2048)]; %% 互相关函数 [c,lags]=xcorr(x,ADC1);                    % 互相关 subplot(211); xaxis = 1:1:length(x); plot(xaxis,x,'r'); hold on; plot(xaxis,ADC1,':'); legend('x信号', 'ADC1信号'); xlabel('时间/s');ylabel('x(t) ADC1(t)'); title('原始信号');grid on; hold off subplot(212); plot(lags/Fs,c,'r'); title('相关函数'); xlabel('时间(s)');ylabel('Rxadc1'); grid on [Am,Lm]=max(c); d = Lm - (length(c)+1)/2; phy=(2*10*d*180/Fs); phy = rem(phy,360)% 取余360 phy =   -180 Delay=d/Fs Delay =    -0.1500 ``` #### 运行结果正确,图形如下:

  • 2020-03-23
  • 回复了主题帖: 信标导航声音定位与识别——声源定位算法分析

    shadow7 发表于 2020-3-23 16:59 请问楼主时间差是用互相关来算吗  
    如果你能找出Chirp信号的特征标志,就可以不用互相关了,互相关运算有点复杂

  • 发表了主题帖: 信号的相关运算及在单片机程序运用中的算法分析(二)

    # 信号的相关运算及在单片机程序运用中的算法分析(二) #### 离散信号分析和处理的主要手段是利用计算机去实现,为便于计算机去实现,引入离散傅里叶变换(Discrete Fourier Transform,DFT) 。 **目录 (Table of Contents)** [TOCM] # 离散傅里叶变换(DFT) #### 比如我们要求矩形脉冲序列的离散傅里叶变换。 # 时域循环卷积(圆卷积)定理 ## 线卷积 #### 有限长序列f1(k)和f2(k)的长度分别为N和M,则两序列的卷积和f(k)(称为线卷积)仍为有限长序列序列,长度为N+M–1。 ## 循环卷积 #### 有限长序列f1(k)和f2(k)的长度相等,均为N,则f1(k)与f2(k)的循环卷积定义为 #### 循环卷积结果的长度仍为N。若两序列长度不等,采用补零法。假如有两个序列f1(k)与f2(k), #### 将f1(k)补一个零点,使f1(k)与f2(k)的长度均为5。 则: #### 所以, #### 以此类推, 。。。。。。 #### 所以此次循环卷积的最终结果为: #### 循环卷积便于利用数字计算机进行计算。为借助循环卷积求线卷积,要使循环卷积的结果与线卷积结果相同,可以采用补零的方法,使f1(k)与f2(k)的长度均为L≥N+M–1 则循环卷积与线卷积的结果相同。 #### 若 f1(k)←→ F1(n) ####    f2(k)←→ F2(n) # FFT(快速傅里叶变换) #### FFT是一种DFT的高效算法,互相关和自相关函数的计算可利用FFT实现。由于离散傅里叶变换隐含着周期性,所以用FFT计算离散相关函数也是对周期序列而言的。直接做N点FFT相当于对两个N点序列x(n)、y(n)作周期延拓,作相关后再取主值(类似圆周卷积)。而实际一般要求的是两个有限长序列的线性相关,为避免混淆,需采用与圆周卷积求线性卷积相类似的方法,先将序列延长补0后再用上述方法。 ## FFT的MATLAB算法实现 #### 信标新版信号为线性调频Chirp信号,起始频率250Hz,截止频率2000Hz,信号长度为0.2048秒,采样频率要满足奈奎斯特采样定理,这样才能恢复原信号,即Fs>=2fc。fc为截止频率。 ``` Fs = 10000;           % 采样频率 Ts = 1/Fs;            % 采样周期 L = 2048;             % 信号长度 t=(0:L-1).*Ts;        % 时域自变量 x = chirp(t,250,0.2047,2000);                          % chirp信号从0-0.2048秒,频率从250Hz-2000Hz subplot(311); plot(t,x); title("Chirp信号"); xlabel("t/s") ``` ``` y = fft(x,L);        % FFT变换 y = abs(y)./L;       % 实际幅值变换 f=(0:L-1)*Fs./L;     % 实际频率变换 subplot(312); stem(f(1:L/2),y(1:L./2));                         % 数据值按照茎状形式画出,以圆圈终止 title("N-DFT变换幅频响应单边"); xlabel("f/Hz"); ``` ``` grid on f=f-Fs./2;           % 移位 subplot(313); stem(f,fftshift(y)); title("N-DFT变换幅频响应双边") xlabel("f/Hz") ```

  • 2020-03-22
  • 发表了主题帖: LMV358声音定位麦克风传感器v1.0测试板

    # LMV358声音定位麦克风传感器v1.0测试板 ### 信标车上可以安装前后两块LMV358声音定位麦克风传感器v1.0测试板,总共四个麦克风。 **目录 (Table of Contents)** [TOCM] # LMV358原理设计与仿真 #### 网上找到LMV358数据手册,LMV358是低电压轨至轨输出运算放大器。引脚图如下: #### 其余的介绍请看手册: #### 下面开始使用Multisim软件进行原理性仿真。仿真图只是验证芯片可行性,元件参数也是用来测试的,具体的参数在下面的电路板原理图中会详细给出。仿真图如下: #### 其中R1为运放的平衡电阻,R2与R4组成反馈网络决定放大倍数,R3与C1组成无源低通滤波器——截止频率为1.134KHz,D1为3v稳压管,防止输出电压过高损坏单片机设备。 #### 输入信号源为峰峰值10mv频率1kHz的正弦信号: #### 输出信号波形如下: #### 由以上图形及参数可知放大倍数为: $$A=Uo/Ui=1.98*1000/10=198$$ #### 根据运放的理论放大值应为: $$A=Uo/Ui=1+R4/R2=201$$ #### 再看一下无源低通滤波: #### -3dB带宽的截止频率为2.134Khz。 #### 仿真工程文件分享出来,要用Multisim软件打开: # LMV358声音定位麦克风传感器v1.0测试板设计 #### 根据上述原理电路,开始电路板的设计。 ## 电源部分设计 #### 电源部分电路图: #### 模拟电源与数字电源尽量用磁珠或者0欧电阻隔离开,并加上去耦电容和电容滤波电路,保持电源的纯净和稳定。 ## 运放部分设计 #### 运放部分电路图: #### 在上图中,R1为咪头的灵敏度电阻,可以调节咪头拾取声音的灵敏度,T1、T2、T3、T4是为了方便测试的测试点。其中放大倍数可调,放大倍数的调节可以用测试点数据来作为标杆。 ## 总体设计 #### 板子3D展示如下: PCB板采用DXP设计,板子工程文件如下:

  • 2020-03-21
  • 发表了主题帖: 信号的相关运算及在单片机程序运用中算法分析

    #信号的相关运算及在单片机程序运用中算法分析 ### 相关函数是鉴别信号的有力工具,被广泛应用于雷达回波的识别,通信同步信号的识别等领域。相关是一种与卷积类似的运算。与卷积不同的是没有一个函数的反转。 **目录 (Table of Contents)** [TOCM] # 互相关运算 #### 互相关函数给出了在频域内两个信号是否相关的一个判断指标,把两测点之间信号的互谱与各自的自谱联系了起来。它能用来确定输出信号有多大程度来自输入信号,对修正测量中接入噪声源而产生的误差非常有效。 #### 互相关是表示两个不同函数的相似性参数。可证明,R12(τ)=R21(–τ)。 #### 相关与卷积的关系如下: #### R12(t)= f1(t)* f2(–t) #### R21(t) = f1(–t)* f2(t) #### 若f1(t)和 f2(t)均为实偶函数,则卷积与相关完全相同。 #### 在单片机中处理的信号为数字信号,所以从离散的角度来讲就涉及到卷积和。已知定义在区间( – ∞,∞)上的两个函数f1(k)和f2(k),则定义和 #### 为f1(k)与f2(k)的卷积和。下面借助MATLAB工具来定性感受一下。 matlab中的参数都是以数组的形式存储的,标量可以看作是一维数组。 ``` x1=[1 1.5 2]; %离散数据一 x2=[1 1 1];   % 离散数据二 [a,b] = xcorr(x1,x2);% 两个数据求互相关 a a =     1.0000    2.5000    4.5000    3.5000    2.0000 b b =     -2    -1     0     1     2 ``` #### a、b的结果大家应该不会困惑吧,结果就是卷积求得的结果,在此处a、b可以看成数组,我给大家举个例子: #### 其他的结果大家可以依次类推。 # 自相关运算 #### 自相关函数是描述随机信号X(t)在任意两个不同时刻t1,t2的取值之间的相关程度;若互相关函数中f1(t)= f2(t) = f(t),则得自相关函数。 ####显然,R(-τ)= R(τ)偶函数。 ``` %%%%%互相关运算%%%%%% >> x = [1 3 5]; >> [a,b] = xcorr(x) a =      5    18    35    18     5 b =     -2    -1     0     1     2 ``` ``` t=0:100;% 时间 x=cos(t);% 信号 [a,b]=xcorr(x,'unbiased'); plot(b,a) ``` #### 生成图像如下所示: #### 参数'unbiased'的作用在于基于缺省参数时的计算结果,每个组的计算再除上该组的序号组数,比如b(1)时组数为1,记为N=1,则a(1)=1*5/N=5;b(2)时就是a(2)=18/N=18/2=9;类似等等; ``` t=0:100;% 时间 x=cos(t);% 信号 [a,b]=xcorr(x,'biased'); plot(b,a) ``` #### 参数'biased'的作用在于缺省参数的基础上除以序列x的长度,即a(1)=5/3; ``` t=0:100;% 时间 x=cos(t);% 信号 [a,b]=xcorr(x,'coeff'); plot(b,a) ``` #### 此时用于求序列x的自相关序列,其结果是针对'biased'的情况进行归一化,使得b=0时即中间的值a(3)=1,因此a(1)=5/11.6667,所有的分组数据在'biased'基础上都通过11.6667归一运算。 # 不进位乘法求卷积和 #### 实际在单片机中要处理的为2048个长度的Chirp信号,对有限长序列,卷积和的计算用:不进位乘法。不进位乘法的算法思想是这样的,对于两个序列,将两序列样值以各自k的最高值按右端对齐,然后把逐个样值对应相乘,但不进位,最后把同一列上的乘积值按对位求和。例如: # 总结

  • 2020-03-16
  • 发表了主题帖: Chirp信号的基本原理与应用

    #Chirp信号的基本原理与应用 **目录 (Table of Contents)** [TOCM] [TOC] # Chirp信号的分析与基本原理 chirp的汉语意思是“ 喳喳声;唧唧声”。 Chirp信号是指持续期间频率连续线性变化(频率随着时间递增或递减)的扫频信号,又被称为线性调频信号(LFM),是一种常用的雷达信号,是当前应用最广泛的脉冲压缩信号。调制出的此类脉冲压缩信号以声波形式发射出来,听到的声音如同鸟类的啁啾声,所以LFM信号会有Chirp信号的名称。 Chirp信号是非常典型的非平稳信号,不仅是自然存在的一种常见信号形式,也是人类使用最多的一种检测信号形式。自然界中,海豚和蝙蝠等动物发出的用来定位的声波信号就是Chirp信号的一种,另外还有天体间的万有引力波、色散介质中的声脉冲等等。Chirp信号形式代表了一些实际过程和物理现象,其信号参数反映了客观对象的某种状态和属性,因而对Chirp信号的参数估计是实际应用的需要。基于Chirp信号的优点,它也被广泛用于声纳、雷达、地震勘探和通信传输等领域。 假设一个Chirp信号的开始频率为250Hz,结束频率为2KHz,很明显,这个Chirp信号的频率是随时间递增的。假设Chirp信号的数据存储在内存2048的RAM中,通过转换频率为10KHz的单片机DA转换输出。下面我们借助MATLAB工具定性的看一下Chirp信号。 ``` Fs = 10000;           % 采样频率10kHz T = 1/Fs;             % 采样时间 L = 2048;             % 信号长度 t=0:T:0.25;           % 时间 y = chirp(t,250,0.25,2000);                       % chirp信号从0-0.25秒,频率从250Hz-2000Hz plot(t,y);            % 画出chirp信号 title('Chirp信号') xlabel('时间(s)') ylabel('幅值') ``` 运行结果如下图: 越密集的地方说明频率越高,越稀疏的地方说明频率越低。 如果想要听到这段Chirp声音,还可以输入下面的代码,你可以尝试一下是不是鸟叫声。 ``` sound(y);          % 电脑端播放chirp信号 ``` 如果连续播放这段声音,还需要用到for循环,这样也就模拟了chirp声音循环播放了。 ``` for cnt = 0:100;   % 循环播放次数 sound(y);          % 电脑端播放chirp信号 end ``` # Chirp信号的应用 单片机AD转换速率为10kHz,相当于采样频率也为10KHz,声音信号为250Hz-2000Hz的一段带通信号,满足奈奎斯特抽样定理。 卓晴教授的Chirp信号的数据初始化子程序为: ```c //------------------------------------------------------------------------------ void InitDACBuffer(float fStartF, float fEndF) {     float fAngle = 0;     float fFrequency;     float fDeltaT = 1.0 / DAC_OUTPUT_FREQUENCY;         int i;     for(i = 0; i < DAC_BUFFER; i ++) {                  g_nDACBuffer = (unsigned short)((sin(fAngle * 2 * 3.1415926) + 1.0) / 2 * 0x4ff)+0x100;                         fFrequency = (fEndF - fStartF) * (i + 1) / DAC_BUFFER + fStartF;         fAngle += fFrequency * fDeltaT;     } } ``` 由于疫情原因,没有硬件条件,下面用MATLAB来模拟一下这段程序: ``` fAngle = 0; Fs = 10000;              % 采样频率 T = 1/Fs;                % 采样时间 L = 2048;                % 信号长度 fAngle = 0; for i=1:L buffer(i)=((sin(fAngle*2*pi)+1)/2*1279)+256; fFrequency = (2000 - 250) * (i) / 2048 + 250; fAngle = fAngle+fFrequency*T; end plot(buffer) title('单片机生成Chirp信号') xlabel('时间(s)') ylabel('幅值') ```

统计信息

已有402人来访过

  • 芯币:3686
  • 好友:1
  • 主题:78
  • 回复:293
  • 课时:--
  • 资源:7

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言