#include "ADS869x.h"
#include "delay.h"
#include "math.h"
#include "LED.h"
#include "OLED.h"
#include "iwdg.h"
#define N 5 //中值滤波算法 数据个数
//定义全局变量
unsigned char G_ACTIVE_FLAG=0x00; //定义输入电压过高标志位
unsigned long G_VAL=131076;
float G_RANGE=6;
unsigned char G_F_Flag =0;
//滤波算法 中值滤波算法
/*************************
程序功能:滤波算法 中值滤波算法
参数:无
返回值:滤波 实际电压值的1000,000倍
**************************/
unsigned long Get_ADC_Value(void)
{
unsigned long value_buf[N];
char count,i,j;
unsigned long temp;
for ( count=0;count<N;count++)
{
// ADS869x_ReadREG(0x04);
value_buf[count] = ADS869x_ReadData()>>14;
// ADS869x_ReadREG(0x04);
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf[i]>value_buf[i+1] )
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}
/*************************
程序功能:获取电压值
参数:无
返回值:实际电压值的1000,000倍
**************************/
unsigned long Get_Vol(void)
{
unsigned long vol=0;
static unsigned long Rvol=0;
float temp=0;
ADS869x_NAP_EXIT(); //退出休眠模式 进行采样
// delay_us(20);
vol = Get_ADC_Value(); //进行ADC采样
ADS869x_GO_NAP(); //采样完成进入休眠模式
ADS869x_GO_PD(); //采样完成进入PD模式
if(vol>=G_VAL)
{
vol = vol-G_VAL;
temp = vol*4.096/pow(2,18)*G_RANGE; //计算实际的电压值
vol = temp*1000000; //实际电压值*1 v 000 mv 000 uv 将实际电压值放大 1000 000倍
G_F_Flag=0; //正数标记
}
else
{
vol = G_VAL - 1 - vol;
temp = vol*4.096/pow(2,18)*G_RANGE;
vol = temp*1000000;
G_F_Flag=1; //负数标记
}
/*配置输入范围
0000b 正负 3*4.096 0x0000 6
0001b 正负 2.5*4.096 0x0001
0010b 正负 1.5*4.096 0x0002 3
0011b 正负 1.25*4.096 0x0003
0100b 正负0.626*4.096 0x0004 1.25
*/
if ( temp<2 && G_RANGE!=1.25 )
{
ADS869x_WriteREG(ADS869x_RANGE_SEL,0x0004); //配置 输入范围为 0000b 正负2.5*4.096
G_RANGE=1.25;
OLED_ShowString(110,6,"2 ");
G_VAL=131087;
return Rvol;
}
else if( temp>=2 && temp<5 && G_RANGE!=3)
{
ADS869x_WriteREG(ADS869x_RANGE_SEL,0x0002); //配置 输入范围为 0000b 正负1.5*4.096
G_RANGE=3;
OLED_ShowString(110,6,"5 ");
G_VAL=131078;
return Rvol;
}
else if(temp >=5 && G_RANGE!=6 )
{
ADS869x_WriteREG(ADS869x_RANGE_SEL,0x0000); //配置 输入范围为 0000b 正负2.5*4.096
G_RANGE=6;
OLED_ShowString(110,6,"10");
G_VAL=131076;
return Rvol;
}
else if (temp >10.05)
{
// ALARM_ON();
}
else
{
Rvol = vol;
}
return Rvol;
}
/*************************
程序功能:ADS869x_IO_Init
参数:无
返回值:无
**************************/
void ADS869x_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能A端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOD3,6
GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOD3,6
ADS869x_RST_Clr();
delay_ms(10);
ADS869x_RST_Set();
}
/*************************
程序功能:ADS869x读写8位数据
参数:
dat: 写入的值
返回值:无
**************************/
unsigned char ADS869x_ReadWrite(unsigned char dat)
{
unsigned char i,temp=0;
// while(!ADS869x_RVS); //RVS 为高才能写;
for(i=0;i<8;i++)
{
ADS869x_SCLK_Clr(); //拉低时钟
delay_us(20);
if(dat&0x80) ADS869x_MOSI_Set();
else ADS869x_MOSI_Clr();
dat<<=1;
ADS869x_SCLK_Set();
delay_us(10);
temp<<=1;
if(ADS869x_MISO) temp++;
}
return temp;
}
/*************************
程序功能:ADS869x_SendCMD 写命令
参数:cmd: 写入的命令
dat: 写入的地址
返回值:无
**************************/
void ADS869x_SendCMD(unsigned char cmd,unsigned char addr)
{
ADS869x_CS_Clr(); //拉低片选,开始接受数据或者命令。
ADS869x_ReadWrite(cmd); //发送命令。
ADS869x_ReadWrite(addr); //发送地址
ADS869x_ReadWrite(0x00);
ADS869x_ReadWrite(0x00);
ADS869x_CS_Set(); //拉高片选,开始命令转换。
}
/*************************
程序功能:ADS869x_ReadREG读数据
参数:无
返回值:接收的32 位数据
**************************/
unsigned long ADS869x_ReadREG(unsigned char addr)
{
unsigned long sum=0;
ADS869x_SendCMD(ADS869x_READ_HWORD,addr+2); //先读高16位地址的值 #define ADS869x_READ_HWORD 0xC8
// delay_ms(10);
sum = ADS869x_ReadData(); //读高16位
ADS869x_SendCMD(ADS869x_READ_HWORD,addr); //后读低16位地址的值 #define ADS869x_READ_HWORD 0xC8
sum |= (ADS869x_ReadData()>>16);
return sum; //返回数据
}
/************************************************************/
/*************************
程序功能:ADS869x_WriteREG 写寄存器
参数:regaddr:寄存器地址
dat: 写入的值 16bit
返回值:无
**************************/
void ADS869x_WriteREG(unsigned char regaddr,unsigned short dat)
{
unsigned char dat_H=0,dat_L=0;
dat_L = dat;
dat_H = dat>>8;
ADS869x_CS_Clr(); //拉低片选,接受命令
ADS869x_ReadWrite(ADS869x_WRITE); //发送写命令
ADS869x_ReadWrite(regaddr);
ADS869x_ReadWrite(dat_H);
ADS869x_ReadWrite(dat_L);
ADS869x_CS_Set(); //拉高片选,进入命令操作。
}
/*************************
程序功能:ADS869x_ReadData读数据
参数:无
返回值:接收的32 位数据
**************************/
unsigned long ADS869x_ReadData(void)
{
unsigned char i=0;
unsigned long sum=0;
unsigned long r=0;
// while(!ADS869x_RVS); //当DRDY为低是才能写指令
ADS869x_CS_Clr();
delay_us(25); //延时时间
for(i=0;i<4;i++) //接收数据32位
{
sum = sum << 8;
r = ADS869x_ReadWrite(0x00); //接收数据
sum |= r;
}
ADS869x_CS_Set();
return sum; //返回数据
}
/*************************
程序功能:ADS869x_Over_Judgment FLAG判断
参数:无
返回值:无
**************************/
void ADS869x_Over_Judgment(void)
{
unsigned char i=0;
unsigned long sum=0;
unsigned long r=0;
IWDG_Feed();
// while(!ADS869x_RVS); //当DRDY为低是才能写指令
ADS869x_CS_Clr();
delay_us(25); //延时时间
for(i=0;i<4;i++) //接收数据32位
{
sum = sum << 8;
r = ADS869x_ReadWrite(0x00); //接收数据
sum |= r;
}
ADS869x_CS_Set();
//判断范围
switch(sum&0x3C)
{
case 0x08 : G_ACTIVE_FLAG = 0x01;LED = 1;break;
case 0x04 : G_ACTIVE_FLAG = 0x02;LED = 1;break;
case 0x20 : G_ACTIVE_FLAG = 0x03;LED = 1;break;
case 0x10 : G_ACTIVE_FLAG = 0x04;LED = 1;break;
default: G_ACTIVE_FLAG=0; LED = 0;break;
}
}
/************************************************************/
/*************************
程序功能:ADS869x_GO_NAP进入睡眠模式
参数:无
返回值:接收的32 位数据
**************************/
void ADS869x_GO_NAP(void)
{
ADS869x_WriteREG(0x04,0x6900); //向寄存器地址05H中写入数据69H解锁RST寄存器
ADS869x_WriteREG(0x04,0x0002); //向寄存器地址04H中写入数据69H解锁RST寄存器
// ADS869x_ReadREG(0x04);
}
/*************************
程序功能:ADS869x_NAP_EXIT退出睡眠模式
参数:无
返回值:接收的32 位数据
**************************/
void ADS869x_NAP_EXIT(void)
{
ADS869x_WriteREG(0x04,0x6900); //向寄存器地址05H中写入数据69H解锁RST寄存器
ADS869x_WriteREG(0x04,0x0000); //向寄