Jump to content

PIC I2C неподвижно на 5в


Ilya Gray
 Share

Recommended Posts

Доброго времени суток!

В целом, имеется опыт разработки малых устройств, что-то понимаю, в общем, старательно читаю даташиты, даже понимаю их, но на звание серьёзного инженера (пока что) не претендую.

Я пытаюсь использовать I2C на 8-битном PIC16F18326. Сижу в даташитах. Всё понимаю, всё делаю, на мой неопытный взгляд, правильно. Даже копирую полностью рабочие примеры (я даже купил такой же микроконтроллер, как в примере, скопировал код, контролируя, что он делает. Но всё равно не работает - SCL/SDA на 5в и всё тут).

Так вот: PIC16F18326 on breadboard (прошу прощения, я хз как это по-русски) на внутреннем 32мгц кристалле. Чип пашет, без проблем моргаю LEDкой. Ну, думаю, щас быстренько подниму I2C. В итоге SCL SDA сидят на 5в без движения. Я использую LED для отладки. Судя по LED, код заloopливается в месте, где проверяется while PIR1bits.SSP1IF==0. Я уже везде был, кучу форумов перерыл. Уже попробовал всё, что мог представить. Я довольно новый в мире PIC, хотел попробовать их, а они ужасно сопротивляются. Уже 2 недели долблюсь безуспешно.

Подтяжки 10к, проблем с ними никогда не было.

Собственно, вот код (я уже там попробовал повыключать ADC, вычитал про баг, что сначала I2C пины надо делать OUTPUT LOW, а потом уже INPUT из-за бага MSSP, но ничего не помогло).


// PIC16F18326 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FEXTOSC = OFF    // FEXTOSC External Oscillator mode Selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with 2x PLL (32MHz))
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2)
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config WDTE = OFF       // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored)
#pragma config LPBOREN = OFF    // Low-power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bits (Brown-out Reset enabled, SBOREN bit ignored)
#pragma config BORV = LOW       // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V)
#pragma config PPS1WAY = ON     // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a Reset)
#pragma config DEBUG = OFF      // Debugger enable bit (Background debugger disabled)

// CONFIG3
#pragma config WRT = OFF        // User NVM self-write protection bits (Write protection off)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored.)

// CONFIG4
#pragma config CP = OFF         // User NVM Program Memory Code Protection bit (User NVM code protection disabled)
#pragma config CPD = OFF        // Data NVM Memory Code Protection bit (Data NVM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <htc.h>
#include <stdio.h>
#include <stdint.h>
#define _XTAL_FREQ 32000000
void i2c_is_idle(void){
    //while(!PIR1bits.SSP1IF);
    //while(SSPCON2bits.SEN==1 || SSPCON2bits.RSEN==1 || SSPCON2bits.PEN==1 || SSPCON2bits.RCEN==1 || SSPCON2bits.ACKEN==1 || SSPSTATbits.R_nW==1){};
    while(PIR1bits.SSP1IF == 0){
    PORTCbits.RC2=1;

    }; // SSP1IF is set when operation complete
    PORTCbits.RC2=0;
    PIR1bits.SSP1IF = 0;    // clear interrupt flag
    
}

void i2c_start(void){
    i2c_is_idle();
    SSPCON2bits.SEN = 1;
}

void i2c_rep_start(void){
    i2c_is_idle();
    SSPCON2bits.RSEN = 1;
}

void i2c_stop(void){
    i2c_is_idle();
    SSPCON2bits.PEN = 1;
}

void i2c_write(uint8_t i2c_data){
    i2c_is_idle();
    SSPBUF = i2c_data;
    while(SSPSTATbits.BF != 0);
    while(SSPCON2bits.ACKSTAT != 0);
}

uint8_t i2c_read(uint8_t ack){
    uint8_t recieve =0;
    i2c_is_idle();
    SSPCON2bits.RCEN = 1;
    while(SSPSTATbits.BF != 1);
    recieve = SSPBUF;
    SSPCON2bits.ACKEN = ack;
    return recieve;
}

void i2c_init(void){
    TRISCbits.TRISC0 = 1;
    TRISCbits.TRISC1 = 1;
    
    
    SSPSTATbits.SMP = 1;
    SSPSTATbits.CKE = 0;
    SSPCONbits.SSPM = 0x08;
    SSPADD = 79;
    SSPCONbits.SSPEN = 1;
    
}


void main(void) {    
    ANSELCbits.ANSC0 = 0; //ADC RC0 OFF
    ANSELCbits.ANSC1 = 0; //ADC RC1 OFF
    TRISCbits.TRISC2=0; //LED PIN
    TRISCbits.TRISC0=0; //MSSP bug counter
    TRISCbits.TRISC1=0; //MSSP bug counter
    //__delay_ms(5);
    LATCbits.LATC1=0; //MSSP bug counter
    LATCbits.LATC0=0; //MSSP bug counter

    //__delay_ms(5);
    INTCONbits.GIE=1; //global interrupt en
    INTCONbits.PEIE=1; //peripheral interrupt en
    ADCON0bits.ADON=0; //unpower adc just in case
    i2c_init(); //THIS SETS TRISC BITS FOR SCL SDA
    while(1){

        i2c_start();
        i2c_write(0x3C);
        i2c_stop();
    }
    return;
}

Задача: просто увидеть коммуникацию на SCL SDA, я уже потом по даташитам таргет девайсов без проблем напишу дрова. Не получается именно осуществлять коммуникацию.

Подскажите, пожалуйста, я не понимаю, где я дурак, а между тем волос на голове становится всё меньше, а те, что остались, стремительно приобретают серый окрас, ибо 2 недели я долбаюсь с одной проблемой. Благодарю за ваши советы. Спасибо.

 

Link to comment
Share on other sites

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

3 hours ago, Ilya Gray said:

коммуникацию на SCL SDA

По умолчанию, после ресета, все цифровые выходы подключены к регистру output latch, а не к периферии. То есть можно устанавливать единички-нолики в порту, а модуль I2C при этом отключён от ног.

Для поключения RC0, RC1 к выходу I2C модуля надо настроить PPS, добавив в функцию void i2c_init(void)

RC0PPSbits.RC0PPS = 0x19; //RC0->SDA1   0b11001: SDA output подключаем к RC0  
RC1PPSbits.RC1PPS = 0x18; //RC1->SCL1   0b11000: SCL output подключаем к RC1

 

Link to comment
Share on other sites

15 часов назад, Yurkin2015 сказал:

//////////////////////////

Благодарю за совет. Изучил регистр, добавил эти команды, буду иметь в виду, что такие регистры есть. Полезное знание.

К сожалению, оно встаёт на i2c_wait, так и сидит в while, осциллограф показывает прямую линию без признаков жизни :(

 

void i2c_init(void){
    TRISCbits.TRISC0 = 1;
    TRISCbits.TRISC1 = 1;
    
    RC0PPSbits.RC0PPS = 0x19; //RC0->SDA1   0b11001: SDA output подключаем к RC0  
    RC1PPSbits.RC1PPS = 0x18; //RC1->SCL1   0b11000: SCL output подключаем к RC1
     
    SSPSTATbits.SMP = 1;
    SSPSTATbits.CKE = 0;
    SSPCONbits.SSPM = 0x08;
    SSPADD = 79;
    SSPCONbits.SSPEN = 1;
   
}

Пробовал до трусов вставить эти строчки, ничего не меняется. Меня всё же напрягает, что в примерах на 95% этот же код работает, а у меня нет. Не понимаю, что я делаю не так

Edited by Falconist
Link to comment
Share on other sites

  • 2 months later...

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Как измерить внутреннее сопротивление литиевого аккумулятора. Измеряем правильно

Внутреннее сопротивление – один из наиболее значимых параметров, от которого напрямую зависят другие характеристики литиевого аккумулятора. От этого параметра зависят такие характеристики источника питания, как напряжение на выходе под нагрузкой, максимальный выходной ток и коэффициент полезного действия (КПД). Рассмотрим как измерить действительное значение внутреннего сопротивления АКБ, используя определенные методики. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...