简介
ADC芯片大多数就使用在采集数据上面,与传感器等元器件配合使用做带有数据采集方面的方案开发。
CS1243是一款高精度24位Sigmal-Delta模数转换器(ADC),内部集成低噪声放大器。CS1243有效精度(ENOB)可达22位,可广泛应用于高精度测量领域。
芯片CS1237具有一路差分输入通道,内置温度传感器和高精度振荡器等功能,主要使用在精密测量及控制系统上面。
使用背景
本文主要使用CS1243芯片采集应变片数据。
代码实现
/*****************************************
* CS1237 designed by Robert Lee *
* *
*****************************************/
#include "cs1237.h"
void CS1237_SCK_High(void);
void CS1237_SCK_Low(void);
void CS1237_DOUT_High(void);
void CS1237_DOUT_Low(void);
bool CS1237_DOUT_Status(void);
#define ADC_Bit 24 //ADC有效位数,带符号位 最高24位
#define SCK_1 CS1237_SCK_High()
#define SCK_0 CS1237_SCK_Low()
#define DAT_1 CS1237_DOUT_High()
#define DAT_0 CS1237_DOUT_Low()
#define CS_CON 0X00 //芯片地配置 内部REF 输出10HZ PGA=1 通道A 0X00
#define Lv_Bo 0.01 //滤波系数 小于1
static long AD_Res_Last=0;//上一轮的ADC数值保存
void CS1237_DOUT_High(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = data_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(data_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(data_GPIO_Port, data_Pin, GPIO_PIN_SET);
}
void CS1237_DOUT_Low(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = data_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(data_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(data_GPIO_Port, data_Pin, GPIO_PIN_RESET);
}
bool CS1237_DOUT_Status(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = data_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(data_GPIO_Port, &GPIO_InitStruct);
if(HAL_GPIO_ReadPin(data_GPIO_Port, data_Pin))
return true;
else
return false;
}
void CS1237_SCK_High(void)
{
HAL_GPIO_WritePin(sck_GPIO_Port, sck_Pin, GPIO_PIN_SET);
}
void CS1237_SCK_Low(void)
{
HAL_GPIO_WritePin(sck_GPIO_Port, sck_Pin, GPIO_PIN_RESET);
}
//
//
//OUT引脚输入输出 方向设置 PA3
#define OUT_IN() {}
#define OUT_OUT() {}
// PA2-----CLK
// PA3-----OUT
void Delay1us(void)
{
delay_us(1);
}
void Delay1ms(void)
{
HAL_Delay(1);
}
void delay_ms(__IO uint16_t ms)
{
do{
Delay1ms();
}while(ms--);
}
// 初始化PA2 PA3
// PA2-----CLK
// PA3-----OUT
void CS1237_Init_JX(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(sck_GPIO_Port, sck_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = sck_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(sck_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = data_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(data_GPIO_Port, &GPIO_InitStruct);
}
//配置CS1237芯片
void CS1237_Config(void)
{
unsigned char i;
unsigned char dat;
unsigned int count_i=0;//溢出计时器
dat = 0X0C; //芯片地配置 内部REF 输出40HZ PGA=128 通道A 0X1C
OUT_OUT();
CS1237_DOUT_High(); //OUT引脚拉高
OUT_IN();
CS1237_SCK_Low();// 时钟拉低
while(CS1237_DOUT_Status()==1) //等待CS237准备好
{
delay_ms(1);
count_i++;
if(count_i > 300)
{
OUT_OUT();
CS1237_DOUT_High(); // OUT引脚拉高
CS1237_SCK_High(); // CLK引脚拉高
return;//超时,则直接退出程序
}
}
for(i=0;i<29;i++)// 1 - 29
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
OUT_OUT();
CS1237_SCK_High();Delay1us();CS1237_DOUT_High();CS1237_SCK_Low();Delay1us();//30
CS1237_SCK_High();Delay1us();CS1237_DOUT_High();CS1237_SCK_Low();Delay1us();//31
CS1237_SCK_High();Delay1us();CS1237_DOUT_Low();CS1237_SCK_Low();Delay1us();//32
CS1237_SCK_High();Delay1us();CS1237_DOUT_Low();CS1237_SCK_Low();Delay1us();//33
CS1237_SCK_High();Delay1us();CS1237_DOUT_High();CS1237_SCK_Low();Delay1us();//34
CS1237_SCK_High();Delay1us();CS1237_DOUT_Low();CS1237_SCK_Low();Delay1us();//35
CS1237_SCK_High();Delay1us();CS1237_DOUT_High();CS1237_SCK_Low();Delay1us();//36
//37 写入了0x65
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
for(i=0;i<8;i++)// 38 - 45个脉冲了,写8位数据
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
if(dat&0x80)
CS1237_DOUT_High();// OUT = 1
else
CS1237_DOUT_Low();
dat <<= 1;
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
CS1237_DOUT_High();// OUT = 1
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
// 读取芯片的配置数据
unsigned char Read_Config(void)
{
unsigned char i;
unsigned char dat=0;//读取到的数据
unsigned int count_i=0;//溢出计时器
// unsigned char k=0,j=0;//中间变量
OUT_OUT();
CS1237_DOUT_High(); //OUT引脚拉高
OUT_IN();
CS1237_SCK_Low();//时钟拉低
while(CS1237_DOUT_Status())//等待芯片准备好数据
{
delay_ms(1);
count_i++;
if(count_i > 300)
{
OUT_OUT();
CS1237_SCK_High(); // CLK=1;
CS1237_DOUT_High(); // OUT=1;
return 1;//超时,则直接退出程序
}
}
for(i=0;i<29;i++)// 产生第1到29个时钟
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
OUT_OUT();
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_High();
CS1237_SCK_Low(); // CLK=0;
Delay1us();// 这是第30个时钟
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_Low();
CS1237_SCK_Low(); // CLK=0;
Delay1us();// 这是第31个时钟
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_High();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//32
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_Low();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//33
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_High();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//34
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_High();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//35
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_DOUT_Low();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//36
CS1237_DOUT_High();
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();//37 写入0x56 即读命令
dat=0;
OUT_IN();
for(i=0;i<8;i++)// 第38 - 45个脉冲了,读取数据
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
dat <<= 1;
if(CS1237_DOUT_Status()==1)
dat++;
}
//第46个脉冲
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
OUT_OUT();
CS1237_DOUT_High(); //OUT引脚拉高
return dat;
}
//读取ADC数据,返回的是一个有符号数据
int32_t Read_CS1237(void)
{
unsigned char i;
uint32_t dat=0;//读取到的数据
unsigned int count_i=0;//溢出计时器
int32_t temp;
OUT_OUT();
CS1237_DOUT_High(); //OUT引脚拉高
OUT_IN();
CS1237_DOUT_Low(); //时钟拉低
while(CS1237_DOUT_Status()==1)//等待芯片准备好数据
{
delay_ms(1);
count_i++;
if(count_i > 300)
{
OUT_OUT();
CS1237_SCK_High(); // CLK=1;
CS1237_DOUT_High(); // OUT=1;
return 1;//超时,则直接退出程序
}
}
dat=0;
for(i=0;i<24;i++)//获取24位有效转换
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
dat <<= 1;
if(CS1237_DOUT_Status()==1)
dat ++;
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
for(i=0;i<3;i++)//接着前面的时钟 再来3个时钟
{
CS1237_SCK_High(); // CLK=1;
Delay1us();
CS1237_SCK_Low(); // CLK=0;
Delay1us();
}
OUT_OUT();
CS1237_DOUT_High(); // OUT = 1;
if(dat&0x00800000)// 判断是负数 最高位24位是符号位
{
temp=-(((~dat)&0x007FFFFF) + 1);// 补码变源码
}
else
temp=dat; // 正数的补码就是源码
return temp;
}