AM57x 多核SoC开发板——GPMC的多通道AD采集综合案例手册(上)

目 录

1 ————案例功能

2 ————操作说明

2.1 ————硬件连接

2.2 ————案例测试

2.3 ————使用CCS查看信号波形

2.3.1 ————加载Symbols信息表

2.3.2 ————查看时域波形

2.3.3 ————查看频域波形

3 ————案例编译

4 ————关键代码

4.1 ————ARM(Host)端关键代码

4.2 ————DSP(Slave)端关键代码

本文档适用开发环境:

Windows开发环境:Windows 7 64bit、Windows 10 64bit

Linux Processor SDK:ti-processor-sdk-linux-rt-am57xx-evm-04.03.00.05

RTOS Processor SDK:ti-processor-sdk-rtos-am57xx-evm-04.03.00.05

CCS:CCS7.4

本案例主要是通过GPMC接口采集AD7606或ADS8568模块输入的AD信号,由DSP端对AD信号进行FFT处理,并由ARM端对AD信号进行Qt波形绘制、数据保存等,其中使用到的测试板卡为创龙科技的TL570x-EVM工业开发板。

创龙科技TL570x-EVM是一款基于TI Sitara系列AM5708 ARM Cortex-A15 + 浮点DSP C66x处理器设计的异构多核SoC评估板,由核心板和评估底板组成。典型应用在运动控制、工业PC、机器视觉、智能电力、视频监测等领域。

核心板经过专业的PCB Layout和高低温测试验证,稳定可靠,可满足各种工业应用环境。开发板接口资源丰富,引出双路PRU百兆网口、千兆网口、USB 3.0、CAMERA、GPMC、HDMI、PCIe等接口,方便用户快速进行产品方案评估与技术预研。

案例功能

AM570x DSP端使用EDMA通过GPMC接口采集AD7606或ADS8568模块8通道的AD信号,同时由DSP端对其中6通道的AD信号进行FFT处理,最后将8通道时域数据和经FFT处理的6通道频域数据保存到DSP端L2SRAM中,可通过仿真器与CCS软件查看对应通道的时域波形和频域波形。

程序保存通道0的时域数据和经FFT处理的频域数据至CMEM(共享内存)空间,通过IPC组件通知ARM端读取该通道的时域数据和频域数据,使用Qt在LCD显示屏上进行波形绘制,最后将数据保存到文件中。

本案例默认配置AD7606模块采样周期为6us,即采样率约为167KHz;配置ADS8568模块采样周期分别为5us,即采样率为200KHz。程序工作流程图如下所示:

图 1

操作说明

硬件连接

将Tronlong的TL7606I(AD7606)模块或TL8568I(ADS8568)模块插入评估板GPMC扩展接口,并对模块进行独立供电。TL7606I模块使用5V电源供电,J1跳线帽连接到0,使用±5V量程。TL8568I模块使用12V电源供电,软件已配置为±12V量程。

将模块的待测输通道正确连接信号发生器,信号发生器输出频率为4KHz、峰峰值为2Vpp(即幅值为1V)的正弦波信号。待测信号电压请勿超过模块量程,否则可能会导致模块损坏。评估板接入LCD显示屏,并通过仿真器连接到PC机。硬件连接示意图如下:

图 2 TL7606I模块硬件连接示意图

图 3 TL7606I模块硬件连接示意图

图 4 TL8568I模块硬件连接示意图

  1. 案例测试

案例位于产品资料“4-软件资料\Demo\rtos-examples\tl-linux-ipc-examples\tl-gpmc-ad-fft\”目录下,案例目录说明如下。

图 5

表 1

bin目录

app_host

ARM端可执行文件

load-firmware.sh

DSP端可执行文件运行脚本

server_dsp1.xe66

DSP端可执行文件

lib目录

libqwt-6.1.3.tar.gz

QWT库压缩包

src目录

dsp1目录

存放DSP端源码和配置文件等

host目录

存放ARM端源码和配置文件等

ludev目录

存放共享内存库源码和镜像文件等

shared目录

存放多核共用代码定义相关文件

makefile

顶层Makefile文件,用于构建整个案例程序

products.mak

顶层配置文件,用于配置编译环境

由于本案例需依赖QWT库文件,因此请将libqwt-6.1.3.tar.gz压缩包解压,并将解压目录中的lib目录下的libqwt.so、libqwt.so.6、libqwt.so.6.1、libqwt.so.6.1.3此四个QWT库文件拷贝到文件系统“/usr/lib/”目录下。同时将bin目录下的app_host、server_dsp1.xe66、load-firmware.sh此三个文件拷贝到评估板文件系统同一个目录下。

图 6

Linux内核预留0xa0000000~0xac000000(192MByte)内存作为CMEM共享内存,案例使用0xa0000000~0xa0008000(32KByte)内存进行测试,此32KByte内存划分为2个16KByte (0x4000,16384)池空间,分别用于存放模块通道0的时域数据和频域数据。

进入评估板文件系统执行如下命令。

备注:由于CMEM共享内存地址空间已超过512MByte,故如下测试仅支持DDR3不小于1GByte的评估板。

Target# /etc/init.d/matrix-gui-2.0 stop //关闭Matrix界面程序

Target# pkill ti-mctd //禁用ti-mctd服务,避免cmemk驱动卸载失败

Target# rmmod cmemk //卸载cmemk驱动

Target# modprobe cmemk phys_start=0xa0000000 phys_end=0xa0008000 pools=2x16384 //划分2个16KByte池空间

Target# cat /proc/cmem //查看CMEM配置

图 7

图 8

进入app_host、server_dsp1.xe66、load-firmware.sh文件所在目录并执行如下命令,运行DSP端程序。

Target# ./load-firmware.sh

图 9

执行如下命令可查看ARM端程序参数说明。

Target# ./app_host -h

图 10

执行如下命令,运行ARM端程序。

Target# ./app_host 0x01000000 6 10000 /home/root/ 7606

命令参数说明:

0x01000000:指定GPMC片选首地址,使用的GPMC片选为CS0。

6:指定信号采集周期(单位:us)。TL7606I模块设置为6,TL8568I模块设置为5。

10000:指定采集循环次数。

/home/root/:指定模块通道0的时域数据和频域数据的保存路径。时域数据保存文件为ad_raw_data.txt,频域数据保存文件为ad_fft_data.txt。

7606:指定模块型号。TL7606I模块设置为7606,TL8568I模块设置为8568。

图 11 TL7606I模块运行命令

图 12 TL8568I模块运行命令

程序运行后,即可在LCD显示屏上看到通道0的时域波形和频域波形。

图 13 时域波形

图 14 频域波形

  1. 使用CCS查看信号波形

在程序运行过程中可使用CCS软件查看存储在DSP端L2SRAM中的时域和频域波形。

加载Symbols信息表

进入app_host、server_dsp1.xe66、load-firmware.sh文件所在目录执行如下命令,运行DSP端程序。

Target# ./load-firmware.sh

驱动默认配置DSP端的电源控制模式为auto-suspend(自动休眠),当DSP端处于休眠状态时,CCS将无法连接DSP端。

请执行如下命令设置电源控制模式为on,禁用auto-suspend模式。

Target# echo "on" > /sys/bus/platform/devices/40800000.dsp/power/control

请执行如下命令禁用错误恢复功能,避免发生错误时系统自动重启DSP端,干扰调试。

Target# echo disabled > /sys/kernel/debug/remoteproc/remoteproc2/recovery

请执行如下命令,运行ARM端程序(以TL7606I模块为例)。

Target# ./app_host 0x01000000 6 10000 /home/root/ 7606

图 15

打开CCS,创建仿真配置文件后进入Debug界面,右键点击“Connect Target”连接DSP端,如下图所示。连接后DSP端程序将会暂停运行,请点击

按键恢复运行。

图 16

由于程序调试需用到镜像文件中的Symbols信息表,因此请点击“Run -> Load -> Load Symbols...”加载案例bin目录下的server_dsp1.xe66镜像文件导入Symbols信息表。

备注:请确保加载的server_dsp1.xe66文件与当前DSP端运行的是同一个镜像文件,否则可能导致符号地址不一致以及仿真运行错误。

图 17

图 18

查看时域波形

点击“View -> Memory Browser”,在弹出界面的搜索栏搜索ch_raw_buffer数组,该数组存放时域数据,搜索结果如下图所示。ch_raw_buffer数组包含8个地址,从左到右分别对应存放通道0至7时域数据的起始地址,例如0x00828EA0为存放通道0时域数据的起始地址。

图 19

点击“Tools -> Graph -> Single Time”,如下图所示。

图 20

在弹出界面中按照下图内容进行配置,然后点击OK,即可查看AD信号的时域波形。

图 21

表 2

Acquisition Buffer Size

从Start Address开始读取的数据长度

Dsp Data Type

读取的数据类型

Start Address

从Start Addres开始读取数据

Display Data Size

显示的数据长度(即将多少个采样点的数据进行显示,该数值不能大于Acquisition Buffer Size)

图 22

程序已将8通道的时域数据保存到DSP端L2SRAM,如需查看其他通道波形,请按照上述方法打开对应通道地址查看即可。

本次使用TL7606I模块进行测试,在上图中可看到通道0的时域波形,波形的幅值约为6796。从CCS看到的波形值为AD芯片内部寄存器保存的数字量,从AD7606和ADS8568的芯片数据手册得到的换算公式均为:数字量=待测量/量程*32768,则AD信号实际幅值=数字量*量程/32768=6796*5V/32768=1.04V,与信号发生器的1V标称值接近。

查看频域波形

点击“View -> Memory Browser”,在弹出界面的搜索栏搜索ch_fft_buffer数组,该数组存放频域数据,搜索结果如下图所示。ch_fft_buffer数组包含8个地址,从左到右分别对应存放通道0至7频域数据的起始地址,例如0x008292A0为存放通道0频域数据的起始地址。

备注:由于受处理器的性能限制,程序默认只对通道0~5进行FFT处理,因此ch_fft_buffer数组未存放通道6和7频域数据。

图 23

点击“Tools -> Graph -> Single Time”,如下图所示。

图 24

在弹出界面中按照下图内容进行配置,然后点击OK,即可查看AD信号的频域波形。

图 25

表 3

Acquisition Buffer Size

从Start Address开始读取的数据长度

Dsp Data Type

读取的数据类型

Index Increment

索引增量(即每个采样点数据序号的相差值,由于FFT数据以复数形式存储,只取复数中的实部进行显示,因此设置成2,隔点取值显示)

Start Address

从Start Addres开始读取数据

Display Data Size

显示的数据长度(即将多少个采样点的数据进行显示,该数值不能大于Acquisition Buffer Size)

图 26

点击菜单栏放大按钮进行放大查看,点击

打开游标工具,再点击X-Axis可查看到信号存在,如下图所示。

图 27

程序已将6通道的频域数据保存到DSP端L2SRAM,如需查看其他通道波形,请按照上述方法打开对应通道地址查看即可。

本次使用TL7606I模块进行测试,在上图中可看到通道0的频域波形在第12个点存在信号。程序命令已设置每6us触发一次TL7606I模块的CONVST/GPIO5[13]引脚进行AD信号采集。

图 28

图 29

在程序运行过程中使用示波器通过测量CONVST/GPIO5[13]引脚,测得信号实际采集周期为5.720us,即信号实际采样率为174.8KHz。

图 30

与设定的6us存在一定误差的原因主要有如下两点:

  1. 程序使用的GPTimer6定时器的精度存在误差,并受系统延时影响。
  2. GPIO引脚电平翻转存在约100ns的时延。如选择专用的定时器输出引脚作为触发信号,可降低时延。

根据采集频率计算公式,某点n所表示的采样频率为:Fn=n*(Fs/N)(n>=0),参数解析如下表。

表 4

Fn

采样频率

n

存在信号的点

Fs

信号采样率

N

信号采样长度

可得出实际的采样频率Fn=12*(174.8KHz/512)=4.0969KHz,与信号发生器的4KHz标称值接近。

到这里,案例功能和操作的基本说明,包括硬件连接与案例测试、如何使用CCS查看信号波形部分就介绍到这里,想要查看案例编译和ARM(Host)端、DSP(Slave)端的关键代码,请看下篇文章,感谢关注,欢迎点赞或评论区留言!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
/*************** 深圳市赛亿科技开发有限公司 ******************** * 文件名 : adc * 描述 :多通道AD采集(源文件) * 实验平台 :STM8S105开发板 * 库版本 :V1.0 * 作者 :hcr * QQ :630054913 * 修改时间 :2014-9-20 *******************************************************************************/ #include "adc.h" u16 AdcData_Buff[10]; //AD采集缓存 u16 AdcValue_Channel1; //通道1值 u16 AdcValue_Channel2; //通道2值 u16 AdcValue_Channel3; //通道3值 float Adc_V1; //通道1值电压值 float Adc_V2; //通道2值电压值 float Adc_V3; //通道3值电压值 /************************************************************************** * 函数名:Adc_Task(void) * 描述 :AD不通通道选择 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :10ms调用 *************************************************************************/ void Adc_Task(void) { static u8 Adc_Channel = 1; static u8 Adc_Timer = 0; static u16 Adc_GetValue; switch(Adc_Channel)//通道选择 { case 1: //通道1 Adc_GetValue = ADC1_GetConversionValue(); //获取ADC转换数 AdcData_Buff[Adc_Timer]=Adc_GetValue; //保存采样值 if(Adc_Timer8) { Adc_Timer = 0; //复位 Temp_Choose(); //冒泡法求中间值 AdcValue_Channel1=AdcData_Buff[5]; //取中间值 Adc_V1 = (3.28*AdcValue_Channel1)/1023; //算出实际电压 AdcData_Clean(); //清除缓存数据 Adc_Channel = 2; //另一通道 AdcChannel_Start(ADC1_CHANNEL_2); //ADC,通道2启动 } break; case 2: //通道2 Adc_GetValue = ADC1_GetConversionValue(); //获取ADC转换数 AdcData_Buff[Adc_Timer]=Adc_GetValue; //保存采样值 if(Adc_Timer8) { Adc_Timer = 0; //复位 Temp_Choose(); //冒泡法求中间值 AdcValue_Channel2=AdcData_Buff[5]; //取中间值 Adc_V2 = (3.28*AdcValue_Channel2)/1023; //算出实际电压 AdcData_Clean(); //清除缓存数据 Adc_Channel = 3; //另一通道 AdcChannel_Start(ADC1_CHANNEL_3); //ADC,通道3启动 } break; case 3: //通道3 Adc_GetValue = ADC1_GetConversionValue(); //获取ADC转换数 AdcData_Buff[Adc_Timer]=Adc_GetValue; //保存采样值 if(Adc_Timer8) { Adc_Timer = 0; //复位 Temp_Choose(); //冒泡法求中间值 AdcValue_Channel3=AdcData_Buff[5]; //取中间值 Adc_V3 = (3.28*AdcValue_Channel3)/1023; //算出实际电压 AdcData_Clean(); //清除缓存数据 Adc_Channel = 1; //另一通道 AdcChannel_Start(ADC1_CHANNEL_1); //ADC,通道1启动 } break; default: break; } } /************************************************************************** * 函数名:ADC_Init(void) * 描述 :ADC1初始化 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :系统初始化调用 *************************************************************************/ void ADC_Init(void) { ADC1_DeInit(); //恢复ADC1寄存器为默认值 ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2); //预分频2 ADC1_ITConfig(ADC1_IT_EOCIE,DISABLE); //使能中断 ADC1_Cmd(ENABLE); //启动ADC AdcChannel_Start(ADC1_CHANNEL_1); /* //恢复ADC1寄存器为默认值 ADC1->CSR = 0x00; ADC1->CR1 = 0x00; ADC1->CR2 = 0x00; ADC1->CR3 = 0x00; ADC1->TDRH = 0x00; ADC1->TDRL = 0x00; ADC1->HTRH = 0x03; ADC1->HTRL = 0xFF; ADC1->LTRH = 0x00; ADC1->LTRL = 0x00; ADC1->AWCRH = 0x00; ADC1->AWCRL = 0x00; ADC1->CR1 |= ADC1_PRESSEL_FCPU_D2; //选择2分频 ADC1->CR2 |= ADC1_ALIGN_RIGHT; //右对齐 ADC1->CR1 |= ADC1_CR1_CONT; //连续转换模式 ADC1->CSR |= ADC1_IT_EOCIE; //使能中断 ADC1->CR1 |= ADC1_CR1_ADON; //启动ADC */ } /************************************************************************** * 函数名:AdcChannel_Start(void) * 描述 :选择通道启动 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :外部调用 *************************************************************************/ void AdcChannel_Start(ADC1_Channel_TypeDef ADC1_Channel) { ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_Channel,ADC1_ALIGN_RIGHT);/*配置通道的转换功能,连续右对齐*/ ADC1_StartConversion();//启动转换 /* ADC1->CSR &= (uint8_t)(~0x0F); // Clear the ADC1 channels ADC1->CSR |= ADC1_Channel; // Select the ADC1 channel ADC1->CR1 |= ADC1_CR1_ADON; //启动ADC */ } /************************************************************************** * 函数名:AdcData_Clean(void) * 描述 :清除缓存数据 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :外部调用 *************************************************************************/ void AdcData_Clean(void) { u8 j; for(j=0;j<10;j++) AdcData_Buff[j]=0; } /************************************************************************** * 函数名:Temp_Choose(void) * 描述 :冒泡法取中间值 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :外部调用 *************************************************************************/ void Temp_Choose(void)//冒泡法求中间值 { u8 i_Adc = 0; u8 j_Adc = 0; u16 Data_Buf; for(j_Adc=0;j_Adc<9;j_Adc++) { for(i_Adc=0;i_AdcAdcData_Buff[i_Adc+1]) { Data_Buf=AdcData_Buff[i_Adc]; AdcData_Buff[i_Adc]=AdcData_Buff[i_Adc+1]; AdcData_Buff[i_Adc+1]=Data_Buf; } } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tronlong创龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值