找回密码
 注册
关于网站域名变更的通知
查看: 413|回复: 1
打印 上一主题 下一主题

转——高速数据采集之数据传输(2) 

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-4-15 16:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
转——高速数据采集之数据传输(2)
1、  硬件环境
       硬件平台: Embest SoC --LarkBoard
       软件平台:开发板-linux-3.10.31
                       Quartus 14.0

& x. `! H: \; R/ |3 p
2、系统概述
在上一篇文章已经成功进行了这样的测试,每中断一次,ARMFPGA的ROM中取一次数据,这边文章主要是测试一下,ADC的数据经过双口RAM传递给ARM的过程,设计框图如下所示:
9 b, b  J7 J/ o6 Y6 H' H
3、Qsys设计
下图是qsys的设计和连接关系如下图所示:

5 {0 x5 Z) \4 ]9 E( O
1)  如图所示adc_origin_data挂载在HPS-to-FPGA bridge上,偏移地址为20040000(这个地址是可以任意改动的,注意和驱动对应就行了)
2)  增加了adc_spi_pio的控制接口,实现对ADC的配置和初始化,这个前面的测试中是没有注意的

! @1 P9 w) j8 r7 L5 T$ \2 {$ y4 b
quartus工程文件见附件:
游客,如果您要查看本帖隐藏内容请回复
% h: @- H2 F" Y, y& g* U( L
4、ADC驱动设计
这里测试驱动主要使用了Embest自带的驱动,位于drivers\char\adc9628.c,具体代码可见附件:
游客,如果您要查看本帖隐藏内容请回复
这是一个很好的参考用例,实际使用的时候还需要进一步的修改。上面qsys中偏移地址的设置就是为了和驱动相对应的。

4 l1 u; ]" |, H$ G, U; g7 ^% K' [
主要完成以下功能:
1)通过模拟SPI接口完成ADC9628的初始化
  • /*
  • *init the registers of ADC9628,
  • *write to Altera's PIO IP core to operate the gpio as spi pins
  • */
  • static void bsp_adc_init(struct adc_priv_data *adc_data)
  • {
  •     int iadc_val  ;
  •     writew( 0x7,adc_data->regbase + (0x1*4));                                                 /* pio_dir = 0x7 */
  •         writew( 0x6,adc_data->regbase + (0x4*4));                                                 /* cs = 1  */
  •         writew( 0x2,adc_data->regbase + (0x4*4));                                                 /* sclk=0 */
  •         mdelay(2);
  •     iadc_val = ad9628_read(0x1 );                                                                          /*  chip ID, 0x89 */
  •     printk(KERN_INFO"current id = %x \n", iadc_val);
  •     iadc_val = ad9628_read(0x2 );                                                                          /*  chip grade */
  •         iadc_val = ad9628_read(0x0b );                                                                         /* clock divide */
  •         iadc_val = 0x0;
  •         ad9628_write(0x0b, iadc_val);
  •         iadc_val = ad9628_read(0x0b );
  •     iadc_val = ad9628_read(0x09 );                                                                  /* DUTY stabilty */
  •         iadc_val = ad9628_read(0x0b );                                                                  /* clock ratio */
  •         ad9628_write(0x05, 0x03);                                                                             /*  Channel a b */
  •     iadc_val = ad9628_read(0x5 );
  •         ad9628_write(0x0d, 0x0);                                                                                  /*  normal mode */
  •     iadc_val = ad9628_read(0xd );
  •         iadc_val = ad9628_read(0x101 );
  •         iadc_val |= (0x1<<7);
  •         ad9628_write(0x101, iadc_val);
  •         iadc_val = ad9628_read(0x101 );
  •         bsp_adc_cmos();
  •         iadc_val = ad9628_read(0x14 );
  • }( \% e, v: V% \7 e0 f

4 |9 ~+ @7 h, d" O& `; |1 p
, _: C* O7 W& c

- r! h# N- \1 A+ q, o+ ~
2)完成读双口RAM的操作
  • static const struct file_operations adc_fops = {
  •         .read                = adc_read,
  •         .open                = adc_open,
  •         .release                = adc_release,
  •         .owner                = THIS_MODULE,
  • };
    7 S3 u. Y' @! [2 l) O

! q2 H" n8 l1 B% C' q
/ d( q8 h! v" z
8 P6 l. i0 ]1 `+ ?1 E  W
3)把ADC注册成一个char型设备
  • static int __init adc9628_init(void)
  • {
  •         dev_t dev = MKDEV(LARK_ADC_MAJOR, 0);
  •         int ret;
  •         ret = register_chrdev_region(dev, max_adc_minors, "adc");
  •         if (ret)
  •                 goto error;
  •         cdev_init(&adc_cdev, &adc_fops);
  •         ret = cdev_add(&adc_cdev, dev, max_adc_minors);
  •         if (ret) {
  •                 goto error_region;
  •         }
  •         adc_class = class_create(THIS_MODULE, "adc");
  •         if (IS_ERR(adc_class)) {
  •                 printk(KERN_ERR "Error creating adc class.\n");
  •                 cdev_del(&adc_cdev);
  •                 ret = PTR_ERR(adc_class);
  •                 goto error_region;
  •         }
  •         adc_class->devnode = adc_devnode;
  •         device_create(adc_class, NULL, MKDEV(LARK_ADC_MAJOR, 0), NULL, "adc");
  •         if (!request_mem_region(BSP_ADC_ADDR,sizeof(u32),"adc9628")) {
  •                 printk( "Memory region busy\n");
  •                 return  -EBUSY;
  •         }
  •         gRegbase = ioremap_nocache(BSP_ADC_ADDR, sizeof(u32));
  •         if(!gRegbase) {
  •             printk( KERN_INFO" ioremap failed\n");
  •                 return -EIO;
  •         }
  •         if (!request_mem_region(BSP_FIFO_BASE,sizeof(u32)*1024,"adc9628_fifo")) {
  •                 printk( KERN_INFO"Memory region busy\n");
  •                 return  -EBUSY;
  •         }
  •         gFifobase = ioremap_nocache(BSP_FIFO_BASE, sizeof(u32)*1024);
  •         if(!gFifobase) {
  •             printk( KERN_INFO" ioremap failed\n");
  •                 return -EIO;
  •         }
  •         return 0;
  • error_region:
  •         unregister_chrdev_region(dev, max_adc_minors);
  • error:
  •         return ret;
  • }/ m* J1 {( \; |

. |9 W: x. ^9 m- Y/ m

0 q" J9 v0 c' S% l至此ADC驱动介绍完毕,记得在编译系统的时候把驱动编译进去就行了

$ z: _8 ~0 m3 x/ d+ ~! N
5、应用程序设计
这里使用的也是Embest提供的测试程序,详细程序可见附件: adc_test.zip (1.62 KB, 下载次数: 88)
测试程序主要完成了FFT计算,我也没有深入的研究,因为并不是我想要的东西,只是用它做个测试吧,有兴趣的自行研究吧,这里就不分析代码了;
0 V/ l* e+ H0 w5 V& D1 L( E

9 J: t9 V4 E7 z5 ~8 c) O- G) D( f
6、测试结果
# A* v3 v* m. |5 x) b0 o9 l9 V
1) 环境搭建
把信号发生器的两个输出口,分别接ADC9628 的两个输入端,如下图所示:

. x: `$ r8 S7 v0 Y
7 L3 k" d9 I9 V% o
2)设置信号发生器
5 v5 E* Z$ P' G  H

1 Q) B5 V% o& x. t4 L
3)运行测试程序
  • root@arm:~/adc# ./adc_test
  • current id = 89
  • dong fft
  • caculate real valule
  • 146:chanel0 frequency = 14.970703, amplitude=2185
  • 293:chanel1 frequency = 30.043945, amplitude=1806
    # j1 L* h$ w! m# E$ y1 m  B
: J6 e) u3 C) v/ Y( a0 }$ a- r

9 ?1 v* A" T  A) ]0 _. ?6 x! G$ S2 p& Z
从测试结果看chanel0的频率测量是14.970703Mhz,chanel1的频率测量是30.043945Mhz,和实际设置值相似,且可以按照设定频率进行准确的跟踪,说明数据传输应该没有问题
$ F# h' `7 B7 ]7 ]6 P
7、小结
1) 本次主要测试ADC的采集数据通过双口RAM传递给ARM的过程,测试结果一切正常,为下一步的工作打下了基础;
2)HPS-to-FPGA bridge接口传输的性能还有待进一步的测试,目前优先完成系统设计;
3)下一步准备把前面设计的中断,加入到驱动中去,这样驱动就更加实用了;
4)同时准备移植web服务器,把采集的数据能够在web上进行展示,这方面不擅长,有大侠可帮忙吗?非常感谢!
5 o* Y9 R' y  p, o

0 H( s* E# N3 A8 `* x. r3 R. x0 P$ k- U- `2 C% i7 T; V
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-30 06:47 , Processed in 0.125000 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表