大家好,欢迎来到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