использование MPLAB MCC для настройки I2C и ADC

Я пытаюсь связаться с BQ24259 через I2C, используя PIC16LF1554. В 7-м регистре устройства есть бит, которым можно отключить батарею. Я использовал Mplab MCC для настройки параметров I2C. Используя пример кода в заголовочных файлах, я написал аналогичную функцию.

вот соответствующий фрагмент кода

    #define RETRY_MAX       100
    #define ON              0x4B   //register 7 toggle 5th bit to turn ON/OFF
    #define OFF             0x6B
    I2C_MESSAGE_STATUS status;

    uint16_t        timeOut;
    uint8_t         writeBuffer[1];                // writeBuffer[0] = 07, writeBuffer[1] = data 01001011b(on) 01101011b(off)
    uint8_t         stat;
    uint16_t        address = (0x6B/2) ;           //Bit shifting to the write, and having '0' for write opertaoin, at MSB

uint8_t bat_fet(uint8_t val){
    writeBuffer[0] = 7;                      //slave's seventh register
    writeBuffer[1] = val;
    timeOut=0;
    while(status != I2C_MESSAGE_FAIL){
        I2C_MasterWrite( writeBuffer,        // address of data to be sent
                         2,                  // number of data bytes
                         address,            // address of the peripheral
                         &status);           // address of status register

        while(status == I2C_MESSAGE_PENDING);

        if(status == I2C_MESSAGE_COMPLETE){
            return 1;
            break;
        }
        if(timeOut == RETRY_MAX){
            return 0;

            break; 
        }
        else
            timeOut++;
    }
    if(status == I2C_MESSAGE_FAIL)
        return 0;

}

но он не работает, ничего не происходит, иногда контроллер просто зависает, в основном продолжает работать. Я подключил светодиод к неиспользуемому выводу ввода-вывода и запрограммировал его на включение всякий раз, когда функция возвращает 1, и он включается. Но батарея тоже остается включенной.

Точно так же я пытаюсь использовать АЦП 1 на рис., чтобы проверить напряжение батареи,

вот код,

uint16_t check_bat_voltage(){

    uint16_t bat_v;

    ADC1_StartConversion(01011); //i am using Channel AN11, but no matter what variation of channel and AN11 i passed, it just wouldn't recognize. so i just pass the 5 bit values of the ADCON1 register.

    while(ADC1_IsConversionDone());

    bat_v = ADC1_GetConversionResult();  

//digital value = [analog voltage / (vref+ - vref-)] * 1024 
 //analog value minimum = 2.5/2, voltage divider network
 //vref+ 5
 //vref- 0
 // 1.25/5 * 1024 = 256
    return bat_v;
}

но опять ничего не происходит. Может ли кто-нибудь просмотреть его? Я просто застрял. Спасибо.

Скриншоты MCC тоже могу приложить, может я не правильно настроил периферию.

P.S. я инициализирую оба модуля в main().


person aamir    schedule 23.10.2017    source источник
comment
adc работает, я неправильно рассчитывал значения. Виноват.   -  person aamir    schedule 24.10.2017
comment
Вы уверены, что вам нужен адрес с последним битом для чтения/записи? Или mcc автоматически изменит его, если вы будете использовать чтение или запись?   -  person DmO    schedule 28.03.2018


Ответы (2)


Я считаю, что ваша проблема в том, что вы забыли инициализировать status чем-то другим, кроме I2C_MESSAGE_FAIL перед циклом (я предполагаю, что ваш глобальный stat является опечаткой - это должно быть status).

Если переменные не объявлены постоянными с помощью __attribute__((persistent)) (компилятор XC16 - не уверен насчет XC8), код запуска инициализирует все глобальные переменные нулем. Поскольку я предполагаю, что константа I2C_MESSAGE_FAIL не равна нулю, это означает, что ваш цикл никогда не выполняется.

Компилятор, скорее всего, предупредил вас об использовании переменной до ее инициализации.

Вместо этого попробуйте использовать цикл do {} while.

person EBlake    schedule 24.10.2017
comment
Я не изобретателен, когда дело доходит до именования переменных; статус и статистика - разные переменные. я инициализировал статус I2C_MESSAGE_PENDING, но снова ничего не происходит. - person aamir; 24.10.2017
comment
А, я вижу объявление для statusnow. Теперь, когда об инициализации позаботились, возможно, проблема заключается в конфигурации порта I2C. Я не знаком с этим конкретным MPU. Есть ли у него более одного периферийного устройства I2C? Использует ли он PPC (программируемая конфигурация порта)? ИМХО, полезно не использовать стандартные подпрограммы, потому что усилия по написанию необработанных операций чтения/записи порта приводят к лучшему пониманию оборудования. - person EBlake; 25.10.2017

может быть, это опечатка в ваших декларациях? попробуйте изменить:

uint8_t    writeBuffer[1];

to

uint8_t    writeBuffer[2];

Рекомендую просмотреть строки scl и sda и проверить, что на самом деле отправляется при включении светодиода.

person Ron    schedule 01.02.2018