Operácie

Projekt: Dvojosí akcelerometer A: Rozdiel medzi revíziami

Z SensorWiki

Riadok 55: Riadok 55:
 
#include <stdlib.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include <stdio.h>
FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE); // je nova funkcia pre jeden znak
+
FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE); // nová funkcia pre jeden znak
 
unsigned char pole[8][16]={"1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?","1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?"};
 
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 unsigned int STARTX = 0;   // premenné na výpočet PWM pre os X
 
volatile  long DELTAX;
 
volatile  long DELTAX;
 
volatile unsigned int PULSEX=0,PWMX;
 
volatile unsigned int PULSEX=0,PWMX;
Riadok 64: Riadok 64:
 
volatile unsigned int bufferX=0;
 
volatile unsigned int bufferX=0;
  
volatile unsigned int STARTY = 0;   // The variable for interrupt should be declared as a volatile one!
+
volatile unsigned int STARTY = 0;   // premenné na výpočet PWM pre os Y
 
volatile  long DELTAY;
 
volatile  long DELTAY;
 
volatile unsigned int PULSEY=0,PWMY;
 
volatile unsigned int PULSEY=0,PWMY;
Riadok 70: Riadok 70:
 
volatile unsigned int bufferY=0;
 
volatile unsigned int bufferY=0;
  
ISR(PCINT0_vect)
+
ISR(PCINT0_vect) // prerušenie pre vstup X
 
{
 
{
bufferX=TCNT1;
+
bufferX=TCNT1; //uloženie hodnoty z countra na začiatku prerušenia
  
if (!(PINB & 0b00100000))
+
if (!(PINB & 0b00100000)) //test dobežnej hrany
 
{
 
{
PULSEX=bufferX;
+
PULSEX=bufferX; // dobežná hrana -> výpočet šírky impulzu
 
PWMX=PULSEX-STARTX;
 
PWMX=PULSEX-STARTX;
 
}
 
}
 
else
 
else
 
{
 
{
//TCNT1=0x000;
+
//TCNT1=0x000; // nábežná hrana -> výpočet periódy
 
ENDX=STARTX;
 
ENDX=STARTX;
 
STARTX=bufferX;
 
STARTX=bufferX;
Riadok 88: Riadok 88:
 
}
 
}
  
ISR(PCINT1_vect)
+
ISR(PCINT1_vect) // prerušenie pre vstup Y
 
{
 
{
bufferY=TCNT1;
+
bufferY=TCNT1; //uloženie hodnoty z countra na začiatku prerušenia
  
if (PINC & 0b00000001)
+
if (PINC & 0b00000001) //test nábežnej hrany
 
{
 
{
ENDY=STARTY;
+
ENDY=STARTY; // nábežná hrana -> výpočet periódy
 
STARTY=bufferY;
 
STARTY=bufferY;
 
DELTAY=STARTY-ENDY;
 
DELTAY=STARTY-ENDY;
Riadok 100: Riadok 100:
 
else
 
else
 
{
 
{
PULSEY=bufferY;
+
PULSEY=bufferY; // dobežná hrana -> výpocet šírky impulzu
 
PWMY=PULSEY-STARTY;
 
PWMY=PULSEY-STARTY;
 
}
 
}
Riadok 108: Riadok 108:
  
  
void lcdGotoXY(int riadok,int stlpec)
+
void lcdGotoXY(int riadok,int stlpec) // vlastná funkcia pre nastavenie polohy kurzora na displeji
 
{
 
{
  
Riadok 118: Riadok 118:
 
}
 
}
  
void delay_ms(unsigned int ms)
+
void delay_ms(unsigned int ms) // vlastna funkcia pre časové oneskorenie
 
{
 
{
 
   unsigned int index;
 
   unsigned int index;
Riadok 124: Riadok 124:
 
   while (ms)
 
   while (ms)
 
   {
 
   {
   index = F_CPU / 19040;   // vypocitajte, kolko treba, aby sme dostali 1ms!!
+
   index = F_CPU / 19040;   // 1ms!!
 
          
 
          
 
   while (index)
 
   while (index)
Riadok 136: Riadok 136:
 
}
 
}
  
int SDH(void)
+
int SDH(void) // vlastná funkcia pre display "set cursor home"
 
{
 
{
 
lcdControlWrite(0x02);
 
lcdControlWrite(0x02);
Riadok 142: Riadok 142:
 
}
 
}
  
void Plot(int stlp, int riadok)
+
void Plot(int stlp, int riadok) // vlastna funkcia na vyplnenie displeja z dátového poľa
 
{
 
{
 
int i,j;
 
int i,j;
Riadok 149: Riadok 149:
 
j=riadok;
 
j=riadok;
 
lcdGotoXY(0,0);
 
lcdGotoXY(0,0);
for(i=stlp;i<=stlp+8;i++)
+
for(i=stlp;i<=stlp+8;i++) // vyplnenie prvého riadku
 
{
 
{
 
lcdDataWrite(pole[j][i]);
 
lcdDataWrite(pole[j][i]);
Riadok 156: Riadok 156:
 
j++;
 
j++;
 
lcdGotoXY(1,0);
 
lcdGotoXY(1,0);
for(i=stlp;i<=stlp+8;i++)
+
for(i=stlp;i<=stlp+8;i++) // vyplnenie druhého riadku
 
{
 
{
 
 
Riadok 164: Riadok 164:
 
}
 
}
  
int SDL(void)
+
int SDL(void) // posuň displej doľava
 
{
 
{
 
lcdControlWrite(0x18);
 
lcdControlWrite(0x18);
Riadok 170: Riadok 170:
 
}
 
}
  
int SDR(void)
+
int SDR(void) // posuň displey doprava
 
{
 
{
 
lcdControlWrite(0x1C);
 
lcdControlWrite(0x1C);
Riadok 180: Riadok 180:
 
{
 
{
 
int i=0,j;
 
int i=0,j;
DDRB = 0b00000000;             // Set ICR - Port B, pin0  as INPUT
+
DDRB = 0b00000000;             // nastav ICR - Port B, pin0  ako INPUT
DDRC = 0b00000000;             // Set ICR - Port B, pin0 as INPUT
+
DDRC = 0b00000000;             // nastav ICR - Port C, pin5 ako INPUT
PCICR=0b00000011;
+
PCICR=0b00000011; // nastavenie externého prerušenia
PCIFR=0b00000011;
+
PCIFR=0b00000011;
 
PCMSK1=0b00000001;
 
PCMSK1=0b00000001;
 
PCMSK0=0b00100000;
 
PCMSK0=0b00100000;
  
  TCCR1B = 0b11000010;               // T1 clk = F_CPU : 1024, falling edge pin ICP1,
+
  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 !!
+
  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)
+
   TCNT1 = 0x0000;           // inicializácia počítadla (16-bit! Low+High bytes)
 
lcdInit4();
 
lcdInit4();
  stdout = &mystdout;           // Odteraz funguje printf();
+
  stdout = &mystdout;           // Odteraz funguje printf();
sei();                   // Enable ALL interrupts  
+
sei();                   // povolenie všetkých prerušení  
  
  
Riadok 198: Riadok 198:
  
 
 
// if(PWMX<0)
+
 
// PWMX+=65536;
+
Plot(0,i); //vyplnenie displeja s požadovanými riadkami
+
delay_ms(1000); // delay aby sa dalo odčítať
// if(DELTAX<0)
+
if (((long)(PWMX*10)/DELTAX)==2) // test natočenia v smere x
// DELTAX+=65536;
+
SDR(); // posun displeja
+
else
+
if(((long)(PWMX*10)/DELTAX)==0) // test natočenia v smere -x
+
SDL(); // posun displeja
+
if (((long)(PWMY*10)/DELTAY)==2 && i<6) // test natočenia v smere y
// lcdGotoXY(0,0);
+
i++; // posun vypisaných riadkov
// 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
 
else
if(((long)(PWMY*10)/DELTAY)==0 && i>0)
+
if(((long)(PWMY*10)/DELTAY)==0 && i>0) // test natočenia v smere -y
i--;
+
i--; // posun vypisaných riadkov
  
  
 
}
 
}
 
}
 
}
 +
 
</source>
 
</source>
  
  
 
[[Category:AVR]] [[Category:DVPS]]
 
[[Category:AVR]] [[Category:DVPS]]

Verzia zo dňa a času 12:38, 28. december 2012

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);		// nová funkcia pre jeden znak
unsigned char pole[8][16]={"1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?","1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?"};

volatile unsigned int STARTX = 0;   			// premenné na výpočet PWM pre os X
volatile  	long DELTAX;
volatile unsigned int PULSEX=0,PWMX;
volatile unsigned int ENDX=0;
volatile unsigned int bufferX=0;

volatile unsigned int STARTY = 0;   			//  premenné na výpočet PWM pre os Y
volatile  	long DELTAY;
volatile unsigned int PULSEY=0,PWMY;
volatile unsigned int ENDY=0;
volatile unsigned int bufferY=0;

ISR(PCINT0_vect)					// prerušenie pre vstup X
{
bufferX=TCNT1;						//uloženie hodnoty z countra na začiatku prerušenia

if (!(PINB & 0b00100000))				//test dobežnej hrany
	{
	PULSEX=bufferX;					// dobežná hrana -> výpočet šírky impulzu
	PWMX=PULSEX-STARTX;
	}
	else
	{
	//TCNT1=0x000;					// nábežná hrana -> výpočet periódy
	ENDX=STARTX;
	STARTX=bufferX;
	DELTAX=STARTX-ENDX;
	}
}

ISR(PCINT1_vect)					// prerušenie pre vstup Y
{
bufferY=TCNT1;						//uloženie hodnoty z countra na začiatku prerušenia

if (PINC & 0b00000001)					//test nábežnej hrany
	{
		ENDY=STARTY;				// nábežná hrana -> výpočet periódy
	STARTY=bufferY;
	DELTAY=STARTY-ENDY;
	}
	else
	{
	PULSEY=bufferY;					// dobežná hrana -> výpocet šírky impulzu
		PWMY=PULSEY-STARTY;
	}
}




void lcdGotoXY(int riadok,int stlpec)			// vlastná funkcia pre nastavenie polohy kurzora na displeji
{

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

}

void delay_ms(unsigned int ms)				// vlastna funkcia pre časové oneskorenie
{
  unsigned int index;

  while (ms)
  {
   index = F_CPU / 19040;    				// 1ms!!
        
   while (index)
   {
    asm volatile ("nop");
    index--;
   }

   ms--;
  }
}

int SDH(void)						// vlastná funkcia pre display "set cursor home" 
{
	lcdControlWrite(0x02);	
	return 0;	
}

void Plot(int stlp, int riadok)				// vlastna funkcia na vyplnenie displeja z dátového poľa 
{
	int i,j;

	
	j=riadok;
	lcdGotoXY(0,0);
	for(i=stlp;i<=stlp+8;i++)			// vyplnenie prvého riadku
	{
	lcdDataWrite(pole[j][i]);

	}	
	j++;
	lcdGotoXY(1,0);
		for(i=stlp;i<=stlp+8;i++)		// vyplnenie druhého riadku
		{
		
	lcdDataWrite(pole[j][i]);

	}
}

int SDL(void)						// posuň displej doľava
{
	lcdControlWrite(0x18);	
	return 0;	
}

int SDR(void)						// posuň displey doprava
{
	lcdControlWrite(0x1C);	
	return 0;	
}


int main(void)
{
	int i=0,j;
DDRB = 0b00000000;              			// nastav ICR - Port B, pin0  ako INPUT
DDRC = 0b00000000;              			// nastav ICR - Port C, pin5  ako INPUT
	PCICR=0b00000011;				// nastavenie externého prerušenia
	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;           				// inicializácia počítadla (16-bit! Low+High bytes)
lcdInit4();
 stdout = &mystdout;           				// Odteraz funguje printf();
sei();                    				// povolenie všetkých prerušení  


for(;;){

	

	Plot(0,i);  					//vyplnenie displeja s požadovanými riadkami
delay_ms(1000);						// delay aby sa dalo odčítať
	if (((long)(PWMX*10)/DELTAX)==2)		// test natočenia v smere x
	SDR();						// posun displeja
	else								
	if(((long)(PWMX*10)/DELTAX)==0)			// test natočenia v smere -x
	SDL();						// posun displeja
if (((long)(PWMY*10)/DELTAY)==2 && i<6)			// test natočenia v smere y
	i++;						// posun vypisaných riadkov
	else
	if(((long)(PWMY*10)/DELTAY)==0 && i>0)		// test natočenia v smere -y
	i--;						// posun vypisaných riadkov


	}
}