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



Teraz jest 20 kwi 2024, o 09:03


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: 27224
Lokalizacja: Szczecin
Pomógł: 1041

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: 27224
Lokalizacja: Szczecin
Pomógł: 1041

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: 27224
Lokalizacja: Szczecin
Pomógł: 1041

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 7 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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO