七、重定向标准输入输出
以上实现了串口驱动,我们现在来实现串口重定向标准输入输出以方便后面的调试,处于资源和效率考虑,我们这里移植小型的xprintf而不是使用printf。添加xprintf.c xprintf.h到工程src下xprintf.h中使能以下宏
左右滑动查看完整内容
#define XF_USE_OUTPUT 1 /* 1: Enable output functions */ #define XF_CRLF 1 /* 1: Convert ==> in the output char */ #define XF_USE_DUMP 1 /* 1: Enable put_dump function */ #define XF_USE_LLI 1 /* 1: Enable long long integer in size prefix ll */ #define XF_USE_FP 1 /* 1: Enable support for floating point in type e and f */ #define XF_DPC '.' /* Decimal separator for floating point */ #define XF_USE_INPUT 1 /* 1: Enable input functions */ #define XF_INPUT_ECHO 1 /* 1: Echo back input chars in xgets function */hal_entry.c中
#include "xprintf.h"
设置收发接口
左右滑动查看完整内容
void xprintf_output(int ch) { uint8_t val = (uint8_t)ch; drv_uart_write(&val,1); } int xprintf_input(void) { uint8_t val; while(drv_uart_read(&val,1) <= 0); return (int)val; } xdev_out(xprintf_output); xdev_in(xprintf_input);
测试
左右滑动查看完整内容
xprintf("%d ", 1234); /* "1234" */ xprintf("%6d,%3d%% ", -200, 5); /* " -200, 5%" */ xprintf("%-6u ", 100); /* "100 " */ xprintf("%ld ", 12345678); /* "12345678" */ xprintf("%llu ", 0x100000000); /* "4294967296" */ xprintf("%lld ", -1LL); /* "-1" */ xprintf("%04x ", 0xA3); /* "00a3" */ xprintf("%08lX ", 0x123ABC); /* "00123ABC" */ xprintf("%016b ", 0x550F); /* "0101010100001111" */ xprintf("%*d ", 6, 100); /* " 100" */ xprintf("%s ", "abcdefg"); /* "abcdefg" */ xprintf("%5s ", "abc"); /* " abc" */ xprintf("%-5s ", "abc"); /* "abc " */ xprintf("%.5s ", "abcdefg"); /* "abcde" */ xprintf("%-5.2s ", "abcdefg"); /* "ab " */ xprintf("%c ", 'a'); /* "a" */ xprintf("%12f ", 10.0); /* " 10.000000" */ xprintf("%.4E ", 123.45678); /* "1.2346E+02" */ for(;;) { char buffer[64]; char* p = buffer; long a; long b; long c; xprintf("please input int a and int b "); xgets(buffer,sizeof(buffer)); xatoi(&p,&a); xatoi(&p,&b); c = a + b; xprintf("%d + %d = %d ",a,b,c); }
输入1空格2回车打印1 + 2 = 3
八、命令行实现
以上实现了串口重定向,我们现在实现简单的命令行,以便后面进行交互操作。设计思想是,定义命令字符串和实现函数的对应表,标准输入读一行,搜索对应表和字符串匹配,匹配则执行对应的函数。
实现代码见shell.c shell.h shell_func.c shell_func.h测试输入help回车打印如下:
九. ADC采集音频
使用如下麦克风采集模块ADC采集信号。
参考电压为3.3V
配置ADC配置P001为ADC的CH1
添加相关代码
配置属性
生成工程 添加adc.c和adc.h代码测试
#include "adc.h"
初始化
左右滑动查看完整内容
adc_init(); static uint16_t adcbuffer[1024] = {0};
循环调用
左右滑动查看完整内容
adc_read(adcbuffer, 1024); for(uint32_t i=0; i<1024; i++) { xprintf("/*%d*/ ",adcbuffer); }
也可以添加命令行采集Shell_func.h中
void ADCFun(void* param);
Shell_func.c中
左右滑动查看完整内容
#include "adc.h" { (const uint8_t*)"adc", ADCFun, "adc"}, /*ADC采集*/
十、ADC可视化(虚拟示波器)
通过串口将采集的数据发送到PC,PC端使用可视化上位机进行可视化,即实现了虚拟示波器的应用。
十一、DSP算法库
添加DSP算法库使用的是CMSIS-DSP的算法库
添加的代码如下
十二、FFT谐波分析(电能质量分析)
12.1FFT算法
我们可以使用fft算法对原始数据尽心分析,得到谐波,直流量,相位,频率,幅值等信息,以进行电能质量分析,噪声分析等各种应用。
12.2添加命令行
添加命令行参数Shell_func.h中
void FftFun(void* param);
Shell_func.c中
左右滑动查看完整内容
#include "fft.h" { (const uint8_t*)"ft", FftFun, "fft"}, /*fft分析*/ void FftFun(void* param) { int num; if(1 == sscanf(param,"%*s %d",&num)) { while(num--) { fft_test(); } } }
12.3代码
Fft.c fft.h见git
12.4测试
上位机输入fft 10即进行10次采样分析效果如下
十三、噪声检测与分析
我们也可以将开发板打造为噪声监测分析仪,对于噪声首先关心的就是其大小,我们可以实时采集声音并通过算法检测出极大值,最终换算成相对基准功率的噪声分贝值。同时也可以通过命令行控制何时进行采样分析,和其他功能是独立的,可以单独调用,集成在一起作为工具集供调用。当然也可以进行噪声的谐波等分析,和前面的点那个质量谐波分析等一样。
13.1 极大值检测算法
极大值检测算法参见:
https://www.mdpi.com/1999-4893/5/4/588/htm
13.2 添加命令行
添加命令行参数Shell_func.h中
void MaxFun(void* param);
Shell_func.c中
左右滑动查看完整内容
#include "max.h" { (const uint8_t*)"max", MaxFun, "max"}, /*极值检测*/ void MaxFun(void* param) { int num; if(1 == sscanf(param,"%*s %d",&num)) { while(num--) { max_test(); } } }
13.3 代码
Max.c max.h详见git
13.4 测试
上位机输入max 10即进行10次采样分析可视化显示如下,黄色线是极大值检测结果,蓝色线是原始数据。
十四、数字滤波器
14.1 IIR滤波器
DSP算法库中提供了很多滤波算法,我们这里将IIR添加到我们的工具集中进行演示。
14.2 添加命令行
添加命令行参数Shell_func.h中
void IirFun(void* param);
Shell_func.c中
左右滑动查看完整内容
#include "iir.h" { (const uint8_t*)"iir", IirFun, "iir"}, /*滤波分析*/ void IirFun(void* param) { int num; if(1 == sscanf(param,"%*s %d",&num)) { while(num--) { iir_test(); } } }
14.3代码
Iir.c iir.h详见git
14.4测试
上位机输入iir 10即进行10次采样分析可视化显示如下,黄色线滤波结果,蓝色线是原始数据。
十五、相位频率幅值分析(频率计等)
15.1 相位分析
FFT计算结果,幅值最大的横坐标对应信号频率,纵坐标对应幅度。幅值最大的为out[m]=val;则信号频率f0=(Fs/N)m ,信号幅值Vpp=val/(N/2)。N为FFT的点数,Fs为采样频率。相位Pha=atan2(a, b)弧度制,其中ab是输出虚数结果的实部和虚部。
15.2 添加命令行
添加命令行参数Shell_func.h中
Void FrqFun(void* param);
Shell_func.c中
左右滑动查看完整内容
#include "frq.h" { (const uint8_t*)"frq", FrqFun, "frq"}, /*相位分析*/ void FrqFun(void* param) { int num; if(1 == sscanf(param,"%*s %d",&num)) { while(num--) { Frq_test(); } } }
15.3 代码
Frq.c frq.h详见git
15.4 测试
上位机输入frq 10即进行10次采样分析
十六、总结
本开发板性能资源比较丰富,特别适合开发和验证等。本文基于该开发板实现了信号处理前端,实现了虚拟示波器、噪声分析仪、电能质量分析仪、数字滤波器等功能的集合,并且可以方便的快速添加更多的应用。可以基于CLI调用方便脚本化使用,可以使用上位机可视化,是一个瑞士军刀类型的工具集。目前支持的CLI命令如下,可以快速扩展更多应用。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !