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

📄 pedometer.c

📁 基于ADI公司加速度传感器的计步器算法,MCU采用ATMega48,加速度传感器采用ADXL330
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------ADI Pedometer Reference Design Source Code-------------------------------------------------
Author: 		
Date:			2006-09-25
Rev:			2.3
Description:	实现Pedometer的算法,MCU采用ATMega48,加速度传感器采用ADXL330,开发工具采用 WinAVR + AVR Studio
				
-------------------------------------------------------------------------------------------------------------------*/

//ATMega48相关头文件#include <avr/io.h>				
#include <avr/interrupt.h>			
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/twi.h>
//ADC采样通道
#define X_CHANNEL 0
#define Y_CHANNEL 1
#define Z_CHANNEL 2

//保存步长值#define STEP_LENGTH_HIGH (Step_Result[3])#define STEP_LENGTH_LOW  (Step_Result[4])

#define TIMEWINDOW_MIN 2   		//时间窗,×0.02s=0.2s
#define TIMEWINDOW_MAX 20		//时间窗,×0.02s=2s
#define REGULATION	4			//认为找到稳定规律所需要的步数
#define INVALID		2			//认为失去稳定规律所需要的步数

#define TWI_ADDRESS 0x88		//TWI/I2C设备地址

unsigned char itemp,jtemp,temp;								
unsigned char _bad_flag[3];									unsigned char Receive;	    				unsigned char ResultIndex;										unsigned int  Adresult;											unsigned char  sampling_counter;								
unsigned int _adresult[3];									
unsigned int _max[3]={0,0,0};
unsigned int _min[3]={1000,1000,1000};
unsigned int _dc[3]={500,500,500};
unsigned int _vpp[3]={30,30,30};	
unsigned int  _precision[3]={5,5,5};	
unsigned int _old_fixed[3];
unsigned int _new_fixed[3];
unsigned char Readflag,save_data_flag=0,load_data_flag=0;					unsigned char Start_flag;		
unsigned char Sample_flag;			unsigned char Step_Result[11] = {0,0,0,1,0,0,0,0,0,0,0}; //前3个用于存放需要发送给controller的3 Bytes步数结果,后2个用于存放步长值STEP_LENGTH_HIGH和STEP_LENGTH_LOW,最后6个用于存放加速采样的结果
unsigned char Temp_Result[6] = {0,0,0,0,0,0};
unsigned long int STEPS;	
unsigned long int STEPS_Temp;	
unsigned  int _array0[3]={1,1,1};
unsigned  int _array1[3]={1,1,1};
unsigned  int _array2[3]={0,0,0};
unsigned  int _array3[3]={0,0,0};

unsigned char Interval=0;		//记录时间间隔数
unsigned char TempSteps=0;		//记步缓存
unsigned char InvalidSteps=0;	//无效步缓存
unsigned char ReReg=2;			//记录是否重新开始寻找规律
										//	2-新开始
										//	1-已经开始,但是还没有找到规律
										//	0-已经找到规律




/*------------------------------------------------------------------------------------------------------------------------
*Interrupt 	TWI中断
*Function: 	TWI中断,完成与主机的通信协议
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
SIGNAL(SIG_2WIRE_SERIAL)
{
	volatile unsigned char i;			//中断状态
	volatile unsigned char Receive;	 	//接受到的数据 

	i=TW_STATUS;

	if(i==TW_SR_SLA_ACK)
	{
		TWCR = (1<<TWEN)|                           
       				  (1<<TWIE)|(1<<TWINT)|                 
        			 (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO);       
	}
	else if(i==TW_SR_DATA_NACK)
	{
		Receive=TWDR;
		TWCR = (1<<TWEN)|                          
       				  (1<<TWIE)|(1<<TWINT)|                 
        			 (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO) ;      

		//判断命令
		if(Receive == 0xDD)					//if Command = "0xDD" , "Clear Step Counter"		{
			//Clear Step_Result
			STEPS = 0;				Step_Result[0] = 0;							Step_Result[1] = 0; 						Step_Result[2] = 0; 											}		else if(Receive == 0xAA)			//if Command = "0xAA" , "STOP"		{			Start_flag = 0;					//Clear Start_flag
			Sample_flag=0;		}		else if(Receive == 0xCC)			//if Command = "0xCC" , "RUN"		{			Start_flag = 1;					//Set Start_flag		}
        else if(Receive == 0xFF)			{			load_data_flag=1;				}		else if((Receive>0)&&(Receive<12))	//if Command  = ResultIndex(0< Receive <10)		{			ResultIndex = Receive - 1;		//Set ResultIndex		}		else if(Receive == 0xBB)			//if Command  =  "0xBB"  ,"Write EEPROM"		{			save_data_flag=1;         									}
		else if(Receive == 0xEE)
		{
			Sample_flag=1;
			Step_Result[5]=Temp_Result[0];
			Step_Result[6]=Temp_Result[1];
			Step_Result[7]=Temp_Result[2];
			Step_Result[8]=Temp_Result[3];
			Step_Result[9]=Temp_Result[4];
			Step_Result[10]=Temp_Result[5];
		}		else if((Receive>=0xD0)&&(Receive <= 0xD9)) 			//if Command  = STEP_LENGTH_HIGH (D0=< Receive <=D9)		{			STEP_LENGTH_HIGH = (Receive - 0xD0);		}		else if((Receive>=0x90)&&(Receive <= 0x99))				//if Command  = STEP_LENGTH_Low (90=< Receive <=99)		{				STEP_LENGTH_LOW = (Receive - 0x90);		}
	}
	else if(i==TW_SR_STOP)
	{
		TWCR = (1<<TWEN)|                           
       				  (1<<TWIE)|(1<<TWINT)|                 
        			 (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO) ;     	
	}
	else if(i==TW_ST_SLA_ACK)		//发送结果
	{

		TWDR=Step_Result[ResultIndex];

		TWCR = (1<<TWEN)|                             
       				  (1<<TWIE)|(1<<TWINT)|                  
        			 (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)  ;    
	}
	else if(i==TW_ST_DATA_NACK)
	{
		TWCR = (1<<TWEN)|                            
       				  (1<<TWIE)|(1<<TWINT)|                 
        			 (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO) ;     
	}
	else
	{
		TWCR = (1<<TWEN)|                             
       				  (1<<TWIE)|(1<<TWINT)|                 
        			 (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)   ;   
	}
}


/*------------------------------------------------------------------------------------------------------------------------
*Interrupt 	T0中断
*Function: 	T0中断,定时0.1s,实现时间窗功能
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
SIGNAL(SIG_OVERFLOW0)
{

	if(Interval < 0xFF)	//时间间隔数加1,但不能产生溢出
	{
		Interval++;
	}
	TCNT0=80; // T/C0开始值
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		ReadEEPROM()
*Function:	从EEPROM中读取历史记录
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void ReadEEPROM()
{
	unsigned char Addr;

	//读取read flag 
	Addr=0x77;
	Readflag=eeprom_read_byte(&Addr);

	if(Readflag == 0x77)									//read flag 是否正确	{
		//读取5字节数据		for(itemp = 0;itemp<5;itemp++)								{   
			Addr=0x20+itemp;			Step_Result[itemp] = eeprom_read_byte(&Addr);			}
		//更新记步结果		STEPS = 0;		for(itemp = 3;itemp>0;itemp--)		{
				STEPS = STEPS<<7 ;               				STEPS = STEPS + Step_Result[itemp-1];						}	}
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		Timer0_Initiate()
*Function:	初始化 Timer0
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void Timer1_Initiate()		//定时0.1秒
{
	TCNT0=80; // T/C0开始值 
	TCCR0A=0;
	TCCR0B=5; // 预分频 ck/1024 ,计数允许
	
	TIMSK0=_BV(TOIE0);

	Interval=0;
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		TWI_Initiate()
*Function:	初始化TWI
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void TWI_Initiate()
{
	DDRC=0x00;
	PORTC=0x00;
	TWAR=TWI_ADDRESS | _BV(TWGCE);

	TWCR = (1<<TWEN)|                           // TWI Interface enabled.
         (1<<TWIE)|(0<<TWINT)|                  // Enable TWI Interupt and clear the flag.
         (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO) ;      // Prepare to ACK next time the Slave is addressed.
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		Init()
*Function:	初始化ATMege48,给寄存器赋初始值
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void Init()
{
	cli();	//关中断

	Start_flag = 0;		//停止
	sampling_counter=0;
    STEPS=0;

	OSCCAL=0xFF;	//设为最大频率

	TWI_Initiate();
 	Timer1_Initiate();

	sei();	//开中断
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		adc_read()
*Function:	ADC采样,结果保存在Adresult
*Input:		ADC通道号
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/
void adc_read(unsigned char channel)
{

	
	ADMUX=0x40+channel;		//  ADMUX=0xC0;//AVCC参考电压,0通道: x
							//	ADMUX=0xC1;//AVCC参考电压,1通道: y
							//	ADMUX=0xC2;//AVCC参考电压,2通道: z
	ADCSRA=_BV(ADEN);		//使能ADC,单次转换模式
	

	ADCSRA|=_BV(ADSC);		//等待转换结束

	while(ADCSRA&_BV(ADSC)) {;}

	Adresult=ADCL;
	Adresult|=(unsigned int)(ADCH<<8);

	ADCSRA=0;//关闭ADC
}

/*------------------------------------------------------------------------------------------------------------------------
*Name: 		Save_Result()
*Function:	保存记步结果,保存成3 Bytes结果,每个Byte只用其中的低7位
*Input:		void
*Output: 	void
*------------------------------------------------------------------------------------------------------------------------*/


void Save_Result()
{

	unsigned long int TEMP;
//	cli();

⌨️ 快捷键说明

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