CS1237芯片是一枚国产24位A/D转换芯片,输出速率可选:10Hz、40Hz、640Hz、1.28kHz。内置时钟电路,不需外部晶振。带可编程PGA,PGA放大倍数可选:1、2、64、128。2 线 SPI通信接口,最快速率为 1.1MHz。供电电压:5V/3.3V。芯片应用场合:工业过程控制、电子秤、血压计、智能变换器、便携式设备等。
CS1237采用SOP8封装,Pin脚定义如下:
CS1237 SPI 串口通信
其基本时序如图所示:
CS1237读取数据时序图1:
CS1237读取数据时序图 2:
读取数据时序表:
功能配置:
SPI命令字:
CS1237有 2 个命令字,命令字的长度为 7bits,命令字描述如下:
CS1237命令字说明表:
CS1237 Config寄存器:
有了这些,就可以写CS1237的驱动库函数了。新建两个文件分别以cs1237.h,cs1237.c存入C51 Template文件夹下Library文件夹中。完成后的头文件如下:
/*cs1237.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 12/10/2021
*/
#ifndef __CS1237_H__
#define __CS1237_H__
#include "mtype.h"
#include "delay.h"
#include "myport.h" //CS1237_SCLK and CS1237_DOUT were defined
extern FSYSCLOCK FSCLK;
//************************************************************************************************************
typedef enum
{
C1237_10HZ = 0,
C1237_40HZ = 1,
C1237_640HZ = 2,
C1237_1280HZ = 3
}C1237_SPEED;
//************************************************************************************************************
typedef enum
{
C1237_PGA_1 = 0,
C1237_PGA_2 = 1,
C1237_PGA_64 = 2,
C1237_PGA_128 = 3
}C1237_PGA;
//************************************************************************************************************
typedef enum
{
C1237_CHA = 0, //adc channel
C1237_RST = 1, //cheap reserved
C1237_TEM = 2, //temperature test
C1237_INS = 3 //internal short
}C1237_CHN;
/************************************************************************************************************
Function: C1237_InClk();
Return value: void
Discription: C1237 input a clk pusle for to read or write
Example:
C1237_InClk();
*************************************************************************************************************/
void C1237_InClk();
/************************************************************************************************************
Function: CS1237_ReadReg();
Return value: ui8
Discription: read CS1237 register
Example:
CS1237_ReadReg();
*************************************************************************************************************/
ui8 CS1237_ReadReg();
/************************************************************************************************************
Function: C1237_WriteReg(ui8 mData);
Return value: void
Discription: wreite data to C1237 register
Example:
C1237_WriteReg(mData);
*************************************************************************************************************/
void C1237_WriteReg(ui8 mData);
/************************************************************************************************************
Function: C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn);
Return value: void
Discription: CS1237 init
Example:
C1237_Init(0,C1237_10HZ,C1237_PGA_1,C1237_CHA);//ref voltage out disable,speed 10Hz,Pga 1, work at Adc mode
*************************************************************************************************************/
void C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn);
/************************************************************************************************************
Function: C1237_ReadResult();
Return value: ui32
Discription: read C1237 A/D result
Example:
C1237_ReadResult();
*************************************************************************************************************/
ui32 C1237_ReadResult();
#endif
完成后的源代码如下:
/*cs1237.c
Designed by Bill Liu
Version 0.1
Modified last by Bill Liu on 2/18/2022
*/
#include "cs1237.h"
//*************************************************************************************************************
void C1237_InClk()
{
CS1237_SCLK= 1;
Delayxus(2,FSCLK);
CS1237_SCLK = 0;
Delayxus(2,FSCLK);
}
//End of C1237_InClk()
//*************************************************************************************************************
ui8 CS1237_ReadReg()
{
ui8 i = 0;
ui8 tem = 0;
CS1237_SCLK = 0;
CS1237_DOUT = 1;
while( CS1237_DOUT);
for(i = 0; i < 27; i++) //1-26th CLK
C1237_InClk();;
CS1237_DOUT = 1; //cs1237 direction input
//C1237_InClk(); //27th CLK
C1237_InClk(); //28th CLK
C1237_InClk(); //29th CLK
tem = 0x56;
for(i = 0; i < 7; i++) //30~36th CLK
{
if(tem &0x40)
CS1237_DOUT = 1;
else
CS1237_DOUT = 0;
C1237_InClk();;
tem <<= 1;
}
CS1237_DOUT = 1; //cs1237 change to output direction
C1237_InClk();; //37th CLK
for(i = 0; i < 8; i++) //37~45th CLK
{
tem <<= 1;
C1237_InClk();
if(CS1237_DOUT)
tem++;
}
C1237_InClk();; //46th CLK
return tem;
}
//End of CS1237_ReadReg()
//*************************************************************************************************************
void C1237_WriteReg(ui8 mData)
{
ui8 i = 0;
ui8 tem = 0;
CS1237_SCLK = 0;
CS1237_DOUT = 1;
while(CS1237_DOUT);
for(i = 0; i < 27; i++) //1~26th CLK
C1237_InClk();
CS1237_DOUT = 1; //force high
//C1237_InClk();//27th CLK
C1237_InClk();//28th CLK
C1237_InClk();//29th CLK
tem = 0x65;
for(i = 0; i < 7; i++)//30~36th CLK
{
if(tem & 0x40)
CS1237_DOUT = 1;
else
CS1237_DOUT = 0;
C1237_InClk();
tem <<= 1;
}
CS1237_DOUT = 0; //direction chage to intput direction
C1237_InClk(); //37th CLK
for(i = 0; i < 8; i++) //38~45th CLK
{
if(mData&0x80)
CS1237_DOUT = 1;
else
CS1237_DOUT = 0;
mData <<= 1;
C1237_InClk();
}
C1237_InClk();//46th CLK
}
//End of C1237_WriteReg(ui8 mData)
//*************************************************************************************************************
void C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn)
{
ui8 tem = 0;
if(refOutable)
ResetBit(&tem, 6);
else
SetBit(&tem, 6);
SetBits(&tem,5,4,msel);
SetBits(&tem,3,2,mselPga);
SetBits(&tem,1,0,mselChn);
C1237_WriteReg(tem);
}
//End of C1237_Init(BOOL refOutable,C1237_SPEED msel,C1237_PGA mselPga,C1237_CHN mselChn)
//*************************************************************************************************************
ui32 C1237_ReadResult()
{
ui8 i;
ui32 rdata = 0;
CS1237_SCLK= 0;
CS1237_DOUT = 1;
while(CS1237_DOUT); //waite ADC finish
for(i = 0; i < 24; i++)
{
rdata <<= 1;
C1237_InClk();
if(CS1237_DOUT) //read data
rdata++;
}
C1237_InClk();
C1237_InClk();
C1237_InClk();
return rdata;
}
//End of C1237_ReadResult()
受一些因素影响,可能个别ADC数据不是很准确,需要消除或减小其影响,我们可以采用多值平均法,阀值剔除法等数字滤波手法,有了以上库函数就可以轻松实现。读写验证如下:
上面串口接收区的值为寄存器读出值。
下面是AD转换结果。