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

📄 acceleration.c

📁 加速度采集器。基于ATMega16L.AVRSTUIDIO4
💻 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 + -