📄 pedometer.c
字号:
/*-----------------------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 + -