Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR1665 - Pomiar prędkości liniowej na AVR Atmega8 (AVT1665) i enkoderze

sob211 16 Sty 2017 04:12 537 1
  • #1 16 Sty 2017 04:12
    sob211
    Poziom 7  

    Witam serdecznie.
    Jestem na etapie pisania programu w Atmel Studio 7 realizującego pomiar prędkości liniowej na bazie AVT1665 (Amega8) oraz enkoderze inkrementalnym.
    Poniżej zamieszczam program który napisałem, jednak mam problem z kilkoma błędami. Proszę o pomoc.
    Proszę również o opinię co do składni czy logika programu jest prawidłowa.
    Aktualnie czekam na części do tego projektu i nie mam możliwości sprawdzenia czy program działa poprawnie.
    Załączam schemat połączeń Atmegi8 z enkoderem oraz dokumentację AVT1665 i enkodera.

    ////////Pomiar prędkości liniowej//////////////

    #define F_CPU 11059200
    #include <avr/io.h>
    #include <stdio.h>
    #include "lcd_displ.h"
    #include "util/delay.h"
    #include <avr/interrupt.h>
    unsigned char ilosc_imp=0;

    int main(void)
    {
    DDRD &=~ (1<<PD2); //ustaw PD2 jako wejscie
    PORTD |= (1<<PD2); //podciag programowo wewn rezystorem linie PD2 do VCC

    MCUCR |= (1<<ISC00); //przerwanie INT0 inicjowane poprzez zmianę stanu (ISC01 jest 0)
    GICR |= (1<<INT0); //załącz przerwanie INT0
    sei(); //włącznie przerwań globalnych

    ISR(INT0_vect)
    {
    ilosc_imp++;
    }

    lcd_init(); //załącz wyświetlacz LCD 2x16
    lcd_gotoxy(0,0); //Ustaw kursor na LCD w pozycji (0,0)
    lcd_printf("Predkosc liniowa [m/min]"); //Wyświetl na LCD w pierszej linii "Prędkość liniowa [m/min]"

    while (1) //pętla nieskończona
    {
    lcd_gotoxy(0,1); //Ustaw kursor na LCD w pozycji (0,1)
    lcd_printf("%d",2277/100000*ilosc_imp); //Wyświetla aktualną prędkość liniową w [m/min]
    //(jest to iloczyn współczynnika 0.00003795 i ilości impulsów zliczonych w czasie 1s
    //wsp. 0.002277 obliczono z danych: śr. koła pomiarowego 30.2[mm]
    //co daje obwód 94.876[mm]=0,094876[m] ilość imp/obr 2500[imp/obr]
    //V=0,094876/2500*ilosc_imp*60 [m/min] --> V=0.002277*ilosc_imp [m/min]
    ilosc_imp = 0;

    _delay_ms(1000);
    }
    }

    0 1
  • Pomocny post
    #2 19 Sty 2017 09:15
    marszalek_duck
    Poziom 17  

    Jest parę błędów które widzę już teraz.
    Pozwoliłem sobie wstawić to w syntax bo nie dało się czytać :)

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Tutaj jest chyba największy byk:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Obsługa przerwania jest osobną funkcją! A definicja funkcji nie może się znajdować we wnętrzu innej funkcji. Musi mieć swój kawałek podłogi :P :P :P

    Inna sprawa że unsigned char ilosc_imp=0; powinno zostać opatrzone jeszcze etykietką volatile. Czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Volatile wyłącza dla tej konkretne zmiennej optymalizację. Jest to konieczne jeżeli korzystasz ze zmiennej jednocześnie w przerwaniu oraz funkcji main.

    Co do estetyki, warto by było abyś napisał sobie jakąś funkcję przeznaczoną na inicjalizacje (np. setup itp.).

    Tyle mogę powiedzieć na teraz, jak wrócę z pracy to postaram się dokładniej sprawdzić czy coś jeszcze się tam skrywa :D

    0