📄 acceleration.c
字号:
//ICC-AVR application builder : 2009-3-26 18:32:14
// Target : M16
// Crystal: 4.0000Mhz
#include <iom16v.h>
#include <macros.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//Drivers
#include "lcd.h"
#include "fat.h"
#include "ap89021.h"
//Tasks
#include "keyboard.h"
#include "lcdtask.h"
#include "SDCard.h"
#include "sdTask.h"
#include "apTask.h"
//======================Parameters=================
#include "def.h"
//=======================Globals====================
//---------States-------
unsigned char mainState = 0; //IDLE=0, Sampling=1;
unsigned char mute = 0;
//--------Time----*0.01s-------
unsigned long currentTime = 0;
unsigned short idleTime = 0;
//------LCD & ISD interface-----When Read, CLI!!!----
unsigned short currentImpact = 0;
unsigned char currentImpactUpdated = 0x01; //bit 0 = LCD; bit 1 = ISD;
unsigned short impactCounter = 0;
extern unsigned char sdBuffer[512];
extern unsigned char sdQueueFront;
extern unsigned char sdQueueEnd;
extern unsigned char sdCardInserted;
void dataAnalysis(unsigned char voltX, unsigned char voltY);
void powerOff(void);
//==========Initialization Code===============
void port_init(void)
{
PORTA = 0x20;
DDRA = 0x7C;
PORTB = 0x77;
DDRB = 0xB0;
PORTC = 0x00; //m103 output only
DDRC = 0xC3;
PORTD = 0x00;
DDRD = 0x00;
}
//TIMER1 initialize - prescale:64
// WGM: 4) CTC, TOP=OCRnA
// desired value: 100Hz
// actual value: 100.000Hz (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFD; //setup
TCNT1L = 0x90;
OCR1AH = 0x02;
OCR1AL = 0x70;
OCR1BH = 0x02;
OCR1BL = 0x70;
ICR1H = 0x02;
ICR1L = 0x70;
TCCR1A = 0x00;
TCCR1B = 0x0B; //start Timer
}
#pragma interrupt_handler timer1_ovf_isr:9
INTERRUPT(SIG_OVERFLOW1)
{
//TIMER1 has overflowed
TCNT1H = 0xFD; //reload counter high value
TCNT1L = 0x90; //reload counter low value
//Keyboard check
keyboardRead();
if(mainState)
currentTime++;
else
{
idleTime++;
if (idleTime>AUTOPOWEROFF)
powerOff();
}// if keyboard check
//ADC Start
if(mainState) //Sampling
{
ADMUX &= 0xe0; //Choose Channel 0
ADCSRA |=0x40; //Start Conversion
}
}
//SPI initialize
// clock rate: 1000000hz
void spi_init(void)
{
SPCR = 0x50; //setup SPI //master,enable,MSB first, CPOL=CPHA=0
SPSR = 0x00; //setup SPI
}
//ADC initialize
// Conversion time: 104uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x40; //select adc input 0
ACSR = 0x80;
ADCSR = 0x8D;
}
#pragma interrupt_handler adc_isr:15
INTERRUPT(SIG_ADC)
{
static unsigned char valueChannel0, valueChannel1;
unsigned short valueTemp;
//conversion complete, read value (int) using...
valueTemp=ADCL; //Read 8 low bits first (important)
valueTemp|=(int)ADCH << 8; //read 2 high bits and shift into top byte
//Calculate ABS
if (valueTemp>=512)
valueTemp -=512;
else
valueTemp = 512-valueTemp;
if(ADMUX&0x01)
{
valueChannel1 = valueTemp>>1; //discard 1 bit
dataAnalysis(valueChannel0,valueChannel1);
}
else
{//Channel 0
valueChannel0 = valueTemp>>1; //discard 1 bit
ADMUX |= 0x01;
ADCSRA |=0x40; //Start Channel 1
}
}//adc_isr
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
spi_init();
adc_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
//
void main(void)
{
//test
// unsigned short i,j;
init_devices();
// for(i=0;i<20000;i++);
//insert your functional code here...
//=====Initialization===========
lcdInit();
sdTaskInit();
// if(!sdInitCard())
// {
// PORTA |= 0x80;
// sdReadData(0<<9);
// sdWriteData(11801L<<9);
// sdReadData(11801L<<9);
// }
// fatInit();
// fileCreateSequential(filenamePrefix,fileIndexLength,filenameExt);
// PORTA|=0x80;
// for(i=0;i<20;i++)
//{
// for(j=0;j<512;j++)
// sdBuffer[j] = ((i+j)%26)+'A';
// fileWriteBuffer();
//}
// PORTA&=~0x80;
// fileClose(5);
clearState();
timer1_init();//Open Timer
//=====Background tasks=========
while(1)
{
lcdTask();
if(!apIsBusy())
sdTask(); //Donot write when playing sound
if ( !mute && (sdQueueFront==sdQueueEnd || !sdCardInserted) ) //Only output sound when queue empty
apTask();
if(mainState==2)
{
powerOff();
break;
}
}
while(1);
}
unsigned short calculateImpact(unsigned char valueX, unsigned char valueY);
unsigned short sqrt(unsigned long M);
void impactDetect(unsigned short impactTransient);
//=========Data analysis subroutine===============
void dataAnalysis(unsigned char valueX, unsigned char valueY)
{
unsigned short impactTransient;
impactTransient = calculateImpact(valueX,valueY);
impactDetect(impactTransient);
}
void impactDetect(unsigned short impactTransient)
{
static unsigned char detectState = 0; //0=IDLE;1=Impact
static unsigned char detectTimer = 0;
static unsigned short impactPeak;
static unsigned long impactPeakTime;
//test
if(impactTransient>=IMPACTTHRESHOLD)
PORTA &= ~0x40;
else
PORTA |=0x40;
// PORTA ^=0x40;
if(detectTimer)
detectTimer--;
if(detectState) //within impact
{
if(impactPeak<impactTransient)
{
impactPeak = impactTransient;
impactPeakTime = currentTime;
}
if(!detectTimer&&impactTransient<IMPACTTHRESHOLD) //impactEnd
{
//SD:impactEnque;
sdEnQueue(&impactPeakTime,&impactPeak);
//LCD,ISD
currentImpact = impactPeak;
currentImpactUpdated = 0x03;
//Counter
impactCounter++;
//Swich state
detectState = 0;
PORTA |= 0x80;
detectTimer = MINIMPACTINTERVAL;
}
}//if state==IMPACT
else if(!detectTimer && impactTransient>=IMPACTTHRESHOLD)
{
detectState = 1;
PORTA &= ~0x80;
detectTimer = MINIMPACTINTERVAL;
impactPeak = impactTransient;
impactPeakTime = currentTime;
}
}
unsigned short sqrt(unsigned long M)
{
unsigned short N = 0;
unsigned char i;
unsigned long MResidue = 0; // /=pow(2,i)
unsigned long Mtest;
unsigned char test;
for(i=16;i;i--)
{
test = M>>30;
MResidue = (MResidue<<2) + test; //fetch first to bit from M
M = M<<2;//prepare next 2 bits
N = N<<1;
Mtest = (N<<1)+1;
if(MResidue>=Mtest)
{
MResidue -= Mtest;
N++;
}
}
return N;
}
unsigned short calculateImpact(unsigned char valueX, unsigned char valueY)
{
unsigned long valueX2Y2;
unsigned short impactTransient;
valueX2Y2 = (unsigned long)((unsigned short)valueX*valueX)+((unsigned short)valueY*valueY);
valueX2Y2 *= ACCELERATIONCOEF;
valueX2Y2 = valueX2Y2 >> (ACCELERATIONSCALEBIT*2);
impactTransient = sqrt(valueX2Y2);
return impactTransient;
}
void powerOff(void)
{
mainState = 0;//-->IDLE
sdTaskFinish();
//Save SD card
PORT_POWER &= ~BIT_POWER;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -