[C] wskaznik struktury na funkcje

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Awatar użytkownika
mictronic
-
Posty: 81
Rejestracja: 04 paź 2006, 19:28
Lokalizacja: Bydgoszcz
Kontakt:

[C] wskaznik struktury na funkcje

Post autor: mictronic » 21 lis 2013, 21:36

Witam, przyznam ze nie rozumiem wcale wskaźników, posiłkuje się tylko przykładami , które znalazłem w internecie.

Mam za zadanie wrzucić tablice bajtów jako parametr do funkcji. i Zrobiłem to w ten sposób jednak program się nie kompiluje. Sprawdziłem na milion sposobów, w jednych kompiluje się z warningiem w innych wcale z wieloma bądź jednym błędem.

Program okrojony do najważniejszych części:

Kod: Zaznacz cały


typedef struct
{

uint8_t CFGR0;    
uint8_t CFGR1;    
uint8_t CFGR2;   
uint8_t CFGR3;  
uint8_t VUV;    
uint8_t VOV;

} ltc6803_cfg ;

 ltc6803_cfg *CFGR;

int main(void) 
{


}

void ltc6803_write_cmd (ltc6803_cfg *CFGR)
{

	spi_send(WRCFG);
	spi_send(PEC_WRCFG);
	spi_send(CFGR->CFGR0);
	spi_send(CFGR->CFGR1);
	spi_send(CFGR->CFGR2);
	spi_send(CFGR->CFGR3);
	spi_send(CFGR->VUV);
	spi_send(CFGR->VOV);
	spi_send(get_crc((*CFGR),6));



}

uint8_t get_crc(uint8_t *array, uint8_t len)
{

   return rem;
 }

To prawdopodobnie proste, wprawne oko od razu wypatrzy błędy, więc nawet nie będę wskazywał błędów kompilacji.

Dziekuje Pozdrawiam!

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 21 lis 2013, 22:22

Zapewne błędem jest niekompatybilnosć typu przekazywanego do funkcji get_crc, przekazujesz wskaźnik do struktury a funkcja oczekuje na wskaźnik do tablicy. Zacznij od rzutowania typu wskaźnika w wywołaniu get_crc, jednak jest to mało eleganckie rozwiązanie.
No i mówiąc kolokwialnie usuń gwiazdkę z wywołania get_crc.

Awatar użytkownika
mictronic
-
Posty: 81
Rejestracja: 04 paź 2006, 19:28
Lokalizacja: Bydgoszcz
Kontakt:

Post autor: mictronic » 22 lis 2013, 13:33

Rzeczywiście, kod dla funkcji get_crc wygląda tak:

Kod: Zaznacz cały

unsigned char ltcComputeCRC(unsigned char *array, unsigned char len)
{
   unsigned char rem = 0, i, j;

   for(i=0; i<len; i++) {
      rem = rem ^ array[i];
      for(j=0; j<8; j++) {
         if(rem & 0x80) {   // if leftmost (most significant) bit is set
            rem = (rem << 1) ^ 0x07;
         } else {
            rem = rem << 1;
         }
      }
   }
 
   return rem;
 }
Pytanie jak przerobić ten kod tak by w łatwy sposób pobierać dane do tej funkcji?
Chodzi o uniwersalny sposób by łatwo wskazać miejsce pobieranych danych a nie sztywno wskazać tablice. Mogę prosić o jakieś nakierowanie? Lub jak przerobić funkcje get_crc by obsługiwała ten wskaźnik.

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 22 lis 2013, 16:27

Na początek spróbuj czegoś takiego :

Kod: Zaznacz cały

 spi_send(get_crc((uint8_t *)CFGR, 6));

Awatar użytkownika
mictronic
-
Posty: 81
Rejestracja: 04 paź 2006, 19:28
Lokalizacja: Bydgoszcz
Kontakt:

Post autor: mictronic » 23 lis 2013, 15:14

Niestety, poległem ze strukturami a tymbardziej ze wskaznikami. Deklarujac strukture przed funkcja main, wywalalo blad przy odwolywaniu sie do jej zawartosci

Kod: Zaznacz cały

a=struktura.xyz
Błąd nie pojawiał sie, gdy wszystko bylo w jednej funkcji, nierozumiem tego.

Próbuje wlasnie poradzic sobei z tym w inny sposob, zalaczam caly kod:

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>
#include "LCD/lcd44780.h"

#define SET_BIT(r,x) r|=_BV(x)
#define CLR_BIT(r,x) r&=~_BV(x)
#define TOG_BIT(r,x) r^=_BV(x)

#define MISO PB6
#define MOSI PB5 	
#define SCK PB7	
#define SCS PB4		

#define SPIPORT PORTB
#define SPIDIR DDRB

#define CS_0 SPIPORT &= ~(1<<SCS)
#define CS_1 SPIPORT |= (1<<SCS)

#define TOGGLE_CS 0
#define numdevice 1

void spi_init (void);
uint8_t spi_send( uint8_t bajt );

void ltc6803_write_cmd (void);
uint8_t get_crc(uint8_t *array, uint8_t len);

#define WRCFG   0x01    //Write Config
#define RDCFG   0x02  //Read config
#define RDCV    0x04    //Read Cell Voltage
#define STCVAD  0x10    //Cell Volatge A/D Conversion (on all cells)
#define STOWAD  0x20    //Open_Wire_AD_Conversion (on all cells)

#define PEC_WRCFG   0xC7    //Write Config
#define PEC_RDCFG   0xCE  //Read config
#define PEC_RDCV    0xDC    //Read Cell Voltage
#define PEC_STCVAD  0xB0    //Cell Volatge A/D Conversion (on all cells)
#define PEC_STOWAD  0x20    //Open_Wire_AD_Conversion (on all cells)

#define WDT 7
#define GPIO2 6
#define GPIO1 5

uint8_t CDC=1;//Comparator Duty Cycle
uint8_t ltc6803_cfg[6];

#define CFGR0 0    
#define CFGR1 1  
#define CFGR2 2   
#define CFGR3 3 
#define VUV 4   
#define VOV 5 

	
	


int main(void) 
{

	lcd_init();
	lcd_cls();
	
	
	lcd_locate(0,0);
	lcd_str("");

}

void ltc6803_write_cmd (void)
{


	//CFGR2= (CFGR2 & 0xF0) | (CDC & 0x0F);//dodanie CDC do CFGR2

	#if TOGGLE_CS == 0
	CS_1;
	#else 
	CS_0;
	#endif

	spi_send(WRCFG);
	spi_send(PEC_WRCFG);
	

	spi_send(ltc6803_cfg[CFGR0]);
	//spi_send(crc->CFGR1);
	//spi_send(crc->CFGR2);
	//spi_send(ltc6803_cfg->CFGR3);
	//spi_send(ltc6803_cfg->VUV);
	//spi_send(ltc6803_cfg->VOV);
	spi_send(get_crc(ltc6803_cfg[CFGR0],6));

	#if TOGGLE_CS == 0
	CS_0;
	#else 
	CS_1;
	#endif

}

void spi_init (void)
{

	SET_BIT(SPIPORT,MISO);

	SPIDIR |= (1 << MOSI) | (1 << SCK) | (1 << SCS); 	
	SET_BIT(SPIPORT,MISO);

	SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1)| (1 << SPR0);

#if TOGGLE_CS == 0
CS_1;
#else 
CS_0;
#endif
	
}

uint8_t spi_send( uint8_t bajt ) 
{
	SPDR = bajt;
	while( !(SPSR & (1<<SPIF)) );
	
	return SPDR;

}

uint8_t get_crc(uint8_t *array, uint8_t len)
{
   uint8_t rem = 0, i=0, j=0;

   for(i=0; i<len; i++) {
      rem = rem ^ array[i];
      for(j=0; j<8; j++) {
         if(rem & 0x80) {   // if leftmost (most significant) bit is set
            rem = (rem << 1) ^ 0x07;
         } else {
            rem = rem << 1;
         }
      }
   }
 
   return rem;
 }
wywala warning w miejscu przesylania tablicy "ltc6803_cfg[CFGR0]" do funkcji spi_send

spi_send(get_crc(ltc6803_cfg[CFGR0],6));

Kod: Zaznacz cały

main.c:93: warning: passing argument 1 of 'get_crc' makes pointer from integer without a cast
Domniemam ze któreś zmienne nie sa ze soba kompatybilne, ale wszystkie sa przeciez typu 8 bitowego uint8_t

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 23 lis 2013, 15:30

No to jedziemy :

Kod: Zaznacz cały

get_crc(ltc6803_cfg[CFGR0],6);
Funkcja get_crc przyjmuje jako pierwszy argument adres zmiennej typu uint8_t, natomiast Ty przekazukesz jej wartość pierwszego elementu tablicy zmiennych typu uint8_t.

Zapisz to tak :

Kod: Zaznacz cały

get_crc(&ltc6803_cfg[CFGR0],6);
czyli przekaż adres pierwszego elementu tablicy
albo tak :

Kod: Zaznacz cały

get_crc(ltc6803_cfg,6);
czyli przekaż adres pierwszego elementu tablicy.
"nazwa" tablicy jest jednocześnie wskaźnikiem na pierwszy jej element co powinieneś wiedzieć z analizy funkcji get_crc, a konkretnie fragmentu :

Kod: Zaznacz cały

array[i]
bo array to przecież wskaźnik a nie tablica, a Ty traktujesz zmienną array jak tablicę.

Awatar użytkownika
mictronic
-
Posty: 81
Rejestracja: 04 paź 2006, 19:28
Lokalizacja: Bydgoszcz
Kontakt:

Post autor: mictronic » 25 lis 2013, 21:36

Dziękuję za pomoc serdecznie! Pozdrawiam! :)

ODPOWIEDZ