通过SPI配置高速ADC

接着上一篇LVDS接口ADC,这篇讲它的SPI配置。SPI的时序图如下,一个三个信号,CSB片选低有效,SCLK时钟,SDIO数据。时钟下降沿发送数据,上升沿采样。然后就是跟厂商密切相关的定义了,这个每个厂商的芯片协议字都不一样,其实就是具体的比特代表的含义。
这里写图片描述
首位比特:1代表读,0代表写;接下来两位W1:W0,代表后面传输的数据的字节数(这儿有个坑,一会儿说);然后是13位的寄存器地址;然后是发送或接收的数据。

其中W1:W0刚开始寄存器的设置理解有点问题,没有好好看AN-877技术手册,自己想当然的猜测后面一个字节的数据就应该是01,结果00,01,10,11分别对应1,2,3,4个字节。然后由于设置的数据是两个字节,每次传输完一个寄存器的配置它还在等,下一个就会把它冲掉,整个配置就完全错乱了,too young!

接下来就去查寄存器表看看自己需要配置哪些字段,上电之后复位一下AD芯片肯定是不可少的,然后是一些个性化的需求,比如说采样率,传输方式等等。这里我只复位了一下,然后配置了采样率,其它的全部默认。

其中很重要的一个就是配置采样率后要配置寄存器0xFF=0x01,设置采样率覆盖。
这里写图片描述

这里写图片描述
最后贴上代码,先复位,然后清空复位,然后配置采样率,最后设置采样率覆盖使能。代码比较简单,搞个计数器,把各个寄存器分段顺序输出就行了。

parameter       P_CONFIG0 = 24'h000803;//复位
parameter       P_CONFIG1 = 24'h000800;//清空复位
parameter       P_CONFIG2 = 24'h010004;//设置采样率
parameter       P_CONFIG3 = 24'h00ff01;//设置采样率使能
assign O_FPGA_AD_SYNC = 1'b0;
assign O_FPGA_AD_PDWN = 1'b0;
reg [ 4:0] R_clk_div   ;
reg [ 6:0] R_cnt_tx    ;
reg [23:0] R_config    ;
reg [22:0] R_count_100M;
always @(posedge I_sys_clk or negedge I_reset_n)
begin
    if(~I_reset_n) 
    begin
        R_clk_div <= 0;
    end 
    else
    begin
        R_clk_div <= R_clk_div + 1'b1;
    end
end
assign W_clk_1M = R_clk_div[4];
always @(posedge W_clk_1M or negedge I_reset_n)
begin
    if (~I_reset_n)
    begin
        R_count_100M <= 23'd1;
    end
    else if(|R_count_100M)
    begin
        R_count_100M <= R_count_100M +1'b1;
    end
end
always @(negedge W_clk_1M or negedge I_reset_n)
begin
    if(~I_reset_n) 
    begin
        R_cnt_tx <= 0;
    end 
    else
    begin
        if (&R_count_100M) 
        begin
            R_cnt_tx <= 7'd1;
        end
        else if(|R_cnt_tx)
        begin
            R_cnt_tx <= R_cnt_tx + 1'b1;
        end
    end
end
always @(negedge W_clk_1M or negedge I_reset_n)
begin
    if(~I_reset_n) 
    begin
        R_config <= 0;
        O_FPGA_AD_SC <= 1;
    end 
    else
    begin
        if (R_cnt_tx == 7'd1) 
        begin
            R_config <= P_CONFIG0;
            O_FPGA_AD_SC <= 0;
        end
        else if(R_cnt_tx == 7'd25)
        begin
            O_FPGA_AD_SC <= 1;
        end
        else if (R_cnt_tx == 7'd33) 
        begin
            R_config <= P_CONFIG1;
            O_FPGA_AD_SC <= 0;
        end
        else if(R_cnt_tx == 7'd57)
        begin
            O_FPGA_AD_SC <= 1;
        end
        else if (R_cnt_tx == 7'd65) 
        begin
            R_config <= P_CONFIG2;
            O_FPGA_AD_SC <= 0;
        end
        else if(R_cnt_tx == 7'd89)
        begin
            O_FPGA_AD_SC <= 1;
        end
        else if (R_cnt_tx == 7'd97) 
        begin
            R_config <= P_CONFIG3;
            O_FPGA_AD_SC <= 0;
        end
        else if(R_cnt_tx == 7'd121)
        begin
            O_FPGA_AD_SC <= 1;
        end
        else
        begin
            R_config <= {R_config[22:0],1'b0};
        end
    end
end
assign O_FPGA_AD_SDIO = R_config[23];
assign O_FPGA_AD_SCLK = (~O_FPGA_AD_SC) & W_clk_1M;//1M
  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AD7606是ADI公司的一款高精度、高速率的12位模数转换器。AD7606与微处理器之间的通信采用SPI接口,需要通过驱动程序来实现对AD7606的控制和数据传输。 AD7606 SPI驱动程序一般分为两个部分:硬件配置和软件编程。硬件配置主要包括对SPI总线的初始化和对AD7606片选引脚的配置。软件编程主要包括对SPI读写操作的封装和对AD7606控制命令的发送。 下面是一个简单的AD7606 SPI驱动程序代码示例: ``` #include <linux/spi/spi.h> #define AD7606_SPI_SPEED_HZ 5000000 // SPI时钟频率 #define AD7606_DEV_NAME "ad7606" // 设备名称 static struct spi_device *ad7606_spi_device; // AD7606 SPI设备结构体 static int ad7606_spi_probe(struct spi_device *spi) { // 初始化SPI设备 spi->max_speed_hz = AD7606_SPI_SPEED_HZ; spi->mode = SPI_MODE_3; spi_setup(spi); // 保存SPI设备结构体 ad7606_spi_device = spi; // TODO: 配置AD7606片选引脚 return 0; } static int ad7606_spi_remove(struct spi_device *spi) { // TODO: 释放AD7606片选引脚 return 0; } static struct spi_driver ad7606_spi_driver = { .probe = ad7606_spi_probe, .remove = ad7606_spi_remove, .driver = { .name = AD7606_DEV_NAME, .owner = THIS_MODULE, }, }; static int ad7606_spi_read_reg(u8 reg, u8 *buf, int len) { struct spi_message msg; struct spi_transfer xfer; u8 tx_buf = {reg, 0xFF}; // 第一个字节是寄存器地址,第二个字节可以是任意值 int ret; // 初始化SPI传输结构体 memset(&xfer, 0, sizeof(xfer)); xfer.tx_buf = tx_buf; xfer.rx_buf = buf; xfer.len = len; xfer.cs_change = 1; // 每次传输后自动取消片选 // 初始化SPI消息结构体 memset(&msg, 0, sizeof(msg)); msg.spi = ad7606_spi_device; msg.tx_buf = tx_buf; msg.rx_buf = buf; msg.len = len; // 发送SPI消息 ret = spi_sync_transfer(&msg); if (ret < 0) { printk(KERN_ERR "ad7606: failed to read register %02x\n", reg); return ret; } return 0; } // TODO: 实现其他AD7606控制命令的发送和数据读取函数 static int __init ad7606_init(void) { int ret; // 注册SPI驱动程序 ret = spi_register_driver(&ad7606_spi_driver); if (ret < 0) { printk(KERN_ERR "ad7606: failed to register SPI driver\n"); return ret; } return 0; } static void __exit ad7606_exit(void) { // 注销SPI驱动程序 spi_unregister_driver(&ad7606_spi_driver); } module_init(ad7606_init); module_exit(ad7606_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("AD7606 SPI driver"); ``` 相关问题: 1. AD7606是什么? 2. AD7606 SPI驱动程序的工作原理是什么? 3. AD7606控制命令有哪些? 4. 如何实现对AD7606数据的读取?

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值