Operácie

Projekt: Dvojosí akcelerometer A

Z SensorWiki

Verzia z 12:26, 28. december 2012, ktorú vytvoril StudentDVPS (diskusia | príspevky)

Dvojosí akcelerometer

  • Vypracovali:
Bc. Gabriel Gálik
Bc. Roman Gogola


  • Študijný odbor:Aplikovaná mechatronika
  • Ročník:2. Ing.


Zadanie

  1. Zobrazte na LCD náklon dosky v dvoch osiach zmeraný snímačom Memsic (meranie šírky impulzov).
  2. Implementujte rolovanie dlhého textu na LCD displeji podľa náklonu.


Použitý akcelerometer

Pri riešení projektu sme použili akcelerometer MEMSIC 2125. Jedná sa o tepelný akcelerometer, ktorý je schopný merať náklon, kolízie, statické a dynamické zrýchlenie, natočenie a vibrácie s rozsahom ±3g na dvoch osiach.

SnimacZrychleniaMemsic.jpg Obr. 1: Akcelerometer Memsic 2125

Funkcie akcelerometra:

  • Meranie ±3g na dvoch osiach
  • Jednoduchý impulzný výstup pre každú os
  • Analógový výstup teploty (tout pin)
  • Rozsah prevádzkových teplôt cez 0-70 °C


Základná špecifikácia:

  • Požiadavka na napájanie: 3,3 – 5 V
  • Komunikácia: TTL/CMOS kompatibilné 100Hz PWM výstupný signál ktorý je úmerný zrýchleniu
  • Prevádzková teplota: 0-70 °C


Riešenie

Potrebné súbory: lcd.c lcd.h Projekt_akcelerometer.c‎

Zdrojový kód

Kód v jayzku C:

#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>  
#include <stdlib.h>
#include <stdio.h>
FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE);		// je nova funkcia pre jeden znak
unsigned char pole[8][16]={"1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?","1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?"};

volatile unsigned int STARTX = 0;   // The variable for interrupt should be declared as a volatile one!
volatile  	long DELTAX;
volatile unsigned int PULSEX=0,PWMX;
volatile unsigned int ENDX=0;
volatile unsigned int bufferX=0;

volatile unsigned int STARTY = 0;   // The variable for interrupt should be declared as a volatile one!
volatile  	long DELTAY;
volatile unsigned int PULSEY=0,PWMY;
volatile unsigned int ENDY=0;
volatile unsigned int bufferY=0;

ISR(PCINT0_vect)
{
bufferX=TCNT1;	

if (!(PINB & 0b00100000))
	{
	PULSEX=bufferX;
	PWMX=PULSEX-STARTX;
	}
	else
	{
	//TCNT1=0x000;
	ENDX=STARTX;
	STARTX=bufferX;
	DELTAX=STARTX-ENDX;
	}
}

ISR(PCINT1_vect)
{
bufferY=TCNT1;

if (PINC & 0b00000001)
	{
		ENDY=STARTY;
	STARTY=bufferY;
	DELTAY=STARTY-ENDY;
	}
	else
	{
	PULSEY=bufferY;
		PWMY=PULSEY-STARTY;
	}
}




void lcdGotoXY(int riadok,int stlpec)
{

		if (riadok==1)
		 lcdControlWrite(0x40+0x80+stlpec);
		 else
		 lcdControlWrite(0x80+stlpec);

}

void delay_ms(unsigned int ms)
{
  unsigned int index;

  while (ms)
  {
   index = F_CPU / 19040;    // vypocitajte, kolko treba, aby sme dostali 1ms!!
        
   while (index)
   {
    asm volatile ("nop");
    index--;
   }

   ms--;
  }
}

int SDH(void)
{
	lcdControlWrite(0x02);	
	return 0;	
}

void Plot(int stlp, int riadok)
{
	int i,j;

	
	j=riadok;
	lcdGotoXY(0,0);
	for(i=stlp;i<=stlp+8;i++)
	{
	lcdDataWrite(pole[j][i]);

	}	
	j++;
	lcdGotoXY(1,0);
		for(i=stlp;i<=stlp+8;i++)
		{
		
	lcdDataWrite(pole[j][i]);

	}
}

int SDL(void)
{
	lcdControlWrite(0x18);	
	return 0;	
}

int SDR(void)
{
	lcdControlWrite(0x1C);	
	return 0;	
}


int main(void)
{
	int i=0,j;
DDRB = 0b00000000;              // Set ICR - Port B, pin0  as INPUT
DDRC = 0b00000000;              // Set ICR - Port B, pin0  as INPUT
	PCICR=0b00000011;
	PCIFR=0b00000011;
	PCMSK1=0b00000001;
	PCMSK0=0b00100000;

 TCCR1B = 0b11000010;               // T1 clk = F_CPU : 1024, falling edge pin ICP1,
 TCCR1A = 0b00000000;                // T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !!
  TCNT1 = 0x0000;           // initialize the counter (16-bit! Low+High bytes)
lcdInit4();
 stdout = &mystdout;           // Odteraz funguje printf();
sei();                    // Enable ALL interrupts  


for(;;){

	
//	if(PWMX<0)
//	PWMX+=65536;
	
//		if(DELTAX<0)
//	DELTAX+=65536;
	
	
	
	
//	lcdGotoXY(0,0);
//	printf("%u     ",((long)(PWMX*10)/DELTAX));
//	lcdGotoXY(1,0);
//	printf("%u    ",PWMX);
	Plot(0,i);  // max 8,2
delay_ms(1000);
	if (((long)(PWMX*10)/DELTAX)==2)
	SDR();
	else
	if(((long)(PWMX*10)/DELTAX)==0)
	SDL();
if (((long)(PWMY*10)/DELTAY)==2 && i<6)
	i++;
	else
	if(((long)(PWMY*10)/DELTAY)==0 && i>0)
	i--;


	}
}