Operácie

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

Zo stránky SensorWiki

StudentDVPS (diskusia | príspevky)
Bez shrnutí editace
StudentDVPS (diskusia | príspevky)
Bez shrnutí editace
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 z 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.

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


	}
}