Jump to content
Ilya Gray

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

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 недели я долбаюсь с одной проблемой. Благодарю за ваши советы. Спасибо.

 

Share this post


Link to post
Share on other sites
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

 

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

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

Share this post


Link to post
Share on other sites

Материалы вебинара Параметры выше, цена ниже. Обновление в линейке AC/DC- и DC/DC-преобразователей MORNSUN

Опубликованы запись, ответы на вопросы и материалы вебинара, посвящённого преимуществам и отличиям новых источников питания и DC/DC-преобразователей Mornsun. На вебинаре были рассмотрены изолированные и неизолированные DC/DC-преобразователи последнего, четвертого, поколения (R4) и компактные модульные источники питания второго и третьего поколений (семейства LS/R3 и LD/R2) на плату, также новая группа продукции – встраиваемые источники питания в кожухе.

Подробнее

08.06.2020 в 17:05, Ilya Gray сказал:

PIR1bits.SSP1IF

надо принудительно сбрасывать в 0.

Share this post


Link to post
Share on other sites

Запускаем новый BLE 5.2-чип BlueNRG-LP от STMicroelectronics

Любая разработка начинается с чтения документации и изучения доступных средств разработки. Данный материал целиком посвящен средствам разработки, включая детальные инструкции по запуску вашего первого приложения на BlueNRG-LP. Описана работа с отладкой STEVAL-IDB011V1, набором инструментов и пакетом ПО позволяющим разработчику быстро войти в курс дела.

Подробнее

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
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...

  • Сообщения

  • Similar Content

    • By LiSiY5
      Работаю в Mplab X 5.40, написал основной код программы для Pic16 на Си и есть небольшой код на ассемблере. Так вот, подскажите как правильно сделать переход на подпрограмму с Си на ассемблер и назад. Может на каком либо примере где-то есть. Заранее всем спасибо.
    • By LiSiY5
      Ребята помогите, Я начинаю изучение Pic и не могу создать первую прогу. Сам программирую на LD, FBD, ASM, но тут не могу стартонуть, с выходами все получается, а вот с входами проблемка. Есть код на Си, подскажите в чем ошибка. Буду очень благодарен любой информации.

      // PIC16F18877 Configuration Bit Settings
      // 'C' source line config statements
      // CONFIG1
      #pragma config FEXTOSC = HS     // External Oscillator mode selection bits (HS (crystal oscillator) above 4MHz; PFM set to high power)
      #pragma config RSTOSC = EXT1X   // Power-up default value for COSC bits (EXTOSC operating per FEXTOSC bits)
      #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 bit (FSCM timer enabled)
      // CONFIG2
      #pragma config MCLRE = ON       // Master Clear Enable bit (MCLR pin is Master Clear function)
      #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
      #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 is ignored)
      #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
      #pragma config ZCD = OFF        // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
      #pragma config PPS1WAY = ON     // Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
      #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
      // CONFIG3
      #pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
      #pragma config WDTE = ON        // WDT operating mode (WDT enabled regardless of sleep; SWDTEN ignored)
      #pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
      #pragma config WDTCCS = SC      // WDT input clock selector (Software Control)
      // CONFIG4
      #pragma config WRT = OFF        // UserNVM self-write protection bits (Write protection off)
      #pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
      #pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
      // CONFIG5
      #pragma config CP = OFF         // UserNVM Program memory code protection bit (Program Memory code protection disabled)
      #pragma config CPD = OFF        // DataNVM code protection bit (Data EEPROM code protection disabled)
      // #pragma config statements should precede project file includes.
      // Use project enums instead of #define for ON and OFF.
      #include <xc.h>
      #define _XTAL_FREQ 20000000

      void main(void) {
          TRISB=0;
          PORTB=0;
          TRISA=11111111;
          PORTA=11111111;
          TRISA=11111111;
          if(PORTAbits.RA0 == 1) { RB0 = 1;}
          return;
      }
       
    • By Стальной
      Приветствую. Не получается запустить I2C на STM32F030F4P6 для общения с EEPROM. Использую StdPeriph. Сначала пробовал сам писать, потом взял код отсюда. Результат одинаков: На линиях активности нет, висит 3В. Через CubeMX все работает.
      Последний код, который я пробовал:
      void I2C_EEPROM_Init(void) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); GPIOA->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1; // Режим альтернативной функции GPIOA->OTYPER |= GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10; // Открытый коллектор GPIOA->OSPEEDR |= 0xFF<<18; // Максимальная скорость // Выбор альтернативной функции GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); // I2C1_SCL GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); // I2C1_SDA I2C_InitTypeDef I2C_InitStruct; I2C_InitStruct.I2C_Timing = 0x00402D42; I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Disable; I2C_InitStruct.I2C_DigitalFilter = 0x00; I2C_InitStruct.I2C_Mode = I2C_Mode_I2C ; I2C_InitStruct.I2C_OwnAddress1 = 0xDD; I2C_Init( I2C1, &I2C_InitStruct); I2C_Cmd(I2C1, ENABLE); } int main() { /* * ВКЛЮЧЕНИМЕ IWDG */ // включаем LSI RCC_LSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // разрешается доступ к регистрам IWDG IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // устанавливаем предделитель IWDG_SetPrescaler(IWDG_Prescaler_256); // значение для перезагрузки IWDG_SetReload(0xEA); // перезагрузим значение IWDG_ReloadCounter(); // LSI должен быть включен //IWDG_Enable(); /* * ВКЛЮЧЕНИМЕ IWDG ЗАВЕРШЕНО */ /* * Запуск ФАПЧ * Основная частота 48 МГц * UART от HSI */ RCC->CFGR |= 0xAA<<18; //pll mul = 12 RCC->CFGR |= 5<<8; //APB prescaller = 4 RCC->CFGR3 |= 3; //USART clock from HSI RCC->CR |= RCC_CR_PLLON; while ((RCC->CR | RCC_CR_PLLRDY) == 0); RCC->CFGR |= 2; //PLL as SYSCLK /* * Настройка ФАПЧ завершена */ //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // I2C_Initialization(); I2C_EEPROM_Init(); while (1) { I2C_TransferHandling(I2C1, 0xA0, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);//devAddr while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXE) == RESET);//TXDR empty I2C_SendData(I2C1, 0);//memAddr while(I2C_GetFlagStatus(I2C1, I2C_ISR_TCR) == RESET);//transmition complete I2C_TransferHandling(I2C1, 0xA0, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXE) == RESET); I2C_SendData(I2C1, 25); while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); for (long int i = 0; i < 30000; i++) IWDG_ReloadCounter(); } }  
      Прошу помощи с этой проблемой. Спасибо.
    • By Kovalinski
      Добрый день! Прошу помощи в реализации интерфейса TWI на XMEGA. Набросал код для двух микроконтроллеров.  Но на выходе SDA и SCL вообще ничего не происходит. Привожу пример для мастера. 
      #define F_CPU 2000000UL #define CPU_SPEED 2000000 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> uint8_t slave_address=6, write=0; uint8_t data=0x01; void TWI_init(void) {     TWIC.CTRL=0;     TWIC.MASTER.BAUD=0x05;     TWIC.MASTER.CTRLA=TWI_MASTER_INTLVL_HI_gc|TWI_MASTER_ENABLE_bm|TWI_MASTER_WIEN_bm;     TWIC.MASTER.CTRLB=0;     TWIC.MASTER.CTRLC=0;     TWIC.MASTER.STATUS=TWI_MASTER_BUSSTATE_IDLE_gc; } void TWI_write_date(uint8_t data) {     //TWIC.MASTER.CTRLC=TWI_MASTER_CMD_REPSTART_gc;     TWIC.MASTER.ADDR=slave_address|write;     while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm));     TWIC.MASTER.DATA=data;     while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm));     TWIC.MASTER.DATA=data;     while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm));     TWIC.MASTER.CTRLC=TWI_MASTER_ACKACT_bm|TWI_MASTER_CMD_STOP_gc;     TWIC.MASTER.CTRLC=0; } int main(void) {     CPU_SREG|=(1<<CPU_I_bp);     TWI_init();     while(1)     {         TWI_write_date(data);     } }  
    • By Николай кол
      Привет, у меня есть вопрос, как передать данных с микроконтроллера pic через блютуз модуль HC-05 на телефон в виде графика.Не могли бы вы показать скрипт или статю.Про Arduino много а про pic не (нужно передать данные с микроконтроллера на телефон а не на оборот).У же есть приложение на app inventor 2.Нужно примерно как тут https://www.youtube.com/watch?v=WzoCQ2fRsRQ
×
×
  • Create New...