技术热线: 0755-86643915

新闻动态

20 bit的ADC芯片CS1237

更新时间: 2024-01-16 15:39:28
阅读量:

#include "main.h"
#include "CS1237.h"    //20bit ADC


#define ADC_Bit  20 //ADC有效位数,带符号位 最高24位
#define SCK_1  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET)
#define SCK_0  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET)
#define DAT_1  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET)
#define DAT_0  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET)
#define DOUT   (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)==GPIO_PIN_SET)
#define    NOP_5()        for(int i=10;i>0;i--);
#define    NOP30()        NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();
#define    NOP40()        NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();
#define One_CLK  SCK_1;NOP40();SCK_0;NOP40();
#define CS_CON  0X0C   //芯片地配置 内部REF 输出40HZ PGA=128 通道A 0X1C   

void CS1237_init()
{
  GPIO_InitTypeDef GPIO_InitStruct;
     
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void DATAIN(void)
{
     GPIO_InitTypeDef GPIO_InitStruct;

  /*Configure GPIO pin : PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void DATAOUT(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
      /*Configure GPIO pin : PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}



//延时500US 25MHZ
void delay_500us(unsigned char a)
{    
    unsigned char i,j,b;
    for(b=0;b<a;b++)
    {
        i = 13;
        j = 37;
        do
        {
            while (--j);
        } while (--i);
    }
}
//配置CS1237芯片
void Con_CS1237(void)
{
    unsigned char i;
    unsigned char dat;
    unsigned char count_i=0;//溢出计时器
    dat = CS_CON;// 0100 1000
    DATAIN();
    SCK_0;//时钟拉低
    while(DOUT)//芯片准备好数据输出  时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好
    {
        delay_500us(10);
        count_i++;
        if(count_i > 150)
        {
            DATAOUT();
            SCK_1;
            DAT_1;
            return;//超时,则直接退出程序
        }
    }
    DATAOUT();
    for(i=0;i<29;i++)// 1 - 29
    {
        One_CLK;
    }
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//30
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//31
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//32
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//33
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//34
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//35
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//36
    One_CLK;//37     写入了0x65
    for(i=0;i<8;i++)// 38 - 45个脉冲了,写8位数据
    {
        SCK_1;NOP40();
        if(dat&0x80)
            DAT_1;
        else
            DAT_0;
        dat <<= 1;
        SCK_0;NOP40();
    }
    One_CLK;//46个脉冲拉高数据引脚
}
//读取芯片的配置数据
unsigned char Read_CON(void)
{
    unsigned char i;
    unsigned char dat=0;//读取到的数据
    unsigned char count_i=0;//溢出计时器
    DATAIN();
    SCK_0;//时钟拉低
    while(DOUT)//芯片准备好数据输出  时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好
    {
        delay_500us(10);
        count_i++;
        if(count_i > 150)
        {
            SCK_1;
            DAT_1;
            return 1;//超时,则直接退出程序
        }
    }
    DATAOUT();
    for(i=0;i<29;i++)// 1 - 29
    {
        One_CLK;
    }
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//30
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//31
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//32
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//33
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//34
    SCK_1;NOP30();DAT_1;SCK_0;NOP30();//35
    SCK_1;NOP30();DAT_0;SCK_0;NOP30();//36
    DAT_1;
    One_CLK;//37     写入了0x56
    DATAIN();
    dat=0;
    for(i=0;i<8;i++)// 38 - 45个脉冲了,读取数据
    {
        One_CLK;
        dat <<= 1;
        if(DOUT)
            dat++;
    }
    One_CLK;//46个脉冲拉高数据引脚
    return dat;
}
//读取ADC数据,返回的是一个有符号数据
long Read_CS1237(void)
{
    DATAOUT();
    unsigned char i;
    long dat=0;//读取到的数据
    unsigned int count_i=0;//溢出计时器
    DAT_1;//端口锁存1,51必备
    SCK_0;//时钟拉低
    DATAIN();
    while(DOUT)//芯片准备好数据输出  时钟已经为0,数据也需要等CS1237拉低为0才算都准备好
    {
        delay_500us(10);
        count_i++;
        if(count_i > 300)
        {
            DATAOUT();
            SCK_1;
            DAT_1;
            return 0;//超时,则直接退出程序
        }
    }
    DATAOUT();
    DAT_0;//端口锁存1,
    DATAIN();
    dat=0;
    for(i=0;i<24;i++)//获取24位有效转换
    {
        dat <<= 1;
        SCK_1;
        NOP40();
        if(DOUT)
            dat ++;
        SCK_0;
        NOP40();    
    }
    for(i=0;i<3;i++)//一共输入27个脉冲
    {
        One_CLK;
    }
    DATAOUT();
    DAT_1;
    //先根据宏定义里面的有效位,丢弃一些数据
    i = 24 - ADC_Bit;//i表示将要丢弃的位数
    dat >>= i;//丢弃多余的位数
    return dat;
}

struct AD_Value Get_Adc_Average(int times)
{
    struct AD_Value ad_value[5],result;
    long item = 0,ad_item = 0;
    int i = 0;
        for(i = 0; i <times ; i++)   //连续读取五次
        {
                ad_value[i].idex = i;
                ad_item= Read_CS1237();
                if((ad_item&0x000F0000) == 0x000F0000)// 判断是负数 最高位24位是符号位
                {
                    ad_value[i].flag = 1;
                    ad_item=~(ad_item-0x00000001);
                    ad_item = ad_item& 0x000FFFFF;// 补码变源码
                }
                else ad_value[i].flag = 0;
                ad_value[i].value =ad_item;
        }
        for(i = 0;i<times;i++)  //大小排序
        {
            for(int j = 0;j<times;j++)
            {
                if(ad_value[i].value > ad_value[j].value)
                {
                    item = ad_value[i].value;
                    ad_value[i].value = ad_value[j].value;
                    ad_value[j].value = item;
                }
            }        
        }
        if(ad_value[1].flag == ad_value[2].flag && ad_value[1].flag == ad_value[3].flag)
        {
            result.flag = ad_value[1].flag;
            result.value = (ad_value[1].value + ad_value[2].value + ad_value[3].value)/3;
            return result;
        }
        else
        return ad_value[2];


}

int Int_To_Str(unsigned long int x,unsigned char *Str)
{
    int t;
    unsigned char *Ptr,Buf[10]; //定义一个字符串数组和字符串指针,
    int i = 0,bit = 0; //用于计数
    Ptr = Str;  //内部指针指向外部指针,进行参数传递,是属于源参数传递(通过地址),
    if(x < 10)                         // 当整数小于10,转换为0x格式
    {
        *Ptr ++ = '0'; //单个数字前面补“0”
        *Ptr ++ = x+0x30;
    }
    else
    {
        while(x > 0)
        {
            t = x % 10;
            x = x / 10;
            Buf[i++] = t+0x30;    // 通过计算把数字编成ASCII码形式
            bit ++;
        }
        i -- ;
        for(;i >= 0;i --)         // 将得到的字符串倒序
        {
            *(Ptr++) = Buf[i];
        }
    }
    *Ptr = ' ';
    *(Ptr+1) = '
';
    return bit+2;
}
//


资料源自网络,侵删