高精度ADC芯片CS1259B驱动

本文详细介绍了一种基于CS1259B芯片的ADC模块驱动程序的实现过程,包括SPI通信配置、寄存器读写操作、ADC电压采集等功能。通过具体的代码示例,展示了如何初始化芯片、配置GPIO端口、读取ADC数据,并进行了通道0到4的ADC电压采集测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef __ADC_H_
#define __ADC_H_

#ifdef __cplusplus
extern "C" {
#endif


#define ADC_VERF        2.45
#define MAX_INT24       8388607

#define SPI_SCL_PORT       	 GPIOC
#define SPI_SCL_PIN          LL_GPIO_PIN_2

#define SPI_SDA_PORT         GPIOC
#define SPI_SDA_PIN          LL_GPIO_PIN_1

#define SPI_CS_PORT         GPIOC
#define SPI_CS_PIN          LL_GPIO_PIN_0

#define SPI_IO_GRP1_CLK     LL_IOP_GRP1_PERIPH_GPIOC

#define SPI_CS_LOW()        LL_GPIO_ResetOutputPin(SPI_CS_PORT, SPI_CS_PIN)
#define SPI_CS_HIGH()       LL_GPIO_SetOutputPin(SPI_CS_PORT, SPI_CS_PIN)

#define SPI_SCL_LOW()       LL_GPIO_ResetOutputPin(SPI_SCL_PORT, SPI_SCL_PIN)
#define SPI_SCL_HIGH()      LL_GPIO_SetOutputPin(SPI_SCL_PORT, SPI_SCL_PIN)

#define SPI_SDA_LOW()       LL_GPIO_ResetOutputPin(SPI_SDA_PORT, SPI_SDA_PIN)
#define SPI_SDA_HIGH()      LL_GPIO_SetOutputPin(SPI_SDA_PORT, SPI_SDA_PIN)

#define CS1259B_SYS   0x0
#define CS1259B_ADC0  0x1
#define CS1259B_ADC1  0x2
#define CS1259B_ADC2  0x3
#define CS1259B_ADC3  0x4
#define CS1259B_ADC4  0x5
#define CS1259B_ADC5  0x6
#define CS1259B_ADO   0x9
#define CS1259B_ADS   0xA

void CS1259B_init(void);
float CS1259B_read(uint8_t ch);


#ifdef __cplusplus
}
#endif

#endif


#include "hardware.h"


static void SPI_IO_Config(void);
static void CS1259B_Read_Ain0(float* voltage);
static void CS1259B_Read_Ain1(float* voltage);
static void CS1259B_Read_Ain2(float* voltage);
static void CS1259B_Read_Ain3(float* voltage);
static void CS1259B_Read_Ain4(float* voltage);
static void SET_DA_INPUT(void);
static void SET_DA_OUTPUT(void);
static void Send_Byte(uint8_t Data);
static uint8_t Read_Byte(void);
static void Read_Reg(uint8_t addr,uint8_t* RegValue,uint8_t len);
static void Write_Reg(uint8_t addr,uint8_t Value);
static void cs1259b_read_ado(uint8_t* buf);
static int32_t adc_24to32(uint8_t *padc);
static void adc_read_voltage(uint8_t gain, float* voltage);

void CS1259B_init(void)
{
    SPI_IO_Config();
    
    Write_Reg(CS1259B_ADC1, 0x80);
    Write_Reg(CS1259B_ADC3, 0x04);
    Write_Reg(CS1259B_ADC4, 0x41);
    Write_Reg(CS1259B_ADC5, 0x00);
}

float CS1259B_read(uint8_t ch)
{
    float ADC_Value=0.00;
    switch(ch)
    {
        case 0:
            CS1259B_Read_Ain0(&ADC_Value);
            break;
        case 1:
            CS1259B_Read_Ain1(&ADC_Value);
            break;
        case 2:
            CS1259B_Read_Ain2(&ADC_Value);
            break;
        case 3:
            CS1259B_Read_Ain3(&ADC_Value);
            break;
        case 4:
            CS1259B_Read_Ain4(&ADC_Value);
            break;
        default:
            break;
    }
    
    return ADC_Value;
}

static void SPI_IO_Config(void)
{
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    LL_IOP_GRP1_EnableClock(SPI_IO_GRP1_CLK);

    GPIO_InitStruct.Pin = SPI_CS_PIN;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
    LL_GPIO_Init(SPI_CS_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = SPI_SDA_PIN;
    LL_GPIO_Init(SPI_SDA_PORT, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = SPI_SCL_PIN;
    LL_GPIO_Init(SPI_SCL_PORT, &GPIO_InitStruct);
}

//IO方向设置
//配置数据线为输入
static void SET_DA_INPUT(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    LL_IOP_GRP1_EnableClock(SPI_IO_GRP1_CLK);

    GPIO_InitStruct.Pin = SPI_SDA_PIN;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(SPI_SDA_PORT, &GPIO_InitStruct);   
}
//配置数据线为输出
static void SET_DA_OUTPUT(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    LL_IOP_GRP1_EnableClock(SPI_IO_GRP1_CLK);
    GPIO_InitStruct.Pin = SPI_SDA_PIN;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
    LL_GPIO_Init(SPI_SDA_PORT, &GPIO_InitStruct);
}

//发送一个字节
static void Send_Byte(uint8_t Data)//外部设备在 SCLK 上升沿写数据
{
    uint8_t i=0;
    SET_DA_OUTPUT();                    //数据线配置为输出
    
    for(i=0;i<8;i++)
    {
        SPI_SCL_LOW();
    
        if(Data&0x80)                           //读入最高位数据,高位在前
        {
            SPI_SDA_HIGH();                 //为一,SDA输出高定平
        }
        else
        {
            SPI_SDA_LOW();
        }
        
        Data<<=1;
        
        SPI_SCL_HIGH();                     //外部设备在 SCLK 上升沿写命令字节
    }
    
    SPI_SCL_LOW();                          
}


//接收一个字节
static uint8_t Read_Byte(void)
{
    uint8_t i=0;
    uint8_t data=0;
    
    for(i=0;i<8;i++)
    {
        SPI_SCL_LOW();
        SPI_SCL_HIGH();                         //CS1259B 在 SCLK 上升沿将数据从 SDA 输出
        data<<=1;                                       //将上一次的数据往左移一位
        if(LL_GPIO_IsInputPinSet(SPI_SDA_PORT, SPI_SDA_PIN))
            data++;
    }
    SPI_SCL_LOW();
    return data;
}

//从CS1259B寄存器中读取数据
static void Read_Reg(uint8_t addr,uint8_t* RegValue,uint8_t len)
{
    uint8_t i=0;
    SPI_CS_LOW();                       //选中芯片
    
    SET_DA_OUTPUT();                //设置为输出,给1259B发送地址数据
    Send_Byte(addr&0x7F);       //最高位为读写标志位
    
    SET_DA_INPUT();                 //设置为输入,读取来自1259B的数据
    
    for(i=0;i<len;i++)
    {
        *RegValue=Read_Byte();
        RegValue++;
    }
    
    SPI_CS_HIGH();                  //取消选中
}
//向1259B中写数据
static void Write_Reg(uint8_t addr,uint8_t Value)
{
    SPI_CS_LOW();
    
    SET_DA_OUTPUT();
    Send_Byte(addr|0x80);
    Send_Byte(Value);
    
    SPI_CS_HIGH();
}


static void cs1259b_read_ado(uint8_t* buf)
{
    uint8_t buffer[1];
        
      Read_Reg(CS1259B_ADO, &buf[0], 3);
    Read_Reg(CS1259B_ADS, buffer, 1);
    while (!(buffer[0]&0x80))
    {
            Read_Reg(CS1259B_ADO, &buf[0], 3);
            Read_Reg(CS1259B_ADS, buffer, 1);
    }
}

static int32_t adc_24to32(uint8_t *padc)
{
    uint32_t value = (uint32_t)*(uint32_t *)padc;
    
    value = __rev((value)) >> 8;

    if(*(padc) & 0x80) {
        value |= 0xFF000000;
    }
    
    return value;
}

static void adc_read_voltage(uint8_t gain, float* voltage)
{
    uint8_t   buf[3];
    int32_t   adc_mask;

    cs1259b_read_ado(buf);
    adc_mask = adc_24to32(buf);
    if ((adc_mask & 0x800000) == 0x800000) {
        adc_mask = -adc_mask;
    }
    
    *voltage = ((float)adc_mask/MAX_INT24)* ADC_VERF / gain;
    
    return;
}


//通道0,ADC电压采集
static void CS1259B_Read_Ain0(float* voltage)
{
    Write_Reg(CS1259B_ADC0, 0x20);
    
    Write_Reg(CS1259B_SYS, 0x16);
    LL_mDelay(100);
  adc_read_voltage(1, voltage);
    Write_Reg(CS1259B_SYS, 0x10);
}
//通道1,ADC电压采集
static void CS1259B_Read_Ain1(float* voltage)
{
    Write_Reg(CS1259B_ADC0, 0x21);

    Write_Reg(CS1259B_SYS, 0x16);
    LL_mDelay(100);
  adc_read_voltage(1, voltage);
    Write_Reg(CS1259B_SYS, 0x10);
}
//通道2,ADC电压采集
static void CS1259B_Read_Ain2(float* voltage)
{
    Write_Reg(CS1259B_ADC0, 0x22);
    
    Write_Reg(CS1259B_SYS, 0x16);
    LL_mDelay(100);
  adc_read_voltage(1, voltage);
    Write_Reg(CS1259B_SYS, 0x10);
}
//通道3,ADC电压采集
static void CS1259B_Read_Ain3(float* voltage)
{
    Write_Reg(CS1259B_ADC0, 0x23);
    
    Write_Reg(CS1259B_SYS, 0x16);
    LL_mDelay(100);
  adc_read_voltage(1, voltage);
    Write_Reg(CS1259B_SYS, 0x10);
}

//通道4,ADC电压采集
static void CS1259B_Read_Ain4(float* voltage)
{
    Write_Reg(CS1259B_ADC0, 0x1F);
    
    Write_Reg(CS1259B_SYS, 0x16);
    LL_mDelay(100);
  adc_read_voltage(1, voltage);
    Write_Reg(CS1259B_SYS, 0x10);
}
void CS1259B_Test(void)
{
    float voltage0,voltage1,voltage2,voltage3,voltage4;
    SPI_IO_Config();

    while(1)
    {
        CS1259B_Read_Ain0(&voltage0);
        debug_print(0, "CS1259B_Read_Ain0:++%lf\r\n",voltage0);
        LL_mDelay(500);
        CS1259B_Read_Ain1(&voltage1);
        debug_print(0, "CS1259B_Read_Ain1:++++%lf\r\n",voltage1);
        LL_mDelay(500);
        CS1259B_Read_Ain2(&voltage2);
        debug_print(0, "CS1259B_Read_Ain2:+++++++%lf\r\n",voltage2);
        LL_mDelay(500);
        CS1259B_Read_Ain3(&voltage3);
        debug_print(0, "CS1259B_Read_Ain3:++++++++++%lf\r\n",voltage3);
        LL_mDelay(500);
        CS1259B_Read_Ain4(&voltage4);
        debug_print(0, "CS1259B_Read_Ain4:++++++++++++++%lf\r\n",voltage4);
        LL_mDelay(500);
    }
}










评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值