嵌入式开发模块]AD转换芯片ADS8344驱动模块16位分辨率,程序实例

文章目录


芯片简介

ADS8344是一个8通道16位模数转换器,使用SPI接口。

其可以使用单端或差分输入,单端模式时,每个CHX独立作为采样输入,测其相对于模拟地的差值。差分模式时,CH0和CH1、CH2和CH3……分别作为一组,测两者之间的差值(前者为正)。

采样值是一个16位无符号整型,0对应着模拟地(以及更低),65535(最大值)对应着参考电压Vref(以及更高),中间值则将模拟地和参考电压间的电压值平分。

比如要是要是COM接着的是0V,Vref接着5V,而采样值测出为34532,那么实际测量到的电压= (5V - 0V)/65535*34532 + 0V ≈ 2.63V

通信方式对应于时钟分为多种:


概括来说,CS引脚断言后,芯片会以收到的第一个1作为控制字节的开始,收完控制字节后开始转换,转换中BUSY引脚会变化,然后根据选择的模式会略有不同。

这里,驱动使用了外部时钟模式,这种模式下,一次转换需要最少25个时钟周期,去掉控制字节的8个,就是17个时钟周期。这是应该控制字节后的第一个时钟周期是用于转换的,第二个时钟周期才开始传输结果。因为大部分单片机都是以字节为单位进行通信的,因此一次转换就需要32个时钟周期。最后7个bit会被填充0,真正的数据是倒数第8个bit起,往前16个bit。

因为十分直白明了,就介绍到这了,代码也不多。


代码


头文件

/*
****************************************************************************************
*
*                                  ADS8344 DRIVER MODULE
*                                     ADS8344驱动模块
*
* File    : ADS8344.h
* By      : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date    : 2019/04/28
* Version : V1.0
* Note    : It only support Single-Ended Channel and external clock mode in this version.
*           To use the interface:
*             a. register the SPI functions to the module by regFuncSPI and regFuncCS.
*             b. call sampleChannelSGLEXT to get one sample at specified channel.
*           Note that the return value of sample is a uint16_t type. 0 means the input
*           equal to or lower than GND, 65535 means equal to or higher than Vref.
*           For example, assume that GND is 0V, Vref is 5V, sample result is 34532, than
*                input = (5V - 0V)/65535*34532 + 0V = 2.63V
****************************************************************************************
*/

#ifndef _ADS8344_H
#define _ADS8344_H

/*
****************************************************************************************
*                                       INCLUDES
****************************************************************************************
*/

#include <stdint.h>

/*
****************************************************************************************
*                                       CONSTANTS
****************************************************************************************
*/
// Single-Ended Channel Selection   // A2 A1 A0
#define ADS8344SGL_CH0        0     // 0  0  0
#define ADS8344SGL_CH1        4     // 1  0  0
#define ADS8344SGL_CH2        1     // 0  0  1
#define ADS8344SGL_CH3        5     // 1  0  1
#define ADS8344SGL_CH4        2     // 0  1  0
#define ADS8344SGL_CH5        6     // 1  1  0
#define ADS8344SGL_CH6        3     // 0  1  1
#define ADS8344SGL_CH7        7     // 1  1  1

// Differential Channel Control     // A2 A1 A0
#define ADS8344DIF_CH0        0     // 0  0  0
#define ADS8344DIF_CH2        1     // 0  0  1
#define ADS8344DIF_CH4        2     // 0  1  0
#define ADS8344DIF_CH6        3     // 0  1  1

// Power-Down Selection.

// Power-down between conversions. When each conversion is finished, the converter enters a
// low-power mode. At the start of the next conversion, the device instantly powers up to 
// full power. There is no need for additional delays to assure full operation and the very 
// first conversion is valid.
#define ADS8344PD_Powerdown     0
// Selects Internal Clock Mode.
#define ADS8344PD_InternalClk   2
// No power-down between conversions, device always powered. Selects external clock mode.
#define ADS8344PD_ExternalClk   3

/*
****************************************************************************************
*                                       INTERFACES
****************************************************************************************
*/

// description: Register SPI call back functions
// parameter  : spi_rb   callback function to read byte using SPI(keep MOSI low!!!!!)
//              spi_wb   callback function to write byte using SPI
// return     : 
// note       : you should register SPI functions through this interface before use the driver.
void ADS8344_regFuncSPI(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb));
// description: Registers call back function for ADS8344 select & deselect.
// parameter  : cs_sel     callback function for ADS8344 select
//              cs_desel   callback fucntion for ADS8344 deselect
// return     : 
// note       : you should register CS functions through this interface before use the driver.
void ADS8344_regFuncCS(void(*cs_sel)(void), void(*cs_desel)(void));
// description: sample the channel 'ch' with Single-Ended Channel and external clock mode.
// parameter  : ch   the channel to sample, see ADS8344SGL_CHX
// return     : the sample result.
// note       : 
uint16_t ADS8344_sampleChannelSGLEXT(uint8_t ch);

#endif


源文件

/*
****************************************************************************************
*
*                                  ADS8344 DRIVER MODULE
*                                     ADS8344驱动模块
*
* File    : ADS8344.c
* By      : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date    : 2019/04/28
* Version : V1.0
* Note    : 
****************************************************************************************
*/

/*
****************************************************************************************
*                                       INCLUDES
****************************************************************************************
*/

#include "ADS8344.h"

/*
****************************************************************************************
*                                        CONSTANTS
****************************************************************************************
*/

#define ADS8344MASK_S    0x80
#define ADS8344MASK_SGL  0x04

/*
****************************************************************************************
*                                       LOVAL OBJECTS
****************************************************************************************
*/

static uint8_t _spi_rb_default(void){return 0;}
static void _spi_wb_default(uint8_t wb){(void)wb;}
static void _nullFunc(void){}

static uint8_t (*_spiRead)(void) = _spi_rb_default;
static void (*_spiWrite)(uint8_t wb) = _spi_wb_default;
static void(*_csSel)(void) = _nullFunc;
static void(*_csDesel)(void) = _nullFunc;

/*
****************************************************************************************
*                               INTERFACE IMPLEMENTATIONS
****************************************************************************************
*/

void ADS8344_regFuncSPI(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)){
  _spiRead = spi_rb;
  _spiWrite = spi_wb;
}

void ADS8344_regFuncCS(void(*cs_sel)(void), void(*cs_desel)(void)){
  _csSel = cs_sel;
  _csDesel = cs_desel;
}

uint16_t ADS8344_sampleChannelSGLEXT(uint8_t ch){
  uint16_t ret;
  _csSel();
  // write control byte
  _spiWrite(ADS8344MASK_S | (ch << 4) | ADS8344MASK_SGL | ADS8344PD_ExternalClk);
  ret = _spiRead() << 8;
  ret |= _spiRead();
  ret <<= 1;
  ret |= (_spiRead() >> 7);
  _csDesel();
  return ret;
}

单元测试代码就不放了。


使用及示例代码

没多少代码,很简单的一个模块。
使用的步骤就是,先按要求实现SPI相关接口并进行注册,让模块知道怎么调用SPI。然后再使用ADS8344_sampleChannelSGLEXT接口获得采样值就行了。

#include <stdio.h>
#include "SPI.h"
#include "ADS8344.h"

// 已隐去不重要部分

#define ADS8344_SPI     SPI2
#define ADS8344_CSDDR   DDRH_DDRH7
#define ADS8344_CS      PTH_PTH7

static void Delay(void);
static void INIT_PLL(void);
static uint8_t ADS8344_readByte(void){
  return SPI_ExchangeChar(ADS8344_SPI, 0x00);
}
static void ADS8344_writeByte(uint8_t b){
  SPI_ExchangeChar(ADS8344_SPI, b);
}
static void ADS8344_SelectCS(void){
  ADS8344_CS = 0;
}
static void ADS8344_DeselectCS(void){
  ADS8344_CS = 1;
}

void main(void) {
  // 已隐去不重要部分
  ADS8344_CSDDR = 1;
  MODRR_MODRR6 = 1;      // route the SPI2 to port H
  // 初始化SPI
  (void)SPI_Init(ADS8344_SPI);
  (void)SPI_Enable(ADS8344_SPI);
  // 注册SPI相关接口给模块使用
  ADS8344_regFuncSPI(ADS8344_readByte,ADS8344_writeByte);
  ADS8344_regFuncCS(ADS8344_SelectCS,ADS8344_DeselectCS);
  
  for(;;) {
    Delay();
    // 采样一次通道CH1并打印
    printf("%5u\r\n", ADS8344_sampleChannelSGLEXT(ADS8344SGL_CH1));
  } 
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下是一个16分辨率AD2S1210的Verilog驱动代码: ```verilog module ad2s1210_driver ( input clk, input rst, input [15:0] data_in, output [15:0] data_out, output cs, output sclk, output rd ); reg [15:0] shift_reg; reg [3:0] state; wire [15:0] rom_data; wire [1:0] rom_address; wire rom_rd; assign cs = (state == 4); assign sclk = (state == 1) || (state == 3); assign rd = (state == 2); ad2s1210_rom rom ( .clk(clk), .address(rom_address), .data(rom_data), .rd(rom_rd) ); always @(posedge clk) begin if (rst) begin shift_reg <= 16'h0; state <= 4'd0; end else begin case (state) 4'd0: begin shift_reg <= {shift_reg[14:0], data_in[15]}; state <= 4'd1; end 4'd1: begin shift_reg <= {shift_reg[14:0], data_in[15]}; state <= 4'd2; end 4'd2: begin shift_reg <= {shift_reg[14:0], rom_data[15]}; state <= 4'd3; end 4'd3: begin shift_reg <= {shift_reg[14:0], rom_data[15]}; state <= 4'd0; end 4'd4: begin shift_reg <= {shift_reg[14:0], 1'b0}; state <= 4'd5; end 4'd5: begin shift_reg <= {shift_reg[14:0], 1'b0}; state <= 4'd0; end default: begin shift_reg <= {shift_reg[14:0], 1'b0}; state <= 4'd0; end endcase end end assign rom_address = shift_reg[9:8]; assign data_out = shift_reg; endmodule module ad2s1210_rom ( input clk, input [1:0] address, output [15:0] data, output rd ); reg [15:0] rom[4]; initial begin // 初始化ROM数据 rom[0] = 16'h0000; rom[1] = 16'hFFFF; rom[2] = 16'h5555; rom[3] = 16'hAAAA; end always @(posedge clk) begin case (address) 2'b00: begin data <= rom[0]; end 2'b01: begin data <= rom[1]; end 2'b10: begin data <= rom[2]; end 2'b11: begin data <= rom[3]; end endcase rd <= 1'b1; end endmodule ``` 这个驱动与之前的驱动类似,只是将数据宽扩展到了16,并相应地修改了状态机和ROM数据的宽。控制模块的状态机有5个状态,分别是:等待数据输入、传输数据到芯片、从芯片中读取数据、传输数据到输出端口和空闲状态。ROM模块包含了4个16的数据,其中的数据可以根据需要进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值