I2C स्लेव्ह वरून 2 बाइट्स साठवा

I2C स्लेव्हकडून मिळालेल्या 2 बाइट्सची अॅरेमध्ये कॉपी करण्यासाठी कोडचा एक सोपा तुकडा काय आहे यासह संघर्ष करत आहे जेणेकरून मी नंतर INT मध्ये रूपांतरित करू शकेन आणि डेटावर गणित करू शकेन.

हा कोड यशस्वीरित्या (माझ्या I2C विश्लेषकानुसार) 16 बिट एडीसीवरील एका रजिस्टर पत्त्यावरून सलग 2 बाइट्स वाचतो.

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() ;
    }
}

त्यामुळे, परिणामी वाचन संकलित करण्यासाठी/संग्रहित करण्यासाठी मला अ‍ॅरे (अस्वाक्षरित चार अॅडकॅरे [२]) आवश्यक आहे, म्हणून मी प्रयत्न केला -

*buf++ = data ;

adcarray[] = data ;

adcarray[] = buf ;

'एक्स्प्रेशन अपेक्षित आहे' याचा अर्थ असा आहे की मला प्रत्येक पासवर अॅरे भरण्यासाठी काही फॉर्म फॉर लूपची आवश्यकता आहे, जरी *बफ लाइन आधीच काउंट 2 लूपमध्ये आहे.

मदतीची प्रशंसा केली (MSP430 आणि ADS1115 ADC वर IAR मध्ये C). विनम्र, राल्फ


c i2c
person Ralph    schedule 07.08.2019    source स्रोत
comment
adcarray किंवा Value म्हणजे काय - तुम्ही त्या व्हेरिएबल्ससाठी घोषणा सोडल्या आहेत.   -  person Chris Turner    schedule 07.08.2019
comment
हॅलो ख्रिस, adc वरील 16bit रजिस्टरमधून सलग वाचलेली 2 x 8 बिट मूल्ये मूल्य आहे. मला ते अॅरेमध्ये किंवा आदर्शपणे INT मध्ये ठेवणे आवश्यक आहे.   -  person Ralph    schedule 07.08.2019
comment
फंक्शन आधीपासून एक पॉइंटर आणि लांबीचे मूल्य घेते जेथे डेटा संग्रहित केला जाणार आहे. त्या फंक्शनला तुमच्या अॅरेच्या पत्त्यासह कॉल का करू नये?   -  person Gerhardh    schedule 07.08.2019
comment
कृपया नेहमी त्रुटी संदेशांबद्दल संपूर्ण माहिती द्या. नेमका मजकूर काय आहे आणि तो कोणत्या ओळीसाठी नोंदवला आहे? स्निपेट वरील कार्याचा भाग नाही. कृपया तुमच्या समस्येचे पुनरुत्पादन करण्यासाठी नेहमी पूर्ण सत्यापित करण्यायोग्य प्रोग्राम प्रदान करा.   -  person Gerhardh    schedule 07.08.2019
comment
तुम्ही यशस्वीरित्या डेटा वाचला की नाही हे तुम्ही कसे सत्यापित कराल? तुम्ही वाचलेल्या मूल्यांची I2C विश्लेषकाशी तुलना कुठे करता?   -  person Gerhardh    schedule 07.08.2019
comment
हॅलो गेर्हार्ड - मी adcdata[count] = डेटा जोडला आहे; *buf++ = डेटा नंतर लगेच; परंतु मला खात्री नाही की ते योग्यरित्या कार्य करत आहे, अॅरे रिक्त असल्याचे दिसते   -  person Ralph    schedule 07.08.2019
comment
माझ्याकडे ZeroPlus लॉजिक स्टेट अॅनालायझर आहे जे मला 2 बाइट्स योग्यरितीने वाचले जात असल्याचे दाखवते, मला फक्त ते साठवायचे आहेत   -  person Ralph    schedule 07.08.2019
comment
चला चॅटमध्ये ही चर्चा सुरू ठेवूया.   -  person Gerhardh    schedule 07.08.2019
comment
माफ करा, मी तुमच्याकडे परत येईन, मला I2C कोडच्या इतर प्रमुख समस्या आहेत   -  person Ralph    schedule 07.08.2019
comment
जर अॅरेमध्ये सर्व शून्य मूल्ये असतील तर तुमचे फंक्शन I2C_SDA_IS_HIGH() समस्या आहे असे दिसते. जर तुम्हाला हा डेटा इंटीजर व्हेरिएबलमध्ये ठेवायचा असेल, तर तुम्हाला नेटवर्क आणि होस्टचा बाइट क्रम पहायला आवडेल. (linux.die.net/man/3/ntohl)   -  person Sunil Shahu    schedule 07.08.2019
comment
हॅलो सुनील, लक्षात घ्या की I2C कोडमध्ये काहीही चूक नाही कारण माझे विश्लेषक 2 बाइट्स क्रमाने वाचले जात असल्याचे दाखवते आणि त्यात अपेक्षित मूल्ये आहेत. माझी समस्या ही आहे की मी ते 2 बाइट्स अॅरे किंवा इंटमध्ये कसे ठेवू जेणेकरून मी गणिते इ. (2 चा प्रशंसा क्रमांक) करू शकेन.   -  person Ralph    schedule 07.08.2019
comment
तुमचा कोड अजूनही अपूर्ण आहे. Value म्हणजे काय? त्यात 'I2CM_In. What's wrong with the content of Value` ने वाचलेले 2 बाइट असावेत? तुम्ही तुमच्या विश्लेषकात जे पाहता ते वेगळे आहे का?   -  person Gerhardh    schedule 07.08.2019
comment
होय, अगदी भिन्न, विश्लेषकामध्ये दर्शविलेली मूल्ये पहिल्या बाइटसाठी 3E आणि दुसऱ्यासाठी f) आहेत. मूल्याचे मूल्य (IAR नुसार) 'अज्ञात किंवा अस्पष्ट चिन्ह' आहे   -  person Ralph    schedule 07.08.2019
comment
मी आता 'सर्व कोड' दाखवले आहे पण त्यामुळे लोकांना गोंधळात टाकण्याची शक्यता आहे, समस्या अशी आहे की बाइट्स कसे सेव्ह करायचे ते मी अजूनही समजू शकत नाही जेणेकरून मी ते पूर्ण करू शकेन/स्केल करू शकेन इत्यादी. मला शंका आहे की मला काहीतरी सोपे आहे.   -  person Ralph    schedule 07.08.2019
comment
unsigned char Value; हे 2 बाइट्स कसे धरायचे?   -  person Gerhardh    schedule 07.08.2019
comment
I2C_Read_Register( ADC, 0x00 ) 2 बाइट्स परत करते (I2C विश्लेषकानुसार), त्यांना धरून ठेवणे ही समस्या आहे ज्यासाठी मी उपाय शोधत आहे.   -  person Ralph    schedule 07.08.2019
comment
2 बाइट्स संचयित / धरून ठेवण्यासाठी मला या *buf++ = डेटा नंतर काहीतरी जोडण्याची आवश्यकता आहे, परंतु मला काय माहित नाही (अ‍ॅरे, इंट्स इत्यादी कार्य करत नाहीत)   -  person Ralph    schedule 07.08.2019
comment
मूल्य हे TI च्या कथित I2C उदाहरण कोडचे फॉलबॅक आहे, हे माझ्यासाठी आश्चर्यकारक नाही की ते एकापेक्षा जास्त बाइटसह कार्य करत नाही.   -  person Ralph    schedule 07.08.2019
comment
समस्या अशी आहे की buf आहे Value च्या मागे वास्तविक व्हेरिएबल, जे फक्त मेमरीचे बाइट वाटप करते. मूल्य बहुधा अ‍ॅरे किंवा 16 बिट इंट असावे आणि I2C_Read_Register फंक्शनने 16 बिट इंट दिले पाहिजे. जर तुम्ही *buf++ = data ; वर ब्रेकपॉईंट हलवला, तर तुमचा विश्लेषक जे पाहतो तीच गोष्ट तुम्हाला दिसते का?   -  person yhyrcanus    schedule 07.08.2019
comment
धन्यवाद पण सोडवले, अगदी सोपे (गोंधळ असले तरी) जर काउंट = 0 किंवा जर काउंट = 1 असेल (लगेच *बुफ++ = डेटा नंतर) तर संबंधित बाइट वेगळ्या अक्षरात साठवा.   -  person Ralph    schedule 07.08.2019


उत्तरे (1)


जर तुम्ही I2CM_In फंक्शनसह डेटा दुसर्‍या अॅरेमध्ये साठवण्याचा प्रयत्न केला, तर तुम्ही तो चुकीचा वापरत आहात.

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 ;
    }
}

प्राप्त केलेला डेटा आधीपासूनच बफरमध्ये संग्रहित आहे: buf. परिणाम संचयित करण्यासाठी योग्य बफर प्रदान करणे हे तुमचे काम आहे.

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 ;
}

जर तुम्हाला 16 बिट असलेले रजिस्टर वाचायचे असेल, तर तुम्ही मूल्य unsigned char म्हणून परत करू शकत नाही. तुम्ही (किमान) 2 बाइट्स ठेवण्यास सक्षम असलेला डेटा प्रकार वापरला पाहिजे.

फंक्शनला सांगून की बफर 2 बाइट लांब आहे, तुम्ही देखील अपरिभाषित वर्तन घडवून आणता.

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

एंडियानेसवर अवलंबून तुम्हाला बाइट ऑर्डर स्विच करण्याची देखील आवश्यकता असू शकते:

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
धन्यवाद, मी प्रत्यक्षात वापरलेले (बऱ्यापैकी भयानक असले तरी) ते होते - जर (गणना == 0) { ADC_Value2 = डेटा ; } जर (गणना == 1) { ADC_Value1 = डेटा ; } - person Ralph; 07.08.2019
comment
अर्थात नंतर दोन स्वतंत्र वर्ण एका इंटमध्ये एकत्र करण्याचा प्रयत्न (गणिताच्या कामासाठी) कार्य करत नाही (स्टँडर्ड शिफ्ट प्रथम चार 8 बिट बाकी वापरून, दुसरा वर्ण इ. जोडा (आयएआर वर्कबेंचमध्ये) पण ती दुसरी गोष्ट आहे. - person Ralph; 07.08.2019
comment
शिफ्टिंग करण्यापूर्वी तुम्ही मूल्य int वर टाकण्याचा प्रयत्न करू शकता. - person Gerhardh; 07.08.2019