ADS1220 24位高精度ADC芯片驱动

芯片引脚及功能描述:
在这里插入图片描述
在这里插入图片描述
驱动代码:
头文件:ads1220.h

#ifndef __ADS1220_H
#define __ADS1220_H

#include "em_device.h"
#include "em_gpio.h"
#include "em_cmu.h"

#include "em_usart.h"
#include "sl_udelay.h"
#include <math.h>
#include <stdio.h>
#include <string.h>

#include "../autogen/sl_spidrv.h"
#include "spidrv.h"
#include "em_assert.h"
#include "sl_spidrv_spiflash_config.h"
#include "sl_spidrv.h"

#define    CLK_PERIOD_UNIT                26 // unit: ns

#define    MIN_CYCLE_PER_INST        1  // cycle count of one instruction
#define    ONE_LOOP_INIT             10 // instruction count of one loop (estimate)

#define    TPUW             10000000       // 10ms

#define    ADS1220_FULL_ACCESS_TIME         TPUW / (CLK_PERIOD_UNIT * MIN_CYCLE_PER_INST * ONE_LOOP_INIT)

/* Fallback to loc 11 if no location is defined for backwards compatibility */
#ifndef ADS1220_LOC_RX
#define ADS1220_LOC_RX            _USART_ROUTELOC0_RXLOC_LOC11
#endif
#ifndef ADS1220_LOC_SCLK
#define ADS1220_LOC_SCLK          _USART_ROUTELOC0_CLKLOC_LOC11
#endif
#ifndef ADS1220_LOC_TX
#define ADS1220_LOC_TX            _USART_ROUTELOC0_TXLOC_LOC11
#endif
/* Fallback to baudrate of 8 MHz if not defined for backwards compatibility */
#ifndef ADS1220_BAUDRATE
#define ADS1220_BAUDRATE   8000000
#endif

#define ADS1220_PORT_DRDY         gpioPortC
#define ADS1220_PIN_DRDY          4

#define ADS1220_USART             USART0
#define ADS1220_USART_CLK         cmuClock_USART0

#define ADS1220_RESET_COMMAND       0x06
#define ADS1220_START_COMMAND       0x08
#define ADS1220_POWERDOWN_COMMAND   0x02
#define ADS1220_RDATA_COMMAND       0x10
#define ADS1220_RREG_COMMAND        0x20
#define ADS1220_WREG_COMMAND        0x40

#define ADS1220_CONFIG_REG0         0x00
#define ADS1220_CONFIG_REG1         0X01
#define ADS1220_CONFIG_REG2         0x02
#define ADS1220_CONFIG_REG3         0x03

#define SUCCESS 0
#define ERROR   1

#define  lint32_t long int

#define CS_SET(status)   {if(status)  GPIO_PinOutSet( SL_SPIDRV_SPIFLASH_CS_PORT, SL_SPIDRV_SPIFLASH_CS_PIN );\
                         else GPIO_PinOutClear( SL_SPIDRV_SPIFLASH_CS_PORT, SL_SPIDRV_SPIFLASH_CS_PIN );}

#define CHECK_RETURN_IS_SUCCESS(ret, tips)  if(ret != SUCCESS) \
                                                       {\
                                                           printf("[ERROR] %s:%ld\r\n", tips, ret);\
                                                           return ERROR;\
                                                       }


void ads1220_init(void);
uint32_t ads1220_write_one_byte(unsigned char command);
uint32_t ads1220_read_one_byte( uint8_t *recv_data );
uint32_t ads1220_read_data(lint32_t *result );
uint32_t ads1220_reset(void);
uint32_t ads1220_powerdown(void);
uint32_t ads1220_start_conversion(void);
uint32_t ads1220_read_register(lint32_t *Data);
uint32_t ads1220_write_register(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData);
uint32_t ads1220_connfig(unsigned char channel);
void ads1220_set_channel_PGA(unsigned char channel, unsigned char gain);
uint32_t ads1220_get_adc_value(uint8_t channel, lint32_t *voltage);
void clk_delay(uint16_t delay_time );
void ads1220_test_process(void);
void ads1220_printf_channel_vol(uint8_t test_num, uint8_t channel);
#endif

源文件:ads1220.c

#include "ads1220.h"

unsigned char channel0[8] = {};
unsigned char channel1[8] = {};
unsigned char Init_Config[8] = {};

void ads1220_init( void )
{
   CMU_ClockEnable( cmuClock_GPIO, true );
   GPIO_PinModeSet( SL_SPIDRV_SPIFLASH_CS_PORT,   SL_SPIDRV_SPIFLASH_CS_PIN,   gpioModePushPull, 1 );
   GPIO_PinModeSet( ADS1220_PORT_DRDY,   ADS1220_PIN_DRDY, gpioModeInput, 0 );
}

uint32_t ads1220_write_one_byte( uint8_t byte_value)
{
    uint32_t ret = SPIDRV_MTransmitB(sl_spidrv_spiflash_handle, &byte_value, 1);
    CHECK_RETURN_IS_SUCCESS(ret, "SPIDRV_MTransmitB error! Error code");
    return SUCCESS;
}

uint32_t ads1220_read_one_byte( uint8_t *recv_data )
{
   uint32_t ret = 1;
   ret = SPIDRV_MReceiveB( sl_spidrv_spiflash_handle, recv_data, 1 );
   CHECK_RETURN_IS_SUCCESS(ret, "SPIDRV_MReceiveB error! Error code");
   return SUCCESS;
}

uint32_t ads1220_read_data(lint32_t *result )
{
    uint32_t ret = 1;
    unsigned char recv_buf = 0;
    CS_SET(0);
    ret = ads1220_write_one_byte(ADS1220_RDATA_COMMAND);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");


    while(GPIO_PinInGet(ADS1220_PORT_DRDY, ADS1220_PIN_DRDY));

    ret = ads1220_read_one_byte(&recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *result = recv_buf;

    ret = ads1220_read_one_byte( &recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *result = (*result << 8)|recv_buf;

    ret = ads1220_read_one_byte( &recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *result = (*result << 8)|recv_buf;

    CS_SET(1);
//    printf("result = 0x%0lx   %ld\r\n", *result, *result);
    if (*result & 0x800000)
    {
        *result |= 0xff000000;
        printf("result |= 0xff000000");
    }
    return SUCCESS;
}

uint32_t ads1220_reset(void)
{
    uint32_t ret = 1;
    CS_SET(0);
    clk_delay(40);
    ret = ads1220_write_one_byte(ADS1220_RESET_COMMAND);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
    clk_delay(40);
    CS_SET(1);
    clk_delay(40);
    return SUCCESS;
}

uint32_t ads1220_powerdown(void)
{
    uint32_t ret = 1;
    CS_SET(0);
    clk_delay(40);
    ret = ads1220_write_one_byte(ADS1220_POWERDOWN_COMMAND);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
    clk_delay(40);
    CS_SET(1);
    clk_delay(40);
    return SUCCESS;
}

uint32_t ads1220_start_conversion(void)
{
    uint32_t ret = 1;
    CS_SET(0);
    clk_delay(80);
    ret = ads1220_write_one_byte(ADS1220_START_COMMAND);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
    clk_delay(80);
    CS_SET(1);
    clk_delay(80);
    return SUCCESS;
}

uint32_t ads1220_read_register(lint32_t *Data)
{
    uint32_t ret = 1;
    unsigned char recv_buf = 0;
    CS_SET(0);
    clk_delay(80);
    ret = ads1220_write_one_byte(ADS1220_RREG_COMMAND|0x03);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
    ret = ads1220_read_one_byte( &recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *Data = recv_buf;
    ret = ads1220_read_one_byte(&recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *Data =  (*Data << 8)|recv_buf;
    ret = ads1220_read_one_byte( &recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *Data = (*Data << 8)|recv_buf;
    ret = ads1220_read_one_byte(&recv_buf);
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_one_byte error! Error code");
    *Data = (*Data << 8)|recv_buf;

    CS_SET(1);
    clk_delay(80);
    return SUCCESS;
}
 
uint32_t ads1220_write_register(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData)
{
    unsigned char i;
    uint32_t ret = 1;
    CS_SET(0);
    clk_delay(80);

    // send the command byte

    ret = ads1220_write_one_byte(ADS1220_WREG_COMMAND | (((StartAddress<<2) & 0x0c) |((NumRegs-1)&0x03)));
    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");

    // send the data bytes
    for (i=0; i< NumRegs; i++)
    {
        ret = ads1220_write_one_byte(*pData);
        CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
        pData++;
    }
    CS_SET(1);
    return SUCCESS;
}

/*
 * 函数说明:ads1220设置配置寄存器,包括多路复用选择、增益配置、数据速率
 *          工作模式、转换模式、基准电压选择等设置
 * 参数:channel  通道选择   1-3可选
 * 返回值:设置成功返回SUCCESS,失败返回ERROR
 *
 * */
uint32_t ads1220_config(unsigned char channel) // 0-1-2-3
{
    uint32_t ret = 1;
    lint32_t data = 0;

    switch(channel)
    {
        case 0: 
            Init_Config[0] = 0x81;
            break;
        case 1: 
            Init_Config[0] = 0x91;
            break;
        case 2: 
            Init_Config[0] = 0xA1;
            break;
        case 3: 
            Init_Config[0] = 0xB1;
            break;
    }
    Init_Config[1] = 0X40;//90SPS
    Init_Config[2] = 0X10; /* 同时抑制50Hz和60Hz IDAC电流关断 */
    Init_Config[3] = 0X00;

    ret = ads1220_write_register(ADS1220_CONFIG_REG0,0x04,Init_Config);

    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_write_one_byte error! Error code");
    ret = ads1220_read_register(&data);

    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_register error! Error code");
    return SUCCESS;
}
 
void ads1220_set_channel_PGA(unsigned char channel, unsigned char gain)
{
    switch(channel)
    {
        case 0:
            if(gain==1)
              channel0[0] = 0x81;
            if(gain==2)
              channel0[1] = 0x83;
            if(gain==4)
                channel0[2] = 0x85;
            if(gain==8)
                channel0[3] = 0x87;
            if(gain==16)
                channel0[4] = 0x89;
            if(gain==32)
                channel0[5] = 0x8B;
            if(gain==64)
                channel0[6] = 0x8D;
            if(gain==128)
                channel0[7] = 0x8F;
            break;
        case 1:
            if(gain==1)
                channel1[0] = 0x91;
            if(gain==2)
                channel1[1] = 0x93;
            if(gain==4)
                channel1[2] = 0x95;
            if(gain==8)
                channel1[3] = 0x97;
            if(gain==16)
                channel1[4] = 0x99;
            if(gain==32)
                channel1[5] = 0x9B;
            if(gain==64)
                channel1[6] = 0x9D;
            if(gain==128)
                channel0[7] = 0x9F;
            break;
        case 2: 
            Init_Config[0] = 0xA1;
            break;
        case 3: 
            Init_Config[0] = 0xB1;
            break;
    }
}
 
uint32_t ads1220_get_adc_value(uint8_t channel, lint32_t *voltage) // 0-1-2-3
{
    uint32_t ret = 1;

    ret = ads1220_config(channel);


    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_config error! Error code");
    ret = ads1220_start_conversion();


    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_start_conversion error! Error code");
    ret = ads1220_read_data(voltage);


    CHECK_RETURN_IS_SUCCESS(ret, "ads1220_read_data error! Error code");
    return SUCCESS;
}
 
void clk_delay(uint16_t delay_time )
{
//  delay_time = delay_time*2;
    while( delay_time>0 )
    {
        delay_time--;
    }
}


void ads1220_printf_channel_vol(uint8_t test_num, uint8_t channel)
{
    lint32_t adc_value = 0;
    uint32_t ret = 1;
    double res_value = 0.0;

    char vol_buf[50] = {0};

    ret = ads1220_get_adc_value(1, &adc_value);
    if(ret != SUCCESS)
    {
        printf("[ERROR] ads1220_get_adc_value error! Error code %ld\r\n", ret);
        return;
    }

    res_value = 100/(2.048/8388608*adc_value-1.25);
    sprintf(vol_buf, "test num: %d   channel: %d  res: %dK\r\n", test_num, channel ,(int)res_value);
    printf("%s", vol_buf);
}

void ads1220_test_process(void)
{
    lint32_t adc_value = 0;
    uint32_t ret = 1;
    double vol_value = 0.0;

    char vol_buf[20] = {0};

    ret = ads1220_get_adc_value(0, &adc_value);
    if(ret != SUCCESS)
    {
        printf("[ERROR] ads1220_get_adc_value error! Error code %ld\r\n", ret);
        return;
    }

    vol_value = 2.048/8388608*adc_value;
    sprintf(vol_buf, "AIN0 vol: %lf\r\n", vol_value);
    printf("%s", vol_buf);


    ret = ads1220_get_adc_value(1, &adc_value);
    if(ret != SUCCESS)
    {
        printf("[ERROR] ads1220_get_adc_value error! Error code %ld\r\n", ret);
        return;
    }

    vol_value = 2.048/8388608*adc_value;
    sprintf(vol_buf, "AIN1 vol: %lf\r\n\r\n", vol_value);
    printf("%s", vol_buf);
    sl_udelay_wait(1000000);
}

注:
ads1220为SPI驱动,仅支持SPI模式1(CPOL = 0 CPHA = 1)
上述代码可直接运行在芯科科技的EFR32BG22中
需要移植到自己的芯片中需要替换掉对应的部分(gpio驱动;延时;如果使用硬件spi还需要适配对应的硬件spi驱动)。

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

all of the time

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

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

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

打赏作者

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

抵扣说明:

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

余额充值