2025年ADC芯片CS1238,CS1237介绍和代码

ADC芯片CS1238,CS1237介绍和代码一 芯片介绍 CS1238 是一款高精度 低功耗 模数转换芯片 两路差分输入通道 内置温度传感器和高精度振荡器 MCU 可以通过 2 线的 SPI 接口 SCLK DRDY 与 CS1237 进行通信 对其进行配置 例如通道选择 PGA 选择 输出速率选择等 下面是 CS1238 和 CS1237 的一些特点 二 硬件设计

大家好,我是讯享网,很高兴认识大家。

一.芯片介绍

CS1238是一款高精度、低功耗 模数转换芯片,两路差分输入通道,内置温度传感器和高精度振荡器。MCU可以通过2线的SPI 接口SCLK、DRDY与CS1237进行通信,对其进行配置,例如通道选择、PGA选择、输出速率选择等。下面是CS1238和CS1237的一些特点。
在这里插入图片描述
讯享网

二.硬件设计

CS1238的管脚定义如下

在这里插入图片描述
结合框架图,可以看出CS1238的使用方法比较简单,除去电源口就只有4个输入脚,CS1238和MCU的通信只要2个IO口模拟SPI。
在这里插入图片描述

三,程序设计

CS1238的程序设计比较简单,按照步骤为配置IO,写寄存器配置模式,读取ADC数据。一般只要配置两个IO口为输入和输出模式就可以。

在这里插入图片描述

//IO初始化 void CS1238_IO_Init(void) { 
    GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_12); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_11); } 

讯享网

CS1238的程序重点在于他的读写时序,首先看下时序图。
在这里插入图片描述
在这里插入图片描述
CS1238一次完整的周期有48个时钟信号。每一个时钟的都有特定的作用,下面我们结合程序来看。首先写一个时钟周期。

讯享网//一个时钟周期 //高电平不能超过100uS,否则进入powerdown的休眠模式. void cs1238_clock(void) { 
    GPIO_SetBits(GPIOA, GPIO_Pin_12); delay_us(10);//延时10us GPIO_ResetBits(GPIOA, GPIO_Pin_12); delay_us(10);//延时10us } 

这里要注意到高电平的时间不可以超过100us,不然就会进入到睡眠模式。

在这里插入图片描述
我们1到24个时钟信号为读ADC数值,代码如下。

//CS1238读数据 int32_t read_cs1238_data(void) { 
    int i=0; uint32_t dat=0;//读取到的数据 int32_t temp; //DOUT由高变低之后开始读取数据 CS1238_OUT(); GPIO_SetBits(GPIOA, GPIO_Pin_11); CS1238_IN(); GPIO_ResetBits(GPIOA, GPIO_Pin_11); //等待芯片准备好,低电平准备好 while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)) { 
    delay_ms(1); i++; if(i>100)//检测100ms { 
    u2_printf("CS1238 Data error \r\n"); return 0; } } /* 1: clk1 ~ clk24 ADC数据*/ for(i=0;i<24;i++)//获取24位有效转换 { 
    dat <<= 1; cs1238_clock(); if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==1) { 
    dat |= 0x01; } } /* 1: clk25 ~ clk27 读取寄存器写操作状态*/ for(i=0;i<3;i++) { 
    cs1238_clock(); } if(dat&0x00)// 判断是负数 最高位24位是符号位 { 
    temp=(((~dat)&0x007FFFFF) + 1);// 补码变源码 u2_printf("CS1238_data= %x \r\n", temp); return temp; } else temp=dat;// 正数的补码就是源码 u2_printf("CS1238_data= %x \r\n", dat); return temp; } 

然后CS1238只有一个7位寄存器,功能为设置ADC的放大倍数和输出数据频率等。并且CS1238只有两个7bit的指令,为写寄存器和读寄存器的指令。
在这里插入图片描述

在这里插入图片描述
相对应的代码如下。

讯享网//写CS1238的寄存器,ad_reg为写入的寄存器数值 void Write_AdReg(u8 ad_reg) { 
    int i; u8 Write_AdReg=0x00; //DOUT由高变低之后开始读取数据 CS1238_OUT(); GPIO_SetBits(GPIOA, GPIO_Pin_11); CS1238_IN(); GPIO_ResetBits(GPIOA, GPIO_Pin_11); //1-29,读ADC数值 for(i=0;i<29;i++) { 
    cs1238_clock(); } CS1238_OUT(); Write_AdReg=0xCA; //0X56为写命令,因为只有7个时钟,所以左移一位 /* 1: clk30 ~ clk36 写入写命令*/ for(i=0;i<7;i++) //30-36 { 
    if(Write_AdReg & 0x80) { 
    GPIO_SetBits(GPIOA, GPIO_Pin_11); // DATA=1 } else { 
    GPIO_ResetBits(GPIOA, GPIO_Pin_11); // DATA=0; } Write_AdReg = Write_AdReg << 1; cs1238_clock(); } //clk37切换写入写出方向 cs1238_clock(); //37 CS1238_OUT(); /* 1: clk38 ~ clk45 写入寄存器配置*/ Write_AdReg=ad_reg; //寄存器配置 for(i=0;i<8;i++) { 
    if(Write_AdReg&0x80) { 
    GPIO_SetBits(GPIOA, GPIO_Pin_11); // DATA=1 } else { 
    GPIO_ResetBits(GPIOA, GPIO_Pin_11); // DATA=0; } Write_AdReg = Write_AdReg << 1; cs1238_clock(); } GPIO_SetBits(GPIOA, GPIO_Pin_11); //clk46 cs1238_clock(); } 
//读CS1238寄存器 uchar_t Rd_AdReg(void) { 
    int i; u8 RD_AdReg=0x00; //DOUT由高变低之后开始读取数据 CS1238_OUT(); GPIO_SetBits(GPIOA, GPIO_Pin_11); CS1238_IN(); GPIO_ResetBits(GPIOA, GPIO_Pin_11); //1-29,读ADC数值 for(i=0;i<29;i++) { 
    cs1238_clock(); } CS1238_OUT(); RD_AdReg = 0xAC; //0X56为读命令,因为只有7个时钟,所以左移一位 /* 1: clk30 ~ clk36 写入读命令*/ for(i=0;i<7;i++) { 
    if((RD_AdReg & 0x80)!=0) { 
    GPIO_SetBits(GPIOA, GPIO_Pin_11); // DATA=1; } else { 
    GPIO_ResetBits(GPIOA, GPIO_Pin_11); // DATA=0; } RD_AdReg<<=1; cs1238_clock(); } //clk37切换写入写出方向 cs1238_clock(); CS1238_IN() /* 1: clk38 ~ clk45 输出寄存器配置*/ RD_AdReg=0x00; for(i=0;i<8;i++) { 
    RD_AdReg<<=1; cs1238_clock(); if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)==1)) { 
    RD_AdReg |= 0x01; //为了保证前面输入的数据不变新输入的数据为高电平1时可以传进来 } } GPIO_SetBits(GPIOA, GPIO_Pin_11); cs1238_clock(); //第46CLK return RD_AdReg; } 

最后是CS1238的初始化。

讯享网//CS1238初始化 void CS1238_Init(void) { 
    CS1238_IO_Init(); //关闭REF输出,ADC输出640HZ,PGA1,通道选择A Write_AdReg(0x60); Rd_AdReg(); } 

然后调用CS1238读ADC的函数是返回一个24bit的数据,一般我习惯把他换算成mV的单位。

//计算CS1238的输入电压 float Get_CS1238_Voltage(void) { 
    CS1238_DATA=read_cs1238_data(); //获取cs1238的AD数值 CS1238_IN=(CS1238_DATA/)*CS1238_REF; //计算差分输入的电压,位满载 CS1238_AINP1=CS1238_IN/2+CS1238_AINN1; //计算CS1238的+输入 u2_printf("CS1238_IN=%.0fmV \r\n",CS1238_IN); u2_printf("CS1238_AINP1=%.0f mV \r\n",CS1238_AINP1); u2_printf("CS1238_AINN1=%.0f mV \r\n",CS1238_AINN1); } 

CS1237和CS1238的用法一样,只不过CS1237的输入只有一组差分输入。最后附上工程代码和资料,需要的可以联系我(不是白嫖的)。
在这里插入图片描述

小讯
上一篇 2025-03-29 17:34
下一篇 2025-02-05 21:23

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/16304.html