Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 19 maja 2025, o 18:40


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
    Autor Wiadomość
    PostNapisane: 2 lis 2011, o 17:03 
    Offline
    Nowy

    Dołączył(a): 02 lis 2011
    Posty: 4
    Pomógł: 0

    Witam.

    Chciałem zrealizować sobie odczyt danych z akcelerometru po i2c, a następnie wyświetlenie ich na wyświetlaczu LCD. Część programu od LCD działa, niestety problem pojawia się przy odczycie z akcelerometru (a dokładniej to przed, bo jeszcze nawet nie doszedłem do końca początku ;)). W podręczniku opisane jest zapisanie odebranych danych do wskaźnika (tak mi się wydaje). Chciałem zmienić sobie to na zwykłą tablicę danych, żeby potem ładnie stworzyć sobie z tego zmienną i wrzucić ją na wyświetlacz. Jednak wyskakuje błąd przy linii

    Kod:
    while (len--) (bufor++) = TWI_read( len ? ACK : NACK );


    o treści

    ../lcdmain.c:147: error: lvalue required as left operand of assignment

    Oczywiście przy zachowaniu *buf zamiast 'bufor' wszystko się kompiluje, ale nie wiem co z tym dalej zrobic :)
    Wszystkie kody są na podstawie Pana książki (po dzikiej edycji w czasie testowania różnych wariantów, przepraszam za chaos;))

    oto kod programu:
    Kod:
    /*
     * main.c
     *
     *  Created on: 2010-03-31
     *       Autor: Miros3aw Kardao
     */
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/eeprom.h>

    #include "LCD/lcd44780.h"


    #define ACK 1
    #define NACK 0
    //#define SLA 0x3A
    //#define adr 0x32

    //#include "twi.h"






    // poni?sz1 linijke czasami trzeba wpisaa w eclipse przed definicjami
    // zmiennych w pamieci EEPROM, ?eby nie podkreola3 sk3adni jako b3ednej
    #define EEMEM __attribute__((section(".eeprom")))

    //char PROGMEM tab1[] = {"tekst1"};
    //char EEMEM tab2[] = {"tekst2"};

    uint8_t znak_L[] = {16,16,18,20,24,16,31,0};      // wzór znaku litery L w pamieci RAM
    uint8_t znak_o[] EEMEM = {4,32,14,17,17,17,14,0};   // wzór znaku litery ó w pamieci EEPROM
    uint8_t znak_buzka[] PROGMEM = {14,17,27,17,17,21,17,14};   // wzór znaku buYki w pamieci FLASH
    uint8_t znak_termo[] PROGMEM = {4,10,10,10,17,31,31,14};   // wzór znaku termometru w pamieci FLASH

    volatile uint8_t pwm1, pwm2, pwm3;


    int main(void)
    {
       DDRD |= (1<<PD0);
       PORTD |= (1<<PD0);

       lcd_init();



    uint8_t bufor [6];                             //                <==================================== czy tak można?


       TWI_read_buf(0x3A, 0x32, 6, bufor);




    //   lcd_str_P(tab1);            // napis z pamieci FLASH
    //   lcd_locate(0,10);            //pierwsza cyfra to rzad, druga to nr kolumny startujacej!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //   lcd_str_P( PSTR("x") );   // napis z pamieci FLASH
    //   lcd_locate(1,0);
    //   lcd_str_E(tab2);            // napis z pamieci EEPROM
       lcd_locate(1,0);

       lcd_str("x");            // napis z pamieci RAM,



    //   lcd_locate(0,0);
    //   lcd_str("dsds");
       // za3adowanie znaków do pamieci CGRAM
       lcd_defchar(0x80, znak_L);
       lcd_defchar_E(0x81, znak_o);
       lcd_defchar_P(0x82, znak_buzka);
       lcd_defchar_P(0x83, znak_termo);


       // wyowietlenie w3asnych znaków na LCD
       lcd_locate(0,7);
       lcd_str("\x80\x81");
       lcd_locate(1,8);
       lcd_str("\x82");
       lcd_locate(1,7);
       lcd_str("\x83");

       while(1);



    }



    void i2cSetBitrate(uint16_t bitrateKHz) {
       uint8_t bitrate_div;

       bitrate_div = ((F_CPU/1000l)/bitrateKHz);
       if(bitrate_div >= 16)
          bitrate_div = (bitrate_div-16)/2;

       TWBR = bitrate_div;
    }

    void TWI_start(void) {
       TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
       while (!(TWCR&(1<<TWINT)));
    }

    void TWI_stop(void) {
       TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
       while ( !(TWCR&(1<<TWSTO)));
    }

    void TWI_write(uint8_t bajt) {
       TWDR = bajt;
       TWCR = (1<<TWINT)|(1<<TWEN);
       while ( !(TWCR&(1<<TWINT)));
    }

    uint8_t TWI_read(uint8_t ack) {
       TWCR = (1<<TWINT)|(ack<<TWEA)|(1<<TWEN);
       while ( !(TWCR & (1<<TWINT)));
       return TWDR;
    }



    void TWI_write_buf( uint8_t SLA, uint8_t adr, uint8_t len, uint8_t bufor )
    {

       TWI_start();
       TWI_write(SLA);
       TWI_write(adr);
       while (len--) TWI_write(bufor++);
       TWI_stop();
    }



    void TWI_read_buf(uint8_t SLA, uint8_t adr, uint8_t len, uint8_t bufor) {

       TWI_start();
       TWI_write(SLA); // adres ukladu slave 0x3A-zapis /0x3B-odczyt
       TWI_write(adr); /// przekazanie adresu adxl_datax,y,z
       TWI_start();
       TWI_write(SLA + 1); // ponowny start (repeated start)
       while (len--) bufor++ = TWI_read( len ? ACK : NACK );
       TWI_stop();
    }




    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 2 lis 2011, o 17:11 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27401
    Lokalizacja: Szczecin
    Pomógł: 1043

    Ojo joj :(

    taka operacja:

    Kod:
    while (len--) (bufor++) = TWI_read( len ? ACK : NACK );


    jest zgodnie z komunikatem błędu absolutnie niedozwolona. Proponuję na głos - tzn tu na forum przeanalizować co kolega chciał osiągnąć takim zapisem i co wg kolegi oznacza tutaj:

    (bufor++) = ...

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 2 lis 2011, o 17:49 
    Offline
    Nowy

    Dołączył(a): 02 lis 2011
    Posty: 4
    Pomógł: 0

    konkretnie to zrozumiałem to w ten sposób:
    w chwili gdy zmniejsza mi się wielkość "len" (pętla odpowiedzialna za odbieranie danych z bufora) zwiększa mi się bufor (tablica)do którego przekazywane są dane odczytane z akcelerometru. Wszystko trwa do momentu gdy len=0


    w sumie to faktycznie niewiele w tym sensu, ale nie wiem jak to obejść. mysle, ze powininem jakos oddzielic numery poszczegolnych elementow tablicy od ich zawartosci...



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 lis 2011, o 21:13 
    Offline
    Nowy

    Dołączył(a): 02 lis 2011
    Posty: 4
    Pomógł: 0

    to może spytam inaczej:

    czy da się jakoś załatwić zczytywanie kolejnych bajtów z kolejnych rejestrów bez tego wskaźnika? (przeraża mnie on)

    jeśli nie to:

    czy wystarczy utworzyć zmienną buf która będzie łapać bajty wysłane pod adresy z wskaźnika?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 lis 2011, o 22:32 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27401
    Lokalizacja: Szczecin
    Pomógł: 1043

    Ale ja na prawdę coraz mniej rozumiem kolegę, i zastanawiam się po co cała ta przeróbka dobrze działającej funkcji na tą dziwną rzecz na górze ???

    przecież:

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    to pięknie zapisuje wszystko do wskazanego bufora - czyli robi dokładnie to o co koledze chodzi - tzn tak mi się wydaje z opisu. No ale skoro wskaźnik przeraża - to niedobrze :( .... trzeba w takim razie najpierw dobrze doczytać i poćwiczyć wskaźniki , ew zadać dodatkowe pytania gdy się czegoś nie zrozumie. Bo tu - to mamy na razie super podstawowe operacje na wskaźnikach.

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 7 lis 2011, o 12:35 
    Offline
    Nowy

    Dołączył(a): 02 lis 2011
    Posty: 4
    Pomógł: 0

    Poczytałem więcej o wskaźnikach i wydaje mi się, że ten kod pokaże w jaki sposób rozumiem zbieranie danych z tego bufora:

    Kod:
    #include <stdio.h>
    #include <avr/io.h>
    #include <stdlib.h>

    #include "i2c_soft_cfg.h"
    #include "i2c_soft.h"
    #include "lcd44780.h"

    #include <util/delay.h>

    u08 a;
    u08 *buf;

    int main(void)
    {

    lcd_init();                                    // inicjalizacja wyświetlacza LCD
    i2c_init();

    a = (1<<3);
    *buf = a;

    I2C_write_buf(0xA6, 0x2D, 1, *buf);               // inicjalizacja ADXL w measurement mode

          while(1)
          {
             

             I2C_read_buf(0xA7, 0x32, 2, *buf);         // zczytanie wartości X (dwa bajty po sobie) do bufora

             lcd_locate(0,5);                  // wyświetlanie zawartości bufora
             lcd_char(*buf);


             _delay_ms(100);
          }

    }



    Kod ma na celu włączenie akcelerometru z którego chcę zczytywać dane z adresów 0x32 i 0x33, łącząc je w jedną liczbę i następnie wyświetlać na LCD. By to osiągnąć muszę najpierw przestawić bit D3 na stan wysoki, co też próbuję wykonać zapisując przesunięcie bitowe w odp. rejestr. Mam praktycznie pewność, że źle pochodzę do sprawy i że może się to rozbijać o typ wysyłanych danych (wysłanie przesunięcia bitowego jako unsigned char), ale prawdę mówiąc nie mogę dojść jak to do końca powinno wyglądać.

    Pojawia się warning o treści:
    warning: passing argument 4 of 'I2C_write_buf' makes pointer from integer without a cast
    note: expected 'u08 *' but argument is of type 'u08'

    Bardzo bym prosił o jakąś wskazówkę :)


    //edit: to co dzieje się potem przy zczytywaniu danych do buf w read_buf jeszcze nie zostało przemyślane, na razie chciałbym mieć działający akcelerometr



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 7 lis 2011, o 13:08 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27401
    Lokalizacja: Szczecin
    Pomógł: 1043

    No to widać postęp po przeczytaniu o wskaźnikach ;) super

    tylko jeszcze wkradł się koledze mały błąd (jednak to można zrozumieć) otóż zapis nie może wyglądać tak:

    Kod:
    a = (1<<3);
    *buf = a;


    tylko jeśli by już iść tą drogą to tak:

    Kod:
    a = (1<<3);
    buf = &a;


    a można jeszcze prościej , tzn w ogóle pozbyć się w tym przypadku zmiennej wskaźnikowej buf i przesłać bezpośrednio adres zmiennej a, czyli:

    Kod:
    a = (1<<3);
    I2C_write_buf(0xA6, 0x2D, 1, &a);


    Popełnił bowiem kolega tu drobny błąd myślowy - bo jak już to mogłoby i powinno wyglądać prawidłowo też tak:

    Kod:
    #define MAX_BUF_SIZE   10   // definiujemy maksymalny rozmiar bufora
    u08 buf[ MAX_BUF_SIZE ];

    buf[0] = (1<<3);
    I2C_write_buf(0xA6, 0x2D, 1, buf);


    a jeśli kolega zechce innym razem więcej bajtów przesłać niż jeden ??? to wtedy wystarczy napełnić kilka bajtów bufora np ze trzy i wysłać je tak:

    Kod:
    I2C_write_buf(0xA6, 0x2D, 3, buf);


    czy teraz jaśniej ???

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 9 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO