#include "main.h"
#include "CS1237.h" //20bit ADC
#define ADC_Bit 20 //ADC有效位数,带符号位 最高24位
#define SCK_1 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET)
#define SCK_0 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET)
#define DAT_1 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET)
#define DAT_0 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET)
#define DOUT (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)==GPIO_PIN_SET)
#define NOP_5() for(int i=10;i>0;i--);
#define NOP30() NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();
#define NOP40() NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();NOP_5();
#define One_CLK SCK_1;NOP40();SCK_0;NOP40();
#define CS_CON 0X0C //芯片地配置 内部REF 输出40HZ PGA=128 通道A 0X1C
void CS1237_init()
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void DATAIN(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*Configure GPIO pin : PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void DATAOUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*Configure GPIO pin : PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
//延时500US 25MHZ
void delay_500us(unsigned char a)
{
unsigned char i,j,b;
for(b=0;b<a;b++)
{
i = 13;
j = 37;
do
{
while (--j);
} while (--i);
}
}
//配置CS1237芯片
void Con_CS1237(void)
{
unsigned char i;
unsigned char dat;
unsigned char count_i=0;//溢出计时器
dat = CS_CON;// 0100 1000
DATAIN();
SCK_0;//时钟拉低
while(DOUT)//芯片准备好数据输出 时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好
{
delay_500us(10);
count_i++;
if(count_i > 150)
{
DATAOUT();
SCK_1;
DAT_1;
return;//超时,则直接退出程序
}
}
DATAOUT();
for(i=0;i<29;i++)// 1 - 29
{
One_CLK;
}
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//30
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//31
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//32
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//33
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//34
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//35
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//36
One_CLK;//37 写入了0x65
for(i=0;i<8;i++)// 38 - 45个脉冲了,写8位数据
{
SCK_1;NOP40();
if(dat&0x80)
DAT_1;
else
DAT_0;
dat <<= 1;
SCK_0;NOP40();
}
One_CLK;//46个脉冲拉高数据引脚
}
//读取芯片的配置数据
unsigned char Read_CON(void)
{
unsigned char i;
unsigned char dat=0;//读取到的数据
unsigned char count_i=0;//溢出计时器
DATAIN();
SCK_0;//时钟拉低
while(DOUT)//芯片准备好数据输出 时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好
{
delay_500us(10);
count_i++;
if(count_i > 150)
{
SCK_1;
DAT_1;
return 1;//超时,则直接退出程序
}
}
DATAOUT();
for(i=0;i<29;i++)// 1 - 29
{
One_CLK;
}
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//30
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//31
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//32
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//33
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//34
SCK_1;NOP30();DAT_1;SCK_0;NOP30();//35
SCK_1;NOP30();DAT_0;SCK_0;NOP30();//36
DAT_1;
One_CLK;//37 写入了0x56
DATAIN();
dat=0;
for(i=0;i<8;i++)// 38 - 45个脉冲了,读取数据
{
One_CLK;
dat <<= 1;
if(DOUT)
dat++;
}
One_CLK;//46个脉冲拉高数据引脚
return dat;
}
//读取ADC数据,返回的是一个有符号数据
long Read_CS1237(void)
{
DATAOUT();
unsigned char i;
long dat=0;//读取到的数据
unsigned int count_i=0;//溢出计时器
DAT_1;//端口锁存1,51必备
SCK_0;//时钟拉低
DATAIN();
while(DOUT)//芯片准备好数据输出 时钟已经为0,数据也需要等CS1237拉低为0才算都准备好
{
delay_500us(10);
count_i++;
if(count_i > 300)
{
DATAOUT();
SCK_1;
DAT_1;
return 0;//超时,则直接退出程序
}
}
DATAOUT();
DAT_0;//端口锁存1,
DATAIN();
dat=0;
for(i=0;i<24;i++)//获取24位有效转换
{
dat <<= 1;
SCK_1;
NOP40();
if(DOUT)
dat ++;
SCK_0;
NOP40();
}
for(i=0;i<3;i++)//一共输入27个脉冲
{
One_CLK;
}
DATAOUT();
DAT_1;
//先根据宏定义里面的有效位,丢弃一些数据
i = 24 - ADC_Bit;//i表示将要丢弃的位数
dat >>= i;//丢弃多余的位数
return dat;
}
struct AD_Value Get_Adc_Average(int times)
{
struct AD_Value ad_value[5],result;
long item = 0,ad_item = 0;
int i = 0;
for(i = 0; i <times ; i++) //连续读取五次
{
ad_value[i].idex = i;
ad_item= Read_CS1237();
if((ad_item&0x000F0000) == 0x000F0000)// 判断是负数 最高位24位是符号位
{
ad_value[i].flag = 1;
ad_item=~(ad_item-0x00000001);
ad_item = ad_item& 0x000FFFFF;// 补码变源码
}
else ad_value[i].flag = 0;
ad_value[i].value =ad_item;
}
for(i = 0;i<times;i++) //大小排序
{
for(int j = 0;j<times;j++)
{
if(ad_value[i].value > ad_value[j].value)
{
item = ad_value[i].value;
ad_value[i].value = ad_value[j].value;
ad_value[j].value = item;
}
}
}
if(ad_value[1].flag == ad_value[2].flag && ad_value[1].flag == ad_value[3].flag)
{
result.flag = ad_value[1].flag;
result.value = (ad_value[1].value + ad_value[2].value + ad_value[3].value)/3;
return result;
}
else
return ad_value[2];
}
int Int_To_Str(unsigned long int x,unsigned char *Str)
{
int t;
unsigned char *Ptr,Buf[10]; //定义一个字符串数组和字符串指针,
int i = 0,bit = 0; //用于计数
Ptr = Str; //内部指针指向外部指针,进行参数传递,是属于源参数传递(通过地址),
if(x < 10) // 当整数小于10,转换为0x格式
{
*Ptr ++ = '0'; //单个数字前面补“0”
*Ptr ++ = x+0x30;
}
else
{
while(x > 0)
{
t = x % 10;
x = x / 10;
Buf[i++] = t+0x30; // 通过计算把数字编成ASCII码形式
bit ++;
}
i -- ;
for(;i >= 0;i --) // 将得到的字符串倒序
{
*(Ptr++) = Buf[i];
}
}
*Ptr = ' ';
*(Ptr+1) = '
';
return bit+2;
}
//
资料源自网络,侵删