ADC芯片CS1238,CS1237介绍和代码

ADC芯片CS1238,CS1237介绍和代码CS1238 是一款高精度 低功耗模数转换芯片 两路差分输入通道 内置温度传感器和高精度振荡器

大家好,欢迎来到IT知识分享网。

一.芯片介绍

二.硬件设计

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); } 
//一个时钟周期 //高电平不能超过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的寄存器,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); } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/122239.html

(0)
上一篇 2025-10-18 10:20
下一篇 2025-10-18 10:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信