Saglabājiet 2 baitus no I2C Slave

cīnās ar to, kas, iespējams, ir vienkāršs koda fragments, lai kopētu 2 baitus, kas saņemti no I2C vergu, masīvā, lai pēc tam varētu konvertēt uz INT un veikt datu matemātiku.

Šis kods veiksmīgi (saskaņā ar manu I2C analizatoru) nolasa 2 secīgus baitus no vienas reģistra adreses 16 bitu ADC.

void ADC_Initialise( void )
{
    _DINT() ;                              // disable all maskable interrupts

    I2C_SCL_HIGH() ;
    I2C_SCL_OUTPUT() ;
    I2C_SDA_HIGH() ;
    I2C_SDA_OUTPUT() ;

    I2C_Write_Register_3B( ADC, 0x01, 0xC0, 0x83) ;  // Write 2 bytes to ADC Config Register

    for(i=0; i < 10000; i++);

    I2C_Read_Register( ADC, 0x00 );      // Read the 2 byte ADC value

    for(i=0; i < 10000; i++);
    _EINT() ;                             // re-enable the interrupts
}

static unsigned char I2C_Read_Register( char Device_Address, char Register_Address )

{
    unsigned char Value ;

    I2CM_Start( ) ;

    if( I2CM_Out( Device_Address << 1 ) )    //send write control byte + chip address
        return 0 ;

    else if( I2CM_Out( Register_Address ) )  //send register number
        return 0 ;

    I2CM_Start( ) ;                          // Restart

    if( I2CM_Out(( Device_Address << 1 ) | 0x01 ))      //send read control byte + chip address
    return 0 ;

    I2CM_In( &Value, 2 ) ;                    //RJ  6.8.19 input 2 byte ADC value to 'buf'

//      return Value ;                          //rj placed after IC2M_In
    I2CM_Stop( ) ;

    return Value ;                              //rj placed after IC2M_Stop
}


static void I2CM_In( unsigned char* buf, int count )
{
    unsigned char data ;

    for( ; count--; )  // How do I store these 2 bytes in a char[] or INT
    {
            data = 0 ;
            I2C_SDA_INPUT() ;

        volatile unsigned int i = 0 ;

        for( ; i < 8 ; ++i )
        {
            //Set Clock High
            I2C_SCL_HIGH() ;              

            //shift the bit over
            data <<= 1 ;

            if( I2C_SDA_IS_HIGH() )
            {
                data |= 0x01 ;
            }
            //Set Clock Low
            brief_pause( 0x04 ) ;
            I2C_SCL_LOW() ;
        }
        //put the input data byte into the buffer, inc buffer pointer
        *buf++ = data ;

        //take sda to output ack
        I2C_SDA_OUTPUT() ;

        //Set Clock High
        I2C_SCL_HIGH() ;

        //Set Clock Low
        brief_pause( 0x04 ) ;
        I2C_SCL_LOW() ;
    }
}

Tātad, iespējams, man ir nepieciešams masīvs (neparakstīts char adcarray [2], lai savāktu / saglabātu iegūtos lasījumus, tāpēc es mēģināju -

*buf++ = data ;

adcarray[] = data ;

adcarray[] = buf ;

“Sagaidāma izteiksme”, iespējams, nozīmē, ka man ir nepieciešama kāda for cilpa, lai aizpildītu masīvu katrā piegājienā, lai gan *buf līnija jau atrodas 2. skaitīšanas cilpas iekšpusē.

Palīdzība tiek novērtēta (C IAR uz MSP430 un ADS1115 ADC). Ar cieņu, Ralf


c i2c
person Ralph    schedule 07.08.2019    source avots
comment
Kas ir adcarray vai Value — jūs esat izlaidis šo mainīgo deklarācijas.   -  person Chris Turner    schedule 07.08.2019
comment
Sveiki, Kriss! Vērtība ir 2 x 8 bitu vērtības, kas tiek secīgi nolasītas no 16 bitu reģistra adc. Man tie jāievieto masīvā vai ideālā gadījumā INT.   -  person Ralph    schedule 07.08.2019
comment
Funkcija jau aizņem rādītāju un garuma vērtību, kur dati ir jāuzglabā. Kāpēc gan neizsaukt šo funkciju ar sava masīva adresi?   -  person Gerhardh    schedule 07.08.2019
comment
Lūdzu, vienmēr sniedziet pilnīgu informāciju par kļūdu ziņojumiem. Kāds ir precīzs teksts un kurā rindiņā tas ir ziņots? Fragments nav daļa no iepriekš minētās funkcijas. Lūdzu, vienmēr nodrošiniet pilnīgu pārbaudāmu programmu, lai atkārtotu jūsu problēmu.   -  person Gerhardh    schedule 07.08.2019
comment
Kā pārbaudīt, vai esat veiksmīgi izlasījis datus? Kur jūs salīdzināt nolasītās vērtības ar I2C analizatoru?   -  person Gerhardh    schedule 07.08.2019
comment
Sveiki, Gerhardh - esmu pievienojis adcdata[count] = data ; uzreiz aiz *buf++ = dati ; bet es neesmu pārliecināts, ka tas darbojas pareizi, šķiet, ka masīvs ir tukšs   -  person Ralph    schedule 07.08.2019
comment
Man ir ZeroPlus loģiskā stāvokļa analizators, kas parāda, ka 2 baiti tiek nolasīti pareizi, man tie tikai jāsaglabā.   -  person Ralph    schedule 07.08.2019
comment
Ļaujiet mums turpināt šo diskusiju tērzēšanā.   -  person Gerhardh    schedule 07.08.2019
comment
Atvainojiet, es atgriezīšos pie jums, man ir citas lielas problēmas ar I2C kodu   -  person Ralph    schedule 07.08.2019
comment
Ja masīvam ir visas nulles vērtības, šķiet, ka problēma ir ar funkciju I2C_SDA_IS_HIGH(). Ja vēlaties ievietot šos datus mainīgajā Vesels skaitlis, vēlaties izpētīt tīkla un resursdatora baitu secību. (linux.die.net/man/3/ntohl)   -  person Sunil Shahu    schedule 07.08.2019
comment
Labdien, Sunil, ņemiet vērā, ka I2C kodam nav nekā nepareiza, jo mans analizators parāda 2 baitus, kas tiek nolasīti secīgi, un tie satur paredzamās vērtības. Mana problēma ir, kā es varu ievietot šos 2 baitus masīvā vai int, lai es varētu veikt matemātiku utt (2 komplimenta numurs)   -  person Ralph    schedule 07.08.2019
comment
Jūsu kods joprojām ir diezgan nepilnīgs. Kas ir Value? Tajā jāietver 2 baiti, ko nolasa “I2CM_In. What's wrong with the content of Value”? Vai tas atšķiras no tā, ko redzat savā analizatorā?   -  person Gerhardh    schedule 07.08.2019
comment
Jā, ļoti dažādas, analizatorā parādītās vērtības ir 3E pirmajam baitam un f) otrajam baitam. Vērtības vērtība (saskaņā ar IAR) ir “nezināms vai neskaidrs simbols”.   -  person Ralph    schedule 07.08.2019
comment
Tagad esmu parādījis "visu kodu", bet tas, iespējams, vienkārši mulsina cilvēkus, jo problēma ir tāda, ka es joprojām nevaru izdomāt, kā saglabāt baitus, lai varētu tos ievadīt/mērogot utt. Man ir aizdomas, ka man trūkst kaut kā vienkārša.   -  person Ralph    schedule 07.08.2019
comment
unsigned char Value; Kā tam vajadzētu ietilpt 2 baitus?   -  person Gerhardh    schedule 07.08.2019
comment
I2C_Read_Register (ADC, 0x00) atgriež 2 baitus (saskaņā ar I2C analizatoru), to turēšana ir problēma, kurai es meklēju risinājumu.   -  person Ralph    schedule 07.08.2019
comment
Man kaut kas jāpievieno pēc šī *buf++ = dati, lai saglabātu/noturētu 2 baitus, bet es nezinu, kas (šķiet, ka masīvi, ints utt. nedarbojas)   -  person Ralph    schedule 07.08.2019
comment
Vērtība ir atkāpšanās no TI domājamā I2C piemēra koda, man nav pārsteigums, ka tas nedarbojas ar vairāk nekā vienu baitu.   -  person Ralph    schedule 07.08.2019
comment
Problēma ir tāda, ka faktiskais mainīgais aiz buf ir Value, kas piešķir tikai baitu atmiņas. Vērtībai, iespējams, ir jābūt masīvam vai 16 bitu int, un funkcijai I2C_Read_Register ir jāatgriež 16 bitu int. Ja jūs ievietojat pārtraukuma punktu *buf++ = data ;, vai redzat to pašu, ko redz jūsu analizators?   -  person yhyrcanus    schedule 07.08.2019
comment
Paldies, bet atrisināts, ļoti vienkāršs (kaut arī netīrs), ja skaits = 0 vai ja skaits = 1 (tūlīt pēc * buf ++ = dati), tad saglabājiet saistīto baitu atsevišķā rakstzīmē.   -  person Ralph    schedule 07.08.2019


Atbildes (1)


Ja mēģināt saglabāt datus citā masīvā ar funkciju I2CM_In, jūs to izmantojat nepareizi.

static void I2CM_In( unsigned char* buf, int count )
{
    unsigned char data ;

    for( ; count--; )
    {
        ....
        //put the input data byte into the buffer, inc buffer pointer
        *buf++ = data ;
    }
}

Saņemtie dati jau ir saglabāti buferī: buf. Jūsu uzdevums ir nodrošināt buferi, kas ir piemērots rezultāta glabāšanai.

static unsigned char I2C_Read_Register( char Device_Address, char Register_Address )
{
    unsigned char Value ;
...
    I2CM_In( &Value, 2 ) ;  // << Value is 1 byte!
...
  return Value ;
}

Ja vēlaties nolasīt reģistru ar 16 bitiem, jūs nevarat atgriezt vērtību kā unsigned char. Jums ir jāizmanto datu tips, kas spēj saturēt (vismaz) 2 baitus.

Pastāstiet funkcijai, ka buferis ir 2 baiti garš, jūs arī izraisa nenoteiktu uzvedību.

static uint16_t I2C_Read_Register( char Device_Address, char Register_Address )
{
    uint16_t Value ;
...
    I2CM_In( &Value, 2 ) ;
...
    return Value ;
}

Atkarībā no uzticamības, iespējams, būs jāmaina arī baitu secība:

static uint16_t I2C_Read_Register( char Device_Address, char Register_Address )
{
    uint8_t tmp_Value[2] ;
...
    I2CM_In( tmp_Value, 2 ) ;
    uint16_t Value;

#if MSB_FIRST
    Value = ((uint16_t)tmp_Value[0]) << 8 || tmp_Value[1];
#else // LSB_FIRST
    Value = ((uint16_t)tmp_Value[1]) << 8 || tmp_Value[0];
#endif
...
    return Value ;
}
person Gerhardh    schedule 07.08.2019
comment
Paldies, es faktiski izmantoju (kaut arī diezgan briesmīgi) - if (count == 0) { ADC_Value2 = data ; } if (skaits == 1) { ADC_Vērtība1 = dati ; } - person Ralph; 07.08.2019
comment
Protams, mēģinājums apvienot divas atsevišķas rakstzīmes int (matemātikas darbam) nedarbojas (izmantojot standarta maiņas pirmo rakstzīmi 8 biti, pievienojiet otro zīmi utt (IAR Workbench), bet tas ir cits stāsts. - person Ralph; 07.08.2019
comment
Pirms pārslēgšanas varat mēģināt nodot vērtību int. - person Gerhardh; 07.08.2019