⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pedometer.c

📁 基于ADI公司加速度传感器的计步器算法,MCU采用ATMega48,加速度传感器采用ADXL330
💻 C
📖 第 1 页 / 共 2 页
字号:
	TEMP=STEPS;
	for(itemp=0;itemp<3;itemp++)	//保存成3 Bytes结果,每个Byte只用其中的低7位
	{
		Step_Result[itemp]=TEMP & 0x007F;
		TEMP=TEMP>>7;
	}

//	Step_Result[4]=_vpp[2] & 0x00FF;
//	Step_Result[3]=_vpp[2]>>8;

//	sei();}


/*------------------------------------------------------------------------------------------------------------------------
*Name: 		TimeWindow()
*Function:	实现"时间窗"算法,认为只有在有效"时间窗"内的记步才有效,而且起始时需要连续出现有效步才认为开始
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void TimeWindow()
{
	if(ReReg==2)		//如果是新开始的第一步,直接在记步缓存中加1
	{
		TempSteps++;
		Interval=0;
		ReReg=1;
		InvalidSteps=0;	
	}
	else				//如果不是新开始的第一步
	{
		if((Interval>=TIMEWINDOW_MIN)&&(Interval<=TIMEWINDOW_MAX))	//如果时间间隔在有效的时间窗内
		{
			InvalidSteps=0;	
			if(ReReg==1)					//如果还没有找到规律
			{
				TempSteps++;				//记步缓存加1
				if(TempSteps>=REGULATION)	//如果记步缓存达到所要求的规律数
				{
					ReReg=0;				//已经找到规律
					STEPS=STEPS+TempSteps;	//更新显示
					TempSteps=0;
				}
				Interval=0;
			}
			else if(ReReg==0)				//如果已经找到规律,直接更新显示
			{
				STEPS++;
				TempSteps=0;
				Interval=0;
			}
		}
		else if(Interval<TIMEWINDOW_MIN)	//如果时间间隔小于时间窗下限
		{	
			if(ReReg==0)					//如果已经找到规律
			{
				if(InvalidSteps<255) 	InvalidSteps++;	//无效步缓存加1
				if(InvalidSteps>=INVALID)				//如果无效步达到所要求的数值,则重新寻找规律
				{	
					InvalidSteps=0;
					ReReg=1;
					TempSteps=1;
					Interval=0;
				}
				else									//否则,只丢弃这一次的记步,但是继续记步,不需要重新寻找规律
				{
					Interval=0;
				}
			}
			else if(ReReg==1)				//如果还没有找到规律,则之前的寻找规律过程无效,重新寻找规律
			{
				InvalidSteps=0;	
				ReReg=1;
				TempSteps=1;
				Interval=0;
			}
		}
		else if(Interval>TIMEWINDOW_MAX)	//如果时间间隔大于时间窗上限,记步已经间断,重新寻找规律
		{
			InvalidSteps=0;	
			ReReg=1;						
			TempSteps=1;
			Interval=0;
		}
	}		
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		Sample()
*Function:	实现采样算法.
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void Sample(){
	for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
	{
		adc_read(jtemp);
			
		Temp_Result[jtemp*2]=Adresult>>8;
		Temp_Result[jtemp*2+1]=Adresult & 0xFF;	
	}
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		step_counter()
*Function:	实现Pedometer的基本算法.
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void step_counter(){

//		PORTD=0xFF;

		//----------------------------------------------ADC采样----------------------//
		for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
		{
			adc_read(jtemp);
			
			//Step_Result[jtemp*2+5]=Adresult>>8;
			//Step_Result[jtemp*2+6]=Adresult & 0xFF;	
		
			_array3[jtemp]=_array2[jtemp];
			_array2[jtemp]=_array1[jtemp];
			_array1[jtemp]=_array0[jtemp];
			
       		_array0[jtemp]=Adresult;
       		_adresult[jtemp]=_array0[jtemp]+_array1[jtemp]+_array2[jtemp]+_array3[jtemp];
      	 	_adresult[jtemp]=_adresult[jtemp]>>2;
			if (_adresult[jtemp]>_max[jtemp])               {_max[jtemp]=_adresult[jtemp];}
			if (_adresult[jtemp]<_min[jtemp])               {_min[jtemp]=_adresult[jtemp];}
		}
		
//		PORTD=0x00;

      	sampling_counter=sampling_counter+1;
	
		//----------------------------------计算动态门限和动态精度-----------------------//
        if (sampling_counter==60)
        {               
          	sampling_counter=0;
				
			for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
			{
				_vpp[jtemp]=_max[jtemp]-_min[jtemp];
            	_dc[jtemp]=_min[jtemp]+(_vpp[jtemp]>>1);
				_max[jtemp]=0;
            	_min[jtemp]=1023;
				_bad_flag[jtemp]=0;
/*
				if (_vpp[jtemp]>=160)
				{
					_precision[jtemp]=_vpp[jtemp]/20;
				}
            	else if ((_vpp[jtemp]>=50)&& (_vpp[jtemp]<160))            
				{
					_precision[jtemp]=8;
				}
           		else if ((_vpp[jtemp]>=15) && (_vpp[jtemp]<50))  
                {
					_precision[jtemp]=4;
				}  
			
				else
           		{ 
              		_precision[jtemp]=2;
                	_bad_flag[jtemp]=1;
            	}
*/
				if (_vpp[jtemp]>=160)
				{
					_precision[jtemp]=_vpp[jtemp]/32; //8
				}
            	else if ((_vpp[jtemp]>=50)&& (_vpp[jtemp]<160))            
				{
					_precision[jtemp]=5;
				}
           		else if ((_vpp[jtemp]>=15) && (_vpp[jtemp]<50))  
                {
					_precision[jtemp]=3;
				}  
			
				else
           		{ 
              		_precision[jtemp]=2;
                	_bad_flag[jtemp]=1;
            	}

			}
      	}
		
		//--------------------------线性移位寄存器--------------------------------------

		for(jtemp=X_CHANNEL;jtemp<=Z_CHANNEL;jtemp++)
		{
			_old_fixed[jtemp]=_new_fixed[jtemp];

        	if (_adresult[jtemp]>=_new_fixed[jtemp])                         
        	{   
         		if((_adresult[jtemp]-_new_fixed[jtemp])>=_precision[jtemp])                    {_new_fixed[jtemp]=_adresult[jtemp];}
        	}
        	if (_adresult[jtemp]<_new_fixed[jtemp])
       	 	{   
           		if((_new_fixed[jtemp]-_adresult[jtemp])>=_precision[jtemp])                    {_new_fixed[jtemp]=_adresult[jtemp];}
        	}
		}

		//------------------------- 动态门限判决 ----------------------------------
		if ((_vpp[X_CHANNEL]>=_vpp[Y_CHANNEL])&&(_vpp[X_CHANNEL]>=_vpp[Z_CHANNEL]))
		{
			if ((_old_fixed[X_CHANNEL]>=_dc[X_CHANNEL])&&(_new_fixed[X_CHANNEL]<_dc[X_CHANNEL])&&(_bad_flag[X_CHANNEL]==0))        
			{
				TimeWindow();
				//STEPS=STEPS+1;
			} 
		}
		else if ((_vpp[Y_CHANNEL]>=_vpp[X_CHANNEL])&&(_vpp[Y_CHANNEL]>=_vpp[Z_CHANNEL]))
		{
			if ((_old_fixed[Y_CHANNEL]>=_dc[Y_CHANNEL])&&(_new_fixed[Y_CHANNEL]<_dc[Y_CHANNEL])&&(_bad_flag[Y_CHANNEL]==0))        
			{
				TimeWindow();
				//STEPS=STEPS+1;
			}
		}
		else if ((_vpp[Z_CHANNEL]>=_vpp[Y_CHANNEL])&&(_vpp[Z_CHANNEL]>=_vpp[X_CHANNEL]))
		{
			if ((_old_fixed[Z_CHANNEL]>=_dc[Z_CHANNEL])&&(_new_fixed[Z_CHANNEL]<_dc[Z_CHANNEL])&&(_bad_flag[Z_CHANNEL]==0))        
			{
				TimeWindow();
				//STEPS=STEPS+1;
			}
		}

		//---------------------------------- 保存结果-----------------------------------------
		Save_Result();
}


/*------------------------------------------------------------------------------------------------------------------------
*Name: 		Delay()
*Function:	延时
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void Delay( unsigned int TimeMS)	//Delay
{	
	int i,j,k;
	for(j=0;j<TimeMS;j++)
	{
		for(i=0;i<100;i++)
		{ 
			for(k=0;k<100;k++)
			{
				;
			}
		}
	}
}
/*------------------------------------------------------------------------------------------------------------------------
*Name: 		main()
*Function:	主函数,死循环等待
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
int main(void)
{
	unsigned char Addr;

	DDRD=0xFF;
	PORTD=0x00;

	Init();		//初始化

    //ReadEEPROM();				//Read EEPROM 
	while(1)					//死循环	{
		
		Delay(20);//延时,使采样率为50Hz
		
		if(Start_flag == 1)		//是否开始
		{ 
			PORTD=0x00;			//测试采样率
			PORTD=0xFF;

			step_counter();		//记步
		

      	}
		if(Sample_flag==1)
		{
			Sample();
		}
        if (load_data_flag==1)	//取历史记录
        { 
           	ReadEEPROM();
           	load_data_flag=0; 
        }
		if(save_data_flag==1)	//保存结果
		{
			Addr=0x77;
			eeprom_write_byte(&Addr,0x77);		//Writes a Save flag for reading		    for(temp = 0;temp < 5;temp++)		    {
				Addr=0x20+temp;			    eeprom_write_byte(&Addr,Step_Result[temp]);	//Writes EEPROM , start address:0x20;		    }
			save_data_flag=0;
		}
	
 	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -