Projekt: Dvojosí akcelerometer A: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
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); // | 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; | 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; | 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; | 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; | DDRB = 0b00000000; // nastav ICR - Port B, pin0 ako INPUT | ||
DDRC = 0b00000000; | 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; | TCCR1B = 0b11000010; // T1 clk = F_CPU : 1024, falling edge pin ICP1, | ||
TCCR1A = 0b00000000; | TCCR1A = 0b00000000; // T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !! | ||
TCNT1 = 0x0000; | TCNT1 = 0x0000; // inicializácia počítadla (16-bit! Low+High bytes) | ||
lcdInit4(); | lcdInit4(); | ||
stdout = &mystdout; | stdout = &mystdout; // Odteraz funguje printf(); | ||
sei(); | sei(); // povolenie všetkých prerušení | ||
Riadok 198: | Riadok 198: | ||
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 | |||
Plot(0,i); | |||
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
- Zobrazte na LCD náklon dosky v dvoch osiach zmeraný snímačom Memsic (meranie šírky impulzov).
- 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
}
}