#include "ads1220.h" #include "app.h" unsigned char PolarFlag; unsigned char Init_Config[4],channel0[8],channel1[8],channel2[8],channel3[8]; unsigned char i; /*************************************************************************** 接线顺序 *************************************************************************/ //PB0 DRDY //PA7 MISO #define DIN_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET); //PA7 MOSI #define DIN_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET); //PA7 MOSI #define SCK_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); //PA5 SCK #define SCK_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET); //PA5 SCK #define CS_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //PA4 CS1 #define CS_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET); //PA4 CS1 #define ADS1220_MISO HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6) #define ADS1220_DRDY HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_4) #define DALAY_CNT 1000 void ADS1220_GPIOInit(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin = GPIO_PIN_5|GPIO_PIN_7; //PA5 PA7 端口配置 MOSI&SCLK GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; //IO口速度为50MHz HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5|GPIO_PIN_6,GPIO_PIN_SET); GPIO_InitStructure.Pin = GPIO_PIN_6; //端口配置 PA6 MISO GPIO_InitStructure.Mode = GPIO_MODE_INPUT; //上拉输入 GPIO_InitStructure.Pull = GPIO_PULLUP ; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO_InitStructure.Pin = GPIO_PIN_4; //端口配置 PC4 DRDY GPIO_InitStructure.Mode = GPIO_MODE_INPUT; //上拉输入 GPIO_InitStructure.Pull = GPIO_PULLUP; //IO口速度为50MHz HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.Pin = GPIO_PIN_4; //端口配置 PA4 CS GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; //IO口速度为50MHz HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); } /*************************************************************************** 函数名称:WriteOneByte(unsigned char 命令) 用途:写入一个字节到ADS1220 *************************************************************************/ void WriteOneByte(unsigned char command) { unsigned char i; for(i = 0; i < 8;i++) { if(command&0x80) { DIN_H;//ADS1220_DIN = 1 } else { DIN_L;//ADS1220_DIN = 0;/ } command <<= 1; delay_us(10); SCK_H;//ADS1220_SCK = 1; delay_us(10); SCK_L;//ADS1220_SCK = 0; delay_us(10); } } /*************************************************************************** *函数名称:ReadOneByte() *用途:从ADS1220读取一个字节 *************************************************************************/ unsigned char ReadOneByte(void) { unsigned char result,i; SCK_L;//SCLK_L; for(i = 0;i<8; i++) { SCK_H; delay_ns(1); result <<= 0x01; if(ADS1220_MISO) result |= 0X01; SCK_L; delay_ns(1); } return result; } /*************************************************************************** *函数名称:ReadData() *用途:从ADS1220读取数据 *************************************************************************/ unsigned long ReadData(void) { unsigned long adval; unsigned char a,b,c; CS_L; delay_ns(10); WriteOneByte(RDATA); a = ReadOneByte(); b = ReadOneByte(); c = ReadOneByte(); adval = a; adval = (adval<<8) | b; adval = (adval<<8) | c; delay_ns(10); CS_H; return adval; } /*************************************************************************** *函数名称:ADReset() *用途:复位ADS1220 *************************************************************************/ void ADReset(void) { CS_L; delay_ns(1); WriteOneByte(RESET); CS_H; } /*************************************************************************** 函数名称:ADS1220_Init() *用途:ADS120初始化 *************************************************************************/ void ADS1220_Init(void) { CS_H; SCK_H; DIN_H; ADReset(); } /*************************************************************************** *函数名称:关闭电源() *************************************************************************/ void ADPowerDown(void) { CS_L; WriteOneByte(POWERDOWN); CS_H; } /*************************************************************************** *函数名称:ADStartConversion() *用途:开始转换 *参数: *************************************************************************/ void ADStartConversion(void) { CS_L; WriteOneByte(START); CS_H; } /*************************************************************************** *函数名称:ReadRegister() *用途:从寄存器中读取数据 *参数:数据 *************************************************************************/ void ReadRegister(void) { unsigned char i; unsigned long Data; CS_L; WriteOneByte(RREG|0x03); for (i=0; i< 4; i++) { Data += ReadOneByte(); } CS_H; } /*************************************************************************** *函数名:WriteRegister(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData) *用途:向寄存器写入数据 *步骤:写地址2。写入数据 * Params NumRegs-----寄存器的数字 *************************************************************************/ void WriteRegister(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData) { unsigned char i; CS_L; WriteOneByte(WREG | (((StartAddress<<2) & 0x0c) |((NumRegs-1)&0x03))); for (i=0; i< NumRegs; i++) { WriteOneByte(*pData); pData++; } CS_H; } /*************************************************************************** 函数名称:CofigAD(unsigned char channel) *用途:设置采样通道 *参数: *************************************************************************/ void CofigAD(unsigned char channel) { switch(channel) { case 0: Init_Config[0] = MUX_8 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN0,AINN = AVSS ,PGA = 1,禁用PGA break; case 1: Init_Config[0] = MUX_9 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN1,AINN = AVSS ,PGA = 1,禁用PGA break; case 2: Init_Config[0] = MUX_10 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN2,AINN = AVSS,PGA = 1,禁用PGA break; case 3: Init_Config[0] = MUX_11 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN3,AINN = AVSS,PGA = 1,禁用PGA break; case 4: Init_Config[0] = MUX_0 | PGA_0 | PGA_BYPASS_Disable;//差分模式,选择通道AINP = AIN0,AINN = AIN1(默认设置),PGA = 1,禁用PGA break; } Init_Config[1] = 0XC0; Init_Config[2] = 0X00; Init_Config[3] = 0X00; WriteRegister(0x00,0x04,Init_Config); ReadRegister(); } /*************************************************************************** *函数名:GetAD(unsigned char channel) *目的:得到结果 *************************************************************************/ float GetAD(unsigned char channel) { float Result_f; unsigned long Result; unsigned long delay_cnt = 0; CofigAD(channel); ADStartConversion(); while(ADS1220_DRDY) { delay_cnt++; if(delay_cnt > DALAY_CNT) { break; } } Result = ReadData(); ADPowerDown(); if(Result & 0x800000) { PolarFlag = 1; Result = ~Result; Result = Result&0xffffff; Result = Result+1; } else PolarFlag =0; // Result_f = (float)Result*1000*2.5/(1048575);//20位精度 Result_f = (float) (2.5 / 0x7fffff) * Result*1000; Result_f =Result_f *2033/2488; return Result_f; } #define DEEPTH 100 float X_ads1220_temp[DEEPTH] = {0},X_ads1220_temp_fl[DEEPTH] = {0},filter_result = 0; char X_ads1220_cnt = 0,full_flag = 0; float Xads1220_filter(char head, char tail) //对20维的数组进行中值滤波 { if(full_flag == 0) return 0; // float t = 0; char i = 0;//,j = 0; filter_result = 0; for(i = 0 ;i < DEEPTH ;i++) X_ads1220_temp_fl[i] = X_ads1220_temp[i]; // for( i = 0 ;i < 19 ;i++) //对此时的20个数据进行升序排序 // { // for(j = i+1;j < 20;j++) // { // if( X_ads1220_temp_fl[i] > X_ads1220_temp_fl[j] ) // { // t = X_ads1220_temp_fl[i]; // X_ads1220_temp_fl[i] = X_ads1220_temp_fl[j]; // X_ads1220_temp_fl[j] = t; // } // } // } QuickSort(X_ads1220_temp_fl, 0, DEEPTH - 1); for( i = head - 1;i < tail;i++) //对 head - tail 之间的数取均值 { filter_result += X_ads1220_temp_fl[i]; } filter_result /= (tail - head + 1); return filter_result; } void Xads1220_record(void) { if(it_1ms_flag == 1) //每隔Xms记录一次ADC值,100维数组循环记录 { it_1ms_flag = 0; X_ads1220_cnt *= (X_ads1220_cnt < DEEPTH); X_ads1220_temp[X_ads1220_cnt] = GetAD(4); X_ads1220_cnt++; } if(X_ads1220_cnt == 100) full_flag = 1; } /*************************快速排序*************************/ void Swap(float* pa, float* pb) { float tmp = *pa; *pa = *pb; *pb = tmp; } //hoare单趟排序 --- 左边做key int PartSort(float* a, int left, int right) { int keyi = left; //左边做key,保存的是key的下标 while (left < right) { //右边先走,找小 //为什么用等于呢?如果keyi和right位置的值相等,那么就会出现死循环 //为什么要加一个 left= a[keyi]) { --right; } //左边后走,找大 while (left < right && a[left] <= a[keyi]) { ++left; } //然后交换左右 Swap(&a[left], &a[right]); } //当left == right的时候,跳出循环,交换和keyi的值 Swap(&a[keyi], &a[left]); //返回相遇位置的下标 return left; } //快速排序递归实现的主框架 void QuickSort(float* a, int begin, int end) { //子区间相等只有一个值,或者不存在,那么就是递归结束的子问题 if (begin >= end) { return; } int keyi = PartSort(a, begin, end); //递归左区间 [begin, keyi-1] QuickSort(a, begin, keyi - 1); //递归右区间 [keyi+1, end] QuickSort(a, keyi + 1, end); } /*************************快速排序*************************/