Array als Rückgabewert kann nicht angezeigt werden

OP #4490963
Lesenswert?

Hallo Zusammen,

ich versuche gerade mittels SPI Zellspannung auszulesen. Diese kommen 
von einem LTC6804-1. Leider scheitere ich gerade an dem Rückgabewert 
oder besser gesagt an dem Pointer auf meine Daten. Lasse ich mir in der 
Funktion "void spi_write_read" die Werte auf dem LCD anzeigen sehe ich 
eine Zahl zwischen 0 und 2^16. Das ist gut soweit. Möchte ich aber den 
Speicherbereich in der die Funktion aufrufenden Schleife ansehen, ist 
der Wert für alle Spannung konstant 0.

Aufrufende Funktion:
1
/***********************************************//**
2
 \brief Read the raw data_spi from the LTC6804 cell voltage register
3

4
 The function reads a single cell voltage register and stores the read data_spi
5
 in the *data_spi point as a byte array. This function is rarely used outside of
6
 the LTC6804_rdcv() command.
7

8
 @param[in] uint8_t reg; This controls which cell voltage register is read back.
9

10
          1: Read back cell group A
11

12
          2: Read back cell group B
13

14
          3: Read back cell group C
15

16
          4: Read back cell group D
17

18
 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
19

20
 @param[out] uint8_t *data_spi; An array of the unparsed cell codes
21

22
Command Code:
23
-------------
24

25
|CMD[0:1]        |  15   |  14   |  13   |  12   |  11   |  10   |   9   |   8   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
26
|-----------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
27
|RDCVA:            |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   1   |   0   |   0   |
28
|RDCVB:            |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   1   |   1   |   0   |
29
|RDCVC:            |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   1   |   0   |   0   |   0   |
30
|RDCVD:            |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   1   |   0   |   1   |   0   |
31

32
 *************************************************/
33
void LTC6804_rdcv_reg(uint8_t reg, //Determines which cell voltage register is read back
34
                                          uint8_t total_ic, //the number of ICs in the
35
                                          uint8_t *data_spi //An array of the unparsed cell codes
36
                                          )
37
{
38
  const uint8_t REG_LEN = 8; //number of bytes in each ICs register + 2 bytes for the PEC
39
  uint8_t cmd[4];
40
  uint16_t cmd_pec, cmd_pec_h;
41

42
  Lcd_Out(2,1, lcd_line2);
43
  //1
44
  if (reg == 1)     //1: RDCVA
45
  {
46
    cmd[1] = 0x04;
47
    cmd[0] = 0x00;
48
  }
49
  else if(reg == 2) //2: RDCVB
50
  {
51
    cmd[1] = 0x06;
52
    cmd[0] = 0x00;
53
  }
54
  else if(reg == 3) //3: RDCVC
55
  {
56
    cmd[1] = 0x08;
57
    cmd[0] = 0x00;
58
  }
59
  else if(reg == 4) //4: RDCVD
60
  {
61
    cmd[1] = 0x0A;
62
    cmd[0] = 0x00;
63
  }
64

65
  sprintf(lcd_line2, "rdcv_an Slave %x", cmd[1]);
66
 Lcd_Out(2,1, lcd_line2);
67
  //2
68
  cmd_pec = pec15_calc(2, cmd);
69
  cmd_pec_h = pec15_calc_h(2, cmd);
70
  cmd[2] = (uint8_t)(cmd_pec_h >> 8);
71
  cmd[3] = (uint8_t)(cmd_pec_h);
72

73
  //3
74
  wakeup_idle (); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed.
75

76
  //4
77
  Chip_Select = 0;
78
  spi_write_read(cmd,4,data_spi,(REG_LEN*total_ic));
79
  Chip_Select = 1;
80
}
81
/*
82
  LTC6804_rdcv_reg Function Process:
83
  1. Determine Command and initialize command array
84
  2. Calculate Command PEC
85
  3. Wake up isoSPI, this step is optional
86
  4. Send Global Command to LTC6804 daisy chain
87
*/


Funktion "void spi_write_read":

1
/*******************************************************************************
2
 \brief Writes and read a set number of bytes using the SPI port.
3

4
@param[in] uint8_t tx_data_spi[] array of data_spi to be written on the SPI port
5
@param[in] uint8_t tx_len length of the tx_data_spi array
6
@param[out] uint8_t rx_data_spi array that read data_spi will be written too.
7
@param[in] uint8_t rx_len number of bytes to be read from the SPI port.
8

9
*******************************************************************************/
10

11
void spi_write_read(uint8_t tx_data_spi[],//array of data_spi to be written on SPI port
12
                                        uint8_t tx_len, //length of the tx data_spi arry
13
                                        uint8_t *rx_data_spi,//Input: array that will store the data_spi read by the SPI port
14
                                        uint8_t rx_len //Option: number of bytes to be read from the SPI port
15
                                        )
16
{
17
uint8_t i;
18
uint16_t spishit[3];
19

20
  for(i = 0; i < tx_len; i++)
21
  {
22
   SPI1_Write(tx_data_spi[i]);
23

24
  }
25

26
  for(i = 0; i < rx_len; i++)
27
  {
28
    rx_data_spi[i] = (uint8_t)SPI1_READ(0xFF);
29
  }
30
}

Die Displayausgabe habe ich entfernt. Kann mir jemand weiter helfen, 
warum ich in der aufrufenden Funktion die Werte aus "rx_data_spi" nicht 
anzeigen lassen kann?

VG und Danke
OP #4491025
Lesenswert?

So:
1
/***********************************************//**
2
 \brief Reads and parses the LTC6804 cell voltage registers.
3

4
 The function is used to read the cell codes of the LTC6804.
5
 This function will send the requested read commands parse the data_spi
6
 and store the cell voltages in cell_codes variable.
7

8
 @param[in] uint8_t reg; This controls which cell voltage register is read back.
9

10
          0: Read back all Cell registers
11

12
          1: Read back cell group A
13

14
          2: Read back cell group B
15

16
          3: Read back cell group C
17

18
          4: Read back cell group D
19

20
 @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
21

22
 @param[out] uint16_t cell_codes[]; An array of the parsed cell codes from lowest to highest. The cell codes will
23
  be stored in the cell_codes[] array in the following format:
24
  |  cell_codes[0][0]| cell_codes[0][1] |  cell_codes[0][2]|    .....     |  cell_codes[0][11]|  cell_codes[1][0] | cell_codes[1][1]|  .....   |
25
  |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
26
  |IC1 Cell 1        |IC1 Cell 2        |IC1 Cell 3        |    .....     |  IC1 Cell 12      |IC2 Cell 1         |IC2 Cell 2       | .....    |
27

28
  @return int8_t, PEC Status.
29

30
    0: No PEC error detected
31

32
    -1: PEC error detected, retry read
33

34

35
 *************************************************/
36
uint8_t LTC6804_rdcv(uint8_t reg, // Controls which cell voltage register is read back.
37
           uint8_t total_ic, // the number of ICs in the system
38
           uint16_t cell_codes[][12] // Array of the parsed cell codes
39
           )
40
{
41

42

43
  const uint8_t NUM_RX_BYT = 8;
44
  const uint8_t BYT_IN_REG = 6;
45
  const uint8_t CELL_IN_REG = 3;
46

47
  uint8_t *cell_data_spi;
48
  uint16_t pec_error = 0;
49
  uint16_t parsed_cell;
50
  uint16_t received_pec;
51
  uint16_t data_spi_pec, data_spi_pec_h;
52
  uint8_t data_spi_counter=0; //data_spi counter
53
  uint8_t cell_reg;
54
  uint8_t current_ic;
55
  uint8_t current_cell;
56

57
  cell_data_spi = (uint8_t *) malloc((NUM_RX_BYT*total_ic)*sizeof(uint8_t));
58
                              //The pec_error variable is simply set negative if any PEC errors
59
  Lcd_Out(2,1, "rdcv_readcellvlt");
60

61
  //1.a
62
  if (reg == 0)
63
  {
64
    //a.i
65
    for(cell_reg = 1; cell_reg<5; cell_reg++)                      //executes once for each of the LTC6804 cell voltage registers
66
    {
67
      data_spi_counter = 0;
68
      LTC6804_rdcv_reg(cell_reg, total_ic,cell_data_spi );                //Reads a single Cell voltage register
69

70
      for (current_ic = 0 ; current_ic < total_ic; current_ic++)       // executes for every LTC6804 in the daisy chain
71
      {                                           // current_ic is used as the IC counter
72

73
        //a.ii
74
    for(current_cell = 0; current_cell<CELL_IN_REG; current_cell++)     // This loop parses the read back data_spi into cell voltages, it
75
        {                                           // loops once for each of the 3 cell voltage codes in the register
76

77
          parsed_cell = cell_data_spi[data_spi_counter] + (cell_data_spi[data_spi_counter + 1] << 8);//Each cell code is received as two bytes and is combined to
78
                                           // create the parsed cell voltage code
79

80
          cell_codes[current_ic][current_cell  + ((cell_reg - 1) * CELL_IN_REG)] = parsed_cell;
81
          data_spi_counter = data_spi_counter + 2;                       //Because cell voltage codes are two bytes the data_spi counter
82
                                          //must increment by two for each parsed cell code
83
        }
84
    //a.iii
85
        received_pec = (cell_data_spi[data_spi_counter] << 8) + cell_data_spi[data_spi_counter+1]; //The received PEC for the current_ic is transmitted as the 7th and 8th                                       //after the 6 cell voltage data_spi bytes
86
        data_spi_pec = pec15_calc(BYT_IN_REG, &cell_data_spi[current_ic * NUM_RX_BYT]);
87
  data_spi_pec_h = pec15_calc_h(BYT_IN_REG, &cell_data_spi[current_ic * NUM_RX_BYT]);
88

89
          sprintf(lcd_line1, "PECvgl=%x, %x", received_pec, data_spi_pec_h);                              //The pec_error variable is simply set negative if any PEC errors
90
          Lcd_Out(1,1, lcd_line1);
91
          Delay_ms(3000);
92
        if(received_pec != data_spi_pec_h)
93
        {
94
          pec_error = -1;
95
                                                                                                                   //The pec_error variable is simply set negative if any PEC errors
96
          Lcd_Cmd(_LCD_CLEAR);               // Clear display
97
          Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
98
          Delay_ms(1000);
99
          sprintf(lcd_line1, "PEC_ERR = %d", pec_error);                              //The pec_error variable is simply set negative if any PEC errors
100
          Lcd_Out(1,1, lcd_line1);                                          //are detected in the serial data_spi
101
        }
102
        data_spi_counter=data_spi_counter+2;                        //Because the transmitted PEC code is 2 bytes long the data_spi_counter
103
                                          //must be incremented by 2 bytes to point to the next ICs cell voltage data_spi
104
      }
105
    }
106
  }
107
 //1.b
108
  else
109
  {
110
  //b.i
111
    //....
112
  }
113

114
 //2
115
 FreeMem(cell_data_spi, sizeof(cell_data_spi));
116
return(pec_error);
117
}
118
/*
119
  LTC6804_rdcv Sequence
120

121
  1. Switch Statement:
122
    a. Reg = 0
123
      i. Read cell voltage registers A-D for every IC in the daisy chain
124
      ii. Parse raw cell voltage data_spi in cell_codes array
125
      iii. Check the PEC of the data_spi read back vs the calculated PEC for each read register command
126
    b. Reg != 0
127
      i.Read single cell voltage register for all ICs in daisy chain
128
      ii. Parse raw cell voltage data_spi in cell_codes array
129
      iii. Check the PEC of the data_spi read back vs the calculated PEC for each read register command
130
  2. Return pec_error flag
131
*/

In "cell_codes" sollten dann die Zellspannungen stehen. Am Ende des 
Code-Blocks sind die einzelnen Abschnitte kurz erklärt.

Was mir auch überhaupt nicht klar ist, wie der Eingabeparameter einer 
Funktion als Ausgabe dienen kann? Beispiel: Funktion "spi_write_read: 
@param[out] uint8_t rx_data_spi array that read data_spi will be written 
too."
Gast #4491119
Lesenswert?

Jetzt fehlen noch die Definitionen von REG_LEN und NUM_RX_BYT

Stefan S. schrieb:
> Was mir auch überhaupt nicht klar ist, wie der Eingabeparameter einer
> Funktion als Ausgabe dienen kann? Beispiel: Funktion "spi_write_read:
> @param[out] uint8_t rx_data_spi array that read data_spi will be written
> too."

Der Kommentar ist etwas konfus.Besser wäre "@param[out] uint8_t* 
rx_data_spi ..."
'rx_data_spi' ist ein Pointer und über diesen kann die Funktion 
Speicherbereiche außerhalb ihres eigenen Gültigkeitsbereichs ändern und 
damit u.a. auch Werte an den Aufrufer übermitteln.
OP #4491127
Lesenswert?

fb schrieb:
> Jetzt fehlen noch die Definitionen von REG_LEN und NUM_RX_BYT

-> const uint8_t NUM_RX_BYT = 8;
-> const uint8_t REG_LEN = 8;

Sind in den Funktionen LTC6804_rdcv und LTC6804_rdcv_reg definiert, 
wurden also nicht vergessen:).

fb schrieb:
> Der Kommentar ist etwas konfus.Besser wäre "@param[out] uint8_t*
> rx_data_spi ..."
> 'rx_data_spi' ist ein Pointer und über diesen kann die Funktion
> Speicherbereiche außerhalb ihres eigenen Gültigkeitsbereichs ändern und
> damit u.a. auch Werte an den Aufrufer übermitteln.

-> So habe ich  mir das gedacht, aber warum das nicht läuft bekomme ich 
nicht heraus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren