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

Оценка точности измерения тока интеллектуальными силовыми ключами PROFET

Интеллектуальные силовые ключи PFOFET производства Infineon могут измерять ток нагрузки с разной точностью, зависящей как от абсолютной величины потребляемого тока, так и от технологии производства конечной продукции, в частности – от наличия или отсутствия этапа калибровки. В статье подробно разбирается расчет коэффициента передачи тока на примере ключа BTS7004-1EPP.
Подробнее

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

PIR1bits.SSP1IF

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

Share this post


Link to post
Share on other sites

STMicroelectronics: электростатический разряд больше не проблема

Защита от статического электричества необходима каждому современному устройству. Компания STMicroelectronics представляет решения, соответствующие стандарту IEC61000-4-2, а также специальное приложение PROTECTION FINDER, которое поможет легкого и эффективно подобрать необходимые компоненты. Рассмотрим практические примеры защиты от ESD, отраслевые стандарты и ряд ключевых параметров важных при проектировании электростатической защиты устройств.

Подробнее

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

  • Сообщения

    • В Америке вот закончились профессиональные космонавты. А ракету новую надо испытать. Обезьянам не доверяют. Наловили на улице несколько бродяг. Нарядили их в дез.комплекты с резиновыми сапогами и посадили в аппарат. На всякий случай крышку закрутили на болты снаружи, чтоб не сбежали. Бабахнули и полетели. А у нас тоже решили испытать новую ракету. Посмотрели, а там в небе уже летит чего то. Это же цель!  Бабахнули и полетели. С красивым чёрным дымом сзади и приятным звуком "У-у-у-у-х! Но американе подкинули в топку пару лишних лопат угля и оторвались. А наша ракета,пожав плечами  повернулась к ним хвостом и полетела поразить чего нибудь ещё.   
    • Большое спасибо, нашел еще парочку вариантов.
    • Вольтдобавка. Без неё положительная волна ограничивается чуть раньше.  Работает, но мощности будет не много совсем.   
    • Здравствуйте. Есть где посмотреть печатную плату на это устройство? Можете выложить сюда?
    • Да и я тоже делал раньше по приколу стабилизатор оборотов с усилителем ошибки на операционнике, с отдельным усилителем прохождения фазы нуля, гун с имульсным трансформатором на выходе итд. Еще игрался с готовыми фазовыми регуляторами 1182пм1 и PR-1500. результат примерно одинаковый. Стабилизатор для мотора от стиралки собрал на одной полуволне с использованием КТ117 и тахогенераторм из 9В моторчика. Обороты большие не нужны, поэтому хватает половинки.  Схему выкладывал раньше, совсем простая, проще точно не бывает. И без реверса. Потому, что стоит на токарном станке в приводе ускоренных подач, там реверс механический, джойстиком. 
    • Про возбуд при повышении тока покоя.  Изначальная схема может работать даже без коррекции, но лучше ненадо.) Все разговоры про невозможность улучшить- в пользу бедных. Берём и улучшаем. Вот схемка получившаяся: вот такой меандр: вот такенный клип: И вот такущие гармоники: Цели задрать петлевое усиление особой небыло, так, разминка для ума. модель : ALC_MKII.asc Всем спасибо  за внимание. 
  • Similar Content

    • By демидос
      имеем: ардуино нано дисплей 1602 с i2c переходником блок релюшек 4 кнопки. все работало около часа при различних кнопкотыканиях. и на испытании произошла непонятная програмная ошибка: сначала вылезли случайные символы потом потухла подсветка, хотя как понял она управляется перемычкой. при дальнейшем перезапуске на выходах висит 0 и нет никакой реакции на нажатия. убрал из программы дисплей и она заработала. пробовал переустановить библиотеки liquid cristal i2c но не помогло. пробовал отключать дисплей. даже инвертированные выходы лежат в 0. код прилагаю
      #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C _lcd1(0x27, 16, 2); int _dispTempLength1=0; boolean _isNeedClearDisp1; const byte _menuParametrsArray[] PROGMEM = {1, 3, 2, 0, 0, 0, 5, 6, 1, 8, 3, 0, 2, 3, 1, 0, 0, 0, 5, 6, 1, 8, 1, 0, 3, 4, 1, 0, 0, 0, 2, 3, 1, 4, 2, 0, 4, 3, 3, 0, 0, 0, 5, 6, 1, 8, 4, 0}; bool _menuValueArray_bool[3]; const bool _menuConstantValuesArray_bool[] PROGMEM = {1, 0}; int _menuValueArray_int[1]; const int _menuConstantValuesArray_int[] PROGMEM = {3, 15, -3}; const char _flprogMenuNameString1[] PROGMEM = "dislink"; const char _flprogMenuNameString2[] PROGMEM = "attenuator"; const char _flprogMenuNameString3[] PROGMEM = "cross line"; const char _flprogMenuNameString4[] PROGMEM = "noise generaror"; const char _flprogMenuNameString5[] PROGMEM = "ON"; const char _flprogMenuNameString6[] PROGMEM = "OFF"; const char* const _flprogMenuStringsArray[] PROGMEM = { _flprogMenuNameString1, _flprogMenuNameString2, _flprogMenuNameString3, _flprogMenuNameString4, _flprogMenuNameString5, _flprogMenuNameString6}; struct _menuItemStricture { int startInArrayIndex; } ; struct _menuMainStricture { byte startIndex; byte stopIndex; bool isSwitchMenuAroundRing; _menuItemStricture currentItem; } ; _menuItemStricture _MenuItems[4]; _menuMainStricture _MainMenus[1]; String _MenuBlock_41244328_MNO; String _MenuBlock_41244328_VNO; bool _MenuBlock_41244328_OEIS = 0; bool _MenuBlock_41244328_OMUIS = 0; bool _MenuBlock_41244328_OMDIS = 0; bool _MenuBlock_41244328_OVUIS = 0; bool _MenuBlock_41244328_OVDIS = 0; bool _bounseInputD0S = 0; bool _bounseInputD0O = 0; unsigned long _bounseInputD0P = 0UL; int _disp2oldLength = 0; bool _bounseInputD2S = 0; bool _bounseInputD2O = 0; unsigned long _bounseInputD2P = 0UL; int _disp1oldLength = 0; bool _bounseInputD1S = 0; bool _bounseInputD1O = 0; unsigned long _bounseInputD1P = 0UL; bool _bounseInputD3S = 0; bool _bounseInputD3O = 0; unsigned long _bounseInputD3P = 0UL; bool _tempVariable_bool; byte _tempVariable_byte; void setup() { pinMode(0, INPUT_PULLUP); pinMode(1, INPUT_PULLUP); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, OUTPUT); digitalWrite(4, 0); pinMode(5, OUTPUT); digitalWrite(5, 0); pinMode(6, OUTPUT); digitalWrite(6, 0); pinMode(7, OUTPUT); digitalWrite(7, 0); pinMode(8, OUTPUT); digitalWrite(8, 0); pinMode(9, OUTPUT); digitalWrite(9, 0); pinMode(10, OUTPUT); digitalWrite(10, 0); pinMode(11, OUTPUT); digitalWrite(11, 0); pinMode(12, OUTPUT); digitalWrite(12, 0); pinMode(13, OUTPUT); digitalWrite(13, 0); Wire.begin(); delay(10); _lcd1.init(); _lcd1.backlight(); _bounseInputD0O = digitalRead(0); _bounseInputD3O = digitalRead(3); _bounseInputD1O = digitalRead(1); _bounseInputD2O = digitalRead(2); _MenuItems[0].startInArrayIndex = 0; _MenuItems[1].startInArrayIndex = 12; _MenuItems[2].startInArrayIndex = 24; _MenuItems[3].startInArrayIndex = 36; _MainMenus[0].startIndex = 1; _MainMenus[0].isSwitchMenuAroundRing = 1; _MainMenus[0].stopIndex = 4; _MainMenus[0].currentItem = _MenuItems[0]; } void loop() { if (_isNeedClearDisp1) { _lcd1.clear(); _isNeedClearDisp1= 0; } bool _bounceInputTmpD0 = (digitalRead (0)); if (_bounseInputD0S) { if (millis() >= (_bounseInputD0P + 40)) { _bounseInputD0O= _bounceInputTmpD0; _bounseInputD0S=0; } } else { if (_bounceInputTmpD0 != _bounseInputD0O) { _bounseInputD0S=1; _bounseInputD0P = millis(); } } bool _bounceInputTmpD3 = (digitalRead (3)); if (_bounseInputD3S) { if (millis() >= (_bounseInputD3P + 40)) { _bounseInputD3O= _bounceInputTmpD3; _bounseInputD3S=0; } } else { if (_bounceInputTmpD3 != _bounseInputD3O) { _bounseInputD3S=1; _bounseInputD3P = millis(); } } bool _bounceInputTmpD1 = (digitalRead (1)); if (_bounseInputD1S) { if (millis() >= (_bounseInputD1P + 40)) { _bounseInputD1O= _bounceInputTmpD1; _bounseInputD1S=0; } } else { if (_bounceInputTmpD1 != _bounseInputD1O) { _bounseInputD1S=1; _bounseInputD1P = millis(); } } bool _bounceInputTmpD2 = (digitalRead (2)); if (_bounseInputD2S) { if (millis() >= (_bounseInputD2P + 40)) { _bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0; } } else { if (_bounceInputTmpD2 != _bounseInputD2O) { _bounseInputD2S=1; _bounseInputD2P = millis(); } } //Плата:1 digitalWrite(4, (_menuValueArray_bool[1])); digitalWrite(5, !((_menuValueArray_bool[0]))); digitalWrite(13, ((((_bounseInputD0O) || (_bounseInputD1O))) || (((_bounseInputD3O) || (_bounseInputD2O))))); if (1) { _tempVariable_bool = 1; if (! _MenuBlock_41244328_OEIS) { _MenuBlock_41244328_OEIS = 1; } _tempVariable_byte = pgm_read_byte(&_menuParametrsArray[((_MainMenus[0].currentItem).startInArrayIndex)+10]); _MenuBlock_41244328_MNO = _readStringFromProgmem ((char*)pgm_read_word(&(_flprogMenuStringsArray[_tempVariable_byte - 1]))); _MenuBlock_41244328_VNO = _menuOutputValueString (0); } else { _tempVariable_bool = 0; if (_MenuBlock_41244328_OEIS) { _MenuBlock_41244328_OEIS = 0; } _MenuBlock_41244328_MNO = ""; _MenuBlock_41244328_VNO = ""; } if(_bounseInputD0O) { if (! _MenuBlock_41244328_OMUIS) { _MenuBlock_41244328_OMUIS = 1; if(_tempVariable_bool) { _menuUpEvents(0); } } } else { _MenuBlock_41244328_OMUIS = 0; } if(_bounseInputD1O) { if (! _MenuBlock_41244328_OMDIS) { _MenuBlock_41244328_OMDIS = 1; if(_tempVariable_bool) { _menuDownEvents(0); } } } else { _MenuBlock_41244328_OMDIS = 0; } if(_bounseInputD3O) { if (! _MenuBlock_41244328_OVUIS) { _MenuBlock_41244328_OVUIS = 1; if(_tempVariable_bool) { _valueUpEvents(0); } } } else { _MenuBlock_41244328_OVUIS = 0; } if(_bounseInputD2O) { if (! _MenuBlock_41244328_OVDIS) { _MenuBlock_41244328_OVDIS = 1; if(_tempVariable_bool) { _valueDownEvents(0); } } } else { _MenuBlock_41244328_OVDIS = 0; } if (1) { _dispTempLength1 = ((_MenuBlock_41244328_VNO)).length(); if (_disp2oldLength > _dispTempLength1) { _isNeedClearDisp1 = 1; } _disp2oldLength = _dispTempLength1; _lcd1.setCursor(0, 1); _lcd1.print((_MenuBlock_41244328_VNO)); } else { if (_disp2oldLength > 0) { _isNeedClearDisp1 = 1; _disp2oldLength = 0; } } if (1) { _dispTempLength1 = ((_MenuBlock_41244328_MNO)).length(); if (_disp1oldLength > _dispTempLength1) { _isNeedClearDisp1 = 1; } _disp1oldLength = _dispTempLength1; _lcd1.setCursor(0, 0); _lcd1.print((_MenuBlock_41244328_MNO)); } else { if (_disp1oldLength > 0) { _isNeedClearDisp1 = 1; _disp1oldLength = 0; } } digitalWrite(6, !((_menuValueArray_bool[2]))); digitalWrite(7, !(((String("0")).equals((String(0, DEC)))))); digitalWrite(8, !(((String("3")).equals((String(0, DEC)))))); digitalWrite(9, !(((String("6")).equals((String(0, DEC)))))); digitalWrite(10, !(((String("9")).equals((String(0, DEC)))))); digitalWrite(11, !(((String("12")).equals((String(0, DEC)))))); digitalWrite(12, !(((String("-3")).equals((String(0, DEC)))))); } String _readStringFromProgmem (char *string) { String result = String(""); while (pgm_read_byte(string)!='\0') { result=result+ char(pgm_read_byte(string)); string++; } return result; } void _menuUpEvents (byte menuIndex) { byte tempIndex = pgm_read_byte(&_menuParametrsArray[((_MainMenus[menuIndex]).currentItem).startInArrayIndex]); byte parIndex = pgm_read_byte(&_menuParametrsArray[ (((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+5]); byte parentStartIndex; byte parentStopIndex; if (parIndex == 0) { parentStartIndex = (_MainMenus[menuIndex]).startIndex; parentStopIndex =(_MainMenus[menuIndex]).stopIndex; } else { parentStartIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex - 1]).startInArrayIndex)+3]); parentStopIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+4]); } if (tempIndex == parentStartIndex) { if((_MainMenus[menuIndex]).isSwitchMenuAroundRing) { (_MainMenus[menuIndex]).currentItem = _MenuItems[parentStopIndex -1]; return; } else { return; } } (_MainMenus[menuIndex]).currentItem = _MenuItems[tempIndex - 2]; return; } void _menuDownEvents (byte menuIndex) { byte tempIndex = pgm_read_byte(&_menuParametrsArray[((_MainMenus[menuIndex]).currentItem).startInArrayIndex]); byte parIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+5]); byte parentStartIndex; byte parentStopIndex; if (parIndex == 0) { parentStartIndex = (_MainMenus[menuIndex]).startIndex; parentStopIndex =(_MainMenus[menuIndex]).stopIndex; } else { parentStartIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+3]); parentStopIndex = pgm_read_byte(&_menuParametrsArray[((_MenuItems[parIndex-1]).startInArrayIndex)+4]); } if (tempIndex == parentStopIndex) { if((_MainMenus[menuIndex]).isSwitchMenuAroundRing) { (_MainMenus[menuIndex]).currentItem = _MenuItems[parentStartIndex -1]; return; } else { return; } } (_MainMenus[menuIndex]).currentItem = _MenuItems[tempIndex]; return; } void _valueUpEvents (byte menuIndex) { byte valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]); byte itemType = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]); byte indexMax = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+6]); byte indexStep = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+8]); if(itemType ==3) { _menuValueArray_bool[valIndex - 1 ] = 1; return; } if (itemType == 4) { if (! indexMax == 0) { if (! (int(pgm_read_word(&_menuConstantValuesArray_int[indexMax -1])) > int(_menuValueArray_int[valIndex -1]))) { return; } } _menuValueArray_int[valIndex -1] = _menuValueArray_int[valIndex -1] + (pgm_read_word(&_menuConstantValuesArray_int[indexStep -1])); } } void _valueDownEvents (byte menuIndex) { byte valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]); byte itemType = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]); byte indexMin = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+7]); byte indexStep = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+8]); if(itemType ==3) { _menuValueArray_bool[valIndex -1] = 0; return; } if (itemType == 4) { if (! indexMin == 0) { if (! ((int(pgm_read_word(&_menuConstantValuesArray_int[indexMin - 1]))) < int(_menuValueArray_int[valIndex - 1]))) { return; } } _menuValueArray_int[valIndex - 1] = _menuValueArray_int[valIndex - 1] - (pgm_read_word(&_menuConstantValuesArray_int[indexStep - 1])); } } String _menuOutputValueString (byte menuIndex) { byte itemType = pgm_read_byte(&_menuParametrsArray[ (((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+1]); byte valIndex = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+2]); byte indexMin = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+7]); byte indexMax = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+6]); if(valIndex == 0) { return ""; } byte convFormat = pgm_read_byte(&_menuParametrsArray[(((_MainMenus[menuIndex]).currentItem).startInArrayIndex)+9]); if(itemType == 3) { return _convertBoolean(itemType, convFormat, valIndex, indexMax, indexMin); } if(itemType == 4) { return _convertNamber(itemType, convFormat, valIndex, indexMax, indexMin); } return ""; } String _convertNamber(byte itemType, byte convFormat, byte valIndex, byte indexMax, byte indexMin) { if (itemType== 4) { if (convFormat == 4) { return String((_menuValueArray_int[valIndex - 1 ]),DEC); } if (convFormat == 5) { return String((_menuValueArray_int[valIndex - 1]),HEX); } if (convFormat == 6) { return String((_menuValueArray_int[valIndex -1]),BIN); } } } String _convertBoolean(byte itemType, byte convFormat, byte valIndex, byte indexMax, byte indexMin) { if (convFormat == 1) { if(_menuValueArray_bool[valIndex -1]) { return "1"; } else { return "0"; } } if (convFormat == 2) { if(_menuValueArray_bool[valIndex -1]) { return "True"; } else { return "False"; } } if (convFormat == 3) { if(_menuValueArray_bool[valIndex -1 ]) { return "Да"; } else { return "Нет"; } } if(_menuValueArray_bool[valIndex -1]) { return _readStringFromProgmem ((char*)pgm_read_word(&(_flprogMenuStringsArray[indexMax - 1]))); } else { return _readStringFromProgmem ((char*)pgm_read_word(&(_flprogMenuStringsArray[indexMin - 1]))); } }  
      пишу в flprog
      i2c сканер тоже молчит и не отправляет данные через порт
       
    • 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);     } }  
×
×
  • Create New...