hc32f460 CS1243 AD采集芯片使用

简介

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;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值