HomeMade

Pełna wersja: Programowanie w języku C w środowisku AVR Studio4
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Córka zasnęłą i mam trochę czasu żeby popisać ...
(01-02-2012 21:30)SQ8MHI napisał(a): [ -> ]... Ja myślę, że on jest po to, żeby kursantom pokazać, jak w C łatwo i prosto zrobić sobie kuku ...
Przepraszam wszystkich kursantów, że zrobiłem Wam "kuku" i serdecznie dziękuje koledze SQ8MHI za uświadomienie mi mojej ciemnoty - żałuję tylko że kolega nie wyjaśnił od razu na czym polegały błedy.
Tłumaczę na czym polegały moje błędy:
1. ten na który zwrócił uwagę SQ8MHI polegał na tym, że rozmiar tablicy powinien uwzględniać również znacznik końca tablicy - czyli jesli chcemy zapisać w nim 9-cio znakowy ciąg to rozmiar tablicy powinien wynosić 10 ( + znacznik '\0' )
2. Drugi błąd polegał na tym że index (wskaźnik) tablicy, czyli zmienna i była typu char. Zmienna typu char może przyjmować ujemne wartości, a wskaźniki tablic nie mogą mieć wartości ujemnych.
My tu ujemnych wartości nie używamy dlatego program działa. Działa też mimo błednie podanego rozmiaru tablicy - kompilator sam powięszył jej rozmiar z 9 do 10, my tego nie widzimy ale tak jest.
Poprawnie skonstruowana funkcja wys_freq powinna wyglądac tak:
Kod:
void wys_freq(unsigned long int xxx)
{
     char freq_string[10];
     freq_string[9]=0;
     unsigned char i;

     for(i=8; i>0; i-=1)
     {
         freq_string[i]=xxx%10+48;
         xxx/=10;
     }

     freq_string[0]=xxx+48;
     napis_lcd(freq_string);
}
lub tak:
Kod:
void wys_freq(unsigned long int xxx)
{
    char freq_string[10];
    freq_string[9]=0;
    unsigned char i;

    i=8;
    while(i>0)
    {
        freq_string[i]=xxx%10+48;
        xxx/=10;
        i-=1;
    }

    freq_string[0]=xxx+48;
    napis_lcd(freq_string);
}
zwróćcie uwagę na pętlę for z pierwszego kodu i funkcję while z drugiego kodu - robią dokładnie to samo - porównanie te pomoże Wam zrozumieć zawiłe sformułowanie for(i=8; i>0; i-=1)

Jutro dodamy dwa przyciski które będą zmieniały częstotliwość ( na razie co 1 Hz ) - Jeśli ktoś ma pomysł jak to zrobić to prosze sie tu wykazać i podzielić z nami kodem.
Jeżeli wstawimy Twój kod do nowy.c to mamy error i warnings.

W każdym bądź razie tak jest u mnie

Build started 2.2.2012 at 06:52:22
avr-gcc -mmcu=atmega32 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT nowy.o -MF dep/nowy.o.d -c ../nowy.c
../nowy.c:1:0: warning: "F_CPU" redefined
<command-line>:0:0: note: this is the location of the previous definition
avr-gcc -mmcu=atmega32 -Wl,-Map=nowy.map nowy.o -o nowy.elf
d:/avr tools/avr toolchain/bin/../lib/gcc/avr/4.5.1/../../../../avr/lib/avr5/crtm32.o: In function `__vectors':
/home/tools/hudson/workspace/avr8-gnu-toolchain/src/avr-libc/crt1/gcrt1.S:52: undefined reference to `main'
collect2: ld returned 1 exit status

make: *** [nowy.elf] Błąd 1
Build failed with 1 errors and 1 warnings...
(02-02-2012 1:18)SP4EJT napisał(a): [ -> ]... Poprawnie skonstruowana funkcja wys_freq powinna wyglądac tak: ...
To znaczy że podałem tylko poprawioną, całą funkcję wys_freq a nie cały plik nowy.c

(02-02-2012 7:59)SQ9JXB napisał(a): [ -> ]../nowy.c:1:0: warning: "F_CPU" redefined
Zapamiętaj, że Jeśli wyskoczy ci bład z napisem "F_CPU" to albo brak ci linijki:
Kod:
#define F_CPU 16000000
(która definiuje zegar Atmegi) albo jest już zdefiniowana i jest zbędna.
W twoim przypadku jest zbędna - wyraz [redefined] oznacza powtórną definicję zegara Atmegi wykonaną zapewne w tym miejscu:[attachment=4658]
Witam

Cała zawartość pliku nowy.c

"#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_alfanum.h"

void wys_freq(unsigned long int xxx)
{
char freq_string[10];
freq_string[9]=0;
unsigned char i;

i=8;
while(i>0)
{
freq_string[i]=xxx%10+48;
xxx/=10;
i-=1;
}

freq_string[0]=xxx+48;
napis_lcd(freq_string);
}
"


A po kompilacji taki błąd (ten sam error).

"rm -rf nowy.o nowy.elf dep/* nowy.hex nowy.eep nowy.lss nowy.map
Build succeeded with 0 Warnings...
avr-gcc -mmcu=atmega32 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT nowy.o -MF dep/nowy.o.d -c ../nowy.c
avr-gcc -mmcu=atmega32 -Wl,-Map=nowy.map nowy.o -o nowy.elf
d:/avr tools/avr toolchain/bin/../lib/gcc/avr/4.5.1/../../../../avr/lib/avr5/crtm32.o: In function `__vectors':
/home/tools/hudson/workspace/avr8-gnu-toolchain/src/avr-libc/crt1/gcrt1.S:52: undefined reference to `main'
collect2: ld returned 1 exit status

make: *** [nowy.elf] Błąd 1
Build failed with 1 errors and 0 warnings...


skąd sie bierze ten komunikat:

-> /home/tools/hudson/workspace/avr8-gnu-toolchain/src/avr-libc/crt1/gcrt1.S:52: undefined reference to `main'
collect2: ld returned 1 exit status
-<
musisz cofnąć się do lekcji 1 ... Zacytuję ci jej fragment, który wszystko Ci wyjaśni ... :
"... za to, to, co jest poniźej to już prawdziwy i poważny kod. Funkcja main() jest główną funkcją programu, może być tylko jedna funkcja o tej nazwie. Funkcje o innej nazwie są "podfunkcjami" i nie musi ich być.
Natomiast main() musi być. Ta funkcja to poprostu ramy naszego programu ... { takie nawiasy są pod nazwa funkcji } i pomiędzy te nawiasy będziemy wstawiać nasze "rozkazy" dla Atmegi. ... "
czy teraz wiesz jak to naprawić swój program ?
Poprostu za dużo wykasowałeś z pilku main.c
Skoro wszyscy wszystko rozumieją Big Grin idziemy dalej ... Lekcja 11 teraz dodajemy obsługę dwóch przycisków, które będą zmieniały częstotliwość ( wartość zmiennej frequency ) o 1Hz w górę i w dół. Podaje treść całej głównej funkcji programu, zamieńcie tą co macie na tą co ja podałem.
Kod:
int main(void)
{
    unsigned long int frequency;
    frequency = 3710000;
    init_lcd();
    DDRC =0b00000000;    //nie musi być tej linii bo domyślnie wyprowadzenia są wejściami
    PORTC=0b11000000;

    while(1)
    {
        if((PINC&0b01000000)==0)
        {
            frequency-=1;
        }
        if((PINC&0b10000000)==0)
        {
            frequency+=1;
        }
        LCD_PORT &= (~1<<LCD_RS);     // "0" na wyprowadzenie RS w wyświewtlaczu
        bajt_lcd(0x87);               // kursor LCD na pozycję 8 - dla drugiej linii " bajt_lcd(0xc7); "
        wys_freq(frequency);
    }
}
zapisy po prawej stronie są równoznaczne z zapisami po lewej
Kod:
if(bit_is_clear(PINC, 7))    ====    if((PINC&0b10000000)==0)
if(bit_is_clear(PINC, 6))    ====    if((PINC&0b01000000)==0)
if(bit_is_clear(PINC, 0))    ====    if((PINC&0b00000001)==0)
- sprawdźcie, jak ktoś nie rozumie jednego i/lub drugiego zapisu - dajcie znać a będę wyjaśniał.
Przyciski podłaczamy pod PC7 i PC6 - podanie niskiego stanu na PC7 zwiększa częstotliwość o 1Hz, a podanie 0 na PC6 zmniejsza.
Uwaga! Płyty z Microsense mają odwrotnie ponumerowany PORTC ! ( przynajmniej moja tak ma )
Jeszcze jedno - domyślnie chyba jest włączony JTAG na tych płytach - jak nie bedzię działał jakis przycisk to napiszcie.
Operator == to operator logiczny (związany z dwoma stanami PRAWDĄ lub FAŁSZEM reprezentowanymi przez 0 i 1). Pojedyńczy znak równości to operator przypisania (arytmetyczny - czyli związany z liczbami).
Są dwa operatory przyrównania:
== znaczy równy
!= znaczy różny
Zatem zapis if(cośtam==0) ... znaczy jeśli cośtam jest Fałszywe (równe 0)to ...
if(cośtam==1) ... znaczy jeśli cośtam jest Prawdziwe (różne od 0)to ...
zapisy po lewek równają sie zapisom po porawej stronie
Kod:
if(cośtam==0)     ====     if(cośtam!=1)
if(cośtam==1)     ====     if(cośtam!=0)
Na następnej lekcji dodamy możliwość zmiany kroku syntezy.
Kolejna lekcja, 12-sta ... podaje treść main() tak jak poprzednio. Macie tu możliwość zmiany kroku syntezy ale poprzez zmianę wartości zmiennej krok.
Kod:
int main(void)
{
    unsigned long int frequency, krok;
    frequency = 3710000;
    krok=100;
    init_lcd();
    PORTC=0b11000000;
    while(1)
    {
        if((PINC&0b01000000)==0)
        {
            frequency-=krok;
        }
        if((PINC&0b10000000)==0)
        {
            frequency+=krok;
        }
        LCD_PORT &= (~1<<LCD_RS);
        bajt_lcd(0x87);
        wys_freq(frequency);
    }
}
Teraz przydałaby się obsługa dwóch dodatkowych przycisków do zmiany kroku. Poniższy kod wam w tym pomoże, przyciski zmiany kroku dołączone do PC5 i PC4.
Kod:
int main(void)
{
    unsigned long int frequency, krok;
    frequency = 3710000;
    krok=100;
    init_lcd();
    PORTC=0b11110000;
    while(1)
    {
        if((PINC&0b01000000)==0)
        { frequency-=krok; }
        if((PINC&0b10000000)==0)
        { frequency+=krok; }
        if((PINC&0b00010000)==0)
        {    if(krok>9)
                { krok/=10; }    }
        if((PINC&0b00100000)==0)
        {     if(krok<10000000)
            { krok*=10; }    }
        LCD_PORT &= (~1<<LCD_RS);
        bajt_lcd(0x87);
        wys_freq(frequency);
        LCD_PORT &= (~1<<LCD_RS);
        bajt_lcd(0xc3);
        napis_lcd("krok");
        wys_freq(krok);
    }
}
Cytat:Przyciski podłaczamy pod PC7 i PC6


Wytłumaczy mi ktoś, jak uruchomić klawiaturę na płycie ewaluacyjnej ATMEGA32?
Bo tu utknąłem.

Co do kompilacji, wszystko poszło bez problemu.
Umiesz czytac proste schematy ? Jesli tak to spójrz w instrukcję - masz pewnie na płycie plik .pdf A jakk nie to masz tu: http://www.microsense.pl/allegro/EvB_ATm...anuals.pdf
STRONA 6
Jak nie dasz rady to zrobie ci potem fotke co i jak ustawić i połączyć
Końcówka lekcji 12
Teraz wprowadzam przyciski PC4 i PC5 zwiekszenie kroku o 10 razy i zmniejszenie o 10 razy. Wyświetla sie także krok syntezy.
Kod:
int main(void)
{
    unsigned long int frequency, krok;
    frequency = 3710000;
    krok=100;
    init_lcd();
    PORTC=0b11110000;
    while(1)
    {
        if((PINC&0b01000000)==0)
        { frequency-=krok; }
        if((PINC&0b10000000)==0)
        { frequency+=krok; }
        if((PINC&0b00010000)==0)
        {    if(krok>9)
                { krok/=10; }    }
        if((PINC&0b00100000)==0)
        {     if(krok<10000000)
            { krok*=10; }    }
        LCD_PORT &= (~1<<LCD_RS);
        bajt_lcd(0x87);
        wys_freq(frequency);
        LCD_PORT &= (~1<<LCD_RS);
        bajt_lcd(0xc3);
        napis_lcd("krok");
        wys_freq(krok);
    }
}
Piszcie czego nie kumacie
Marcin - czytanie schematu to nie problem, tylko nie mogę umiejscowić na płycie złącza CON2(J101)
Napisy na płycie nijak się mają do opisu na schemacie.
Pokaż te połączenia.
To zworka przy której widnieje napis "4x1 KEYBOARD". Masz tu zdjęcie jak podłaczyć kabelki, zworka ma być zwarta, używaj przycisków w pierwszej (od lewej) kolumnie, czyli 1,4,7,*
[attachment=4669]
Gotowi na kolejną lekcję czy coś tłumaczymy ??
może na przerwę chcecie wyjść ? Tongue
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Przekierowanie