Отговори на тема  [ 281 мнения ]  Отиди на страница Предишна  1 ... 4, 5, 6, 7, 8, 9, 10 ... 19  Следваща
I2C малко помощ 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
ig_ivanov написа:
На пръв прочит- D ти е дефинирана локално и по никакъв начин не е свързана с буфера или данните, които се обменят.
Трябва да имаш нещо от рода:
D = EEPROM_buffer[index] или EEPROM_buffer[index] = D;

ПП: Последния if (D=11) логически е вярно, практически- не. Трябва да е if (D==11).


Не съм записал нищо, което да вкарва D в i2c бизнеса, тъй като не знам, какво.

Предполагам - "I2C_slaveWriteData = D;" или "EEPROM_Buffer[0] =D;".......

Твоят код не можах да го натъкмя така, че компилаторът да не ме плюе :) Иначе той ми е доста по-разбираем в сравнение с това, което генерира MCC.

Странното е и това, че докато викам някоя от i2c функциите на master - ра, не виждам никакви признаци на живот по SCL или SDA линиите. Седят си високи и не мигват дори.


Сря Авг 09, 2017 4:13 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: I2C малко помощ
void main(void)
{
// initialize the device
SYSTEM_Initialize();
I2C_Initialize();
unsigned int D;
while (1)

{
RXbuffer_forslave_1=0xee;
I2C_MasterRead(RXbuffer_forslave_1,10,1,&statusReadSlave1);
while ((statusReadSlave1!=I2C_MESSAGE_COMPLETE)
&&
((statusReadSlave1!=I2C_MESSAGE_FAIL))
{ //////wait here

};

D=RXbuffer_forslave_1[0];
if(D==11)
LATA4=1;
if(D==0)
LATA4=0;
};



Не виждам да викаш I2C_Initialize();
Друг труден въпрос
void I2C_ISR ( void ) e дефинирана,
а другата само е "проектирана"
void I2C_BusCollisionISR( void )
{
// enter bus collision handling code here
}

Тези двете функции за прекъсване -кой ги вика? Къде в кода ти се споменават -
предполагам - щом са дадени имена с "ISR", трябва да имаш обработчик на
прекъсванията - който да ги вика,


Сря Авг 09, 2017 4:56 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 03, 2005 2:21 am
Мнения: 12765
Местоположение: София
Мнение Re: I2C малко помощ
ig_ivanov написа:
ПП: Последния if (D=11) логически е вярно, практически- не. Трябва да е if (D==11).

По тоя повод, познат, старо куче програмист, препоръчва синтаксисът да е обърнат:
if (11==D)
Така, при изписване if (11=D), се получава съобщение за грешка, което няма как да не бъде забелязано, докато if (D=11) евентуално би генерирало уърнинг...


Сря Авг 09, 2017 5:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
I2C_Initialize(); e в списъка на SYSTEM_Initialize();

void SYSTEM_Initialize(void)
{

PIN_MANAGER_Initialize();
OSCILLATOR_Initialize();
WDT_Initialize();
I2C_Initialize();
}

ISR функцията не се ли стартира от самото прекъсване за което има вдигнат флаг SSP1IE = 1?

За I2C_BusCollisionISR понятие си нямам :)

Благодаря за кода! Ще тествам и ще пиша резултата.


Сря Авг 09, 2017 5:30 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
while (1)

{
RXbuffer_forslave_1=0xee;
I2C_MasterRead(RXbuffer_forslave_1,10,1,&statusReadSlave1);
while ((statusReadSlave1!=I2C_MESSAGE_COMPLETE)
&&
((statusReadSlave1!=I2C_MESSAGE_FAIL))
{ //////wait here

};

D=RXbuffer_forslave_1[0];
if(D==11)
LATA4=1;
if(D==0)
LATA4=0;
};

Това не ми го приема компилаторът. Мисля, че има една скоба в повече и я махнах, но пак не става.
Декларациите за RXbuffer_forslave_1 и statusReadSlave1 съм направил, като unsigned int. Не знам дали е правилно.


Сря Авг 09, 2017 6:27 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Съб Май 21, 2016 9:47 pm
Мнения: 577
Местоположение: Бургас
Мнение Re: I2C малко помощ
while ((statusReadSlave1!=I2C_MESSAGE_COMPLETE) && (statusReadSlave1!=I2C_MESSAGE_FAIL))
{
//////wait here
}


Сря Авг 09, 2017 6:46 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
Защо се пъне компилаторът, ще го открия все някак. Важното е, че от последната насока на Стефан разбах значението на аргументите на функцията за четене и как да се отработва флага.

Благодаря, че ми помагате :)


Сря Авг 09, 2017 8:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: I2C малко помощ
Сега не ми се чете шита на твоя процесор,
но самата декларация на ISR функцията не указва нито, че е интеръпт-функция , нито за кой флаг се отнася .
Обвързаността флаг - функция (вектор по флаг).... я няма при всички МЦУта. Предполагам , че твоят проц има един - два вектора за прекъсване , при доста много потенциални източници . Тоест на кое да е прекъсване се вика една и съща функция - обработчик/хандлер.
Тоя обработчик(ти го пишеш) проверява възможните флагове за прекъсване и за съответен флаг - вика подходяща функция.
Тоест - всичко това го програмираш ти - и проверката на флаговете, и подходящите функции. В повечето случаи трябва да нулираш и флага, който предизвиква прекъсването - чрез директно нулиране флагХ=0.
Тези готови И2Ц конструкции ,които ползваш, са силно обвързани с прекъсванията.
Така че - време е да почетеш - как ,какво и кога става в проца при прекъсване. И как това се организира в твоята среда/компилатор.


Сря Авг 09, 2017 10:14 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: I2C малко помощ
Код:
void I2C_MasterRead(
                                uint8_t *pdata,
                                uint8_t length,
                                uint16_t address,
                                I2C_MESSAGE_STATUS *pflag)

Цитат:
Декларациите за RXbuffer_forslave_1 и statusReadSlave1 съм направил, като unsigned int. Не знам дали е правилно.



В общи линии е неправилно и може оттам компилаторът да се сърди.
Функцията ще чете данни от тип байт, unsigned int - вероятно е двубайтов тип при тебе.
Ако със специални директиви за преобразувне на типа заобиколиш грешката,
то четецът ще запише два байта от слейва в един елемент на твоя масив от двубайтови числа.
После трябва работата с масива да е съобразена с това .
Възможно е , но трябва да имаш много специална причина да го направиш.
RXbuffer_forslave_1 трябва да е от типа uint8_t, а
statusReadSlave1 - от тип I2C_MESSAGE_STATUS.
Както е в декларацията на функцията.

Промених типовете, защото тез двата твои са специфични и им нямам дефинициите- иначе стандартен Ц компилатор щеше да се сърди :D


ПС.
Всъщност те излъгах. Доста приични може да има да ползваш преобразуване на тип.
Например слейвът изработва 5 резултата от 12битово АЦП- това са 10 байта.
И2Ц функцията може да достави тези 10 байта, тя е написана да достава байтове.
Така първите 2 байта може да ги прати в двубайтов елемент на масива ти от unsigned int.
После -
if (RXbuffer_forslave_2[0]>0x120) {......};
ще проверява коректно истински резултат от АЦП.
За да стане това - прочети за type casting.

Предполагам компилаторът се сърди, заради несъвпадение на типовете - от декларацията и от извикването.


Сря Авг 09, 2017 11:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
Правилно предполагаш :)

Оправих декларациите, както каза:

uint8_t RXbuffer_forslave_1[];
I2C_MESSAGE_STATUS statusReadSlave1;

и компилаторът миряса.

Но комуникацията все още не работи.

Преработих while(1), както следва:

while (1)

{
RXbuffer_forslave_1[0]=0xee;
I2C_MasterRead(RXbuffer_forslave_1,10,1,&statusReadSlave1);


while ((statusReadSlave1!=I2C_MESSAGE_COMPLETE)
&&
(statusReadSlave1!=I2C_MESSAGE_FAIL))

{
//////wait here
}

LATA4=1;

}


само за да видя, докъде стига. LATA4 не се пали, т.е - мисля, че цикли на флаговете I2C_MESSAGE_COMPLETE и I2C_MESSAGE_FAIL.

В тази връзка, не разбирам, защо I2C_MESSAGE_COMPLETE е включено в условието? Не трябва ли да цикли само ако е вдигнат I2C_MESSAGE_FAIL?

Както и да е - пробвах и само с по едно от всяко от условията и пак цикли там.

Това, за прекъсванията ми е малко "тъмна Индия" и единствено знам, че въпросният пик е само с един вектор на прекъсване.

В тази връзка може би трябваше да покажа и това, което е генерирал MCC по въпроса:

За Master - а

Код:
/**
  Generated Interrupt Manager Source File

  @Company:
    Microchip Technology Inc.

  @File Name:
    interrupt_manager.c

  @Summary:
    This is the Interrupt Manager file generated using MPLAB(c) Code Configurator

  @Description:
    This header file provides implementations for global interrupt handling.
    For individual peripheral handlers please see the peripheral driver for
    all modules selected in the GUI.
    Generation Information :
        Product Revision  :  MPLAB(c) Code Configurator - 4.15
        Device            :  PIC12F1840
        Driver Version    :  1.02
    The generated drivers are tested against the following:
        Compiler          :  XC8 1.35
        MPLAB             :  MPLAB X 3.40
*/

/*
   
*/

#include "interrupt_manager.h"
#include "mcc.h"

void interrupt INTERRUPT_InterruptManager (void)
{
    // interrupt handler
    if(INTCONbits.PEIE == 1 && PIE2bits.BCL1IE == 1 && PIR2bits.BCL1IF == 1)
    {
        I2C_BusCollisionISR();
    }
    else if(INTCONbits.PEIE == 1 && PIE1bits.SSP1IE == 1 && PIR1bits.SSP1IF == 1)
    {
        I2C_ISR();
    }
    else
    {
        //Unhandled Interrupt
    }
}



и за Slave:

Код:
/**
  Generated Interrupt Manager Source File

  @Company:
    Microchip Technology Inc.

  @File Name:
    interrupt_manager.c

  @Summary:
    This is the Interrupt Manager file generated using MPLAB(c) Code Configurator

  @Description:
    This header file provides implementations for global interrupt handling.
    For individual peripheral handlers please see the peripheral driver for
    all modules selected in the GUI.
    Generation Information :
        Product Revision  :  MPLAB(c) Code Configurator - 4.15
        Device            :  PIC12F1840
        Driver Version    :  1.02
    The generated drivers are tested against the following:
        Compiler          :  XC8 1.35
        MPLAB             :  MPLAB X 3.40
*/

/*
*/

#include "interrupt_manager.h"
#include "mcc.h"

void interrupt INTERRUPT_InterruptManager (void)
{
    // interrupt handler
    if(INTCONbits.PEIE == 1 && PIE1bits.SSP1IE == 1 && PIR1bits.SSP1IF == 1)
    {
        I2C_ISR();
    }
    else
    {
        //Unhandled Interrupt
    }
}


Чет Авг 10, 2017 12:19 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
Да не би да трябва и функцията I2C_MasterReadTRBBuild() да се изпълнява в цикъла?

Пробвах да я вкарам там с някакви измислени аргументи (не знам, какви да и задам):

Код:
while (1)

{
I2C_MasterReadTRBBuild(1,20,1,1);
I2C_MasterRead(RXbuffer_forslave_1,10,1,statusReadSlave1);


while ((statusReadSlave1!=I2C_MESSAGE_COMPLETE)
&&
(statusReadSlave1!=I2C_MESSAGE_FAIL))


{
    //////wait here
}
   

LATA4=1;


и така вече се забелязва нещо по шината:

Изображение


Чет Авг 10, 2017 4:23 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: I2C малко помощ
Това ,което виждаш е нещо като старт/стоп.
MasterRead вика
...Build и ...Insert.
Както го разбрах - Insert задейства комуникцията и стои в очакване , докато не свърши обмена по някакъв начин.
Тоест просто викаш Read и после обработваш данните - няма нужда от while .
Защо обаче не тръгва - не можах да предположа.

uint8_t RXbuffer_forslave_1[10]; е по-правилно



void interrupt INTERRUPT_InterruptManager (void)
{

//сложи тукнякакво цъкане на някой порт - да видиш сосцилоскопа, че се вика тоя хандлер
// interrupt handler
if(INTCONbits.PEIE == 1
//тоя бит някой рзрешав ли го ???


Пет Авг 11, 2017 12:35 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
Дадох прост пример с четенето на стойността на една променлива само за да наблегна върху същинския проблем - този с I2C комуникацията.
Може би сега е моментът да уточня, че всъщност е удачно при всяка транзакция да се четат блокове от байтове, вместо отделни байтове.

Накратко - идеята е някакъв master, който държи LCD индикация, да сканира малките пикове и да чете от тях по около 40 байта накуп за да ги визуализира.


Пет Авг 11, 2017 12:49 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: I2C малко помощ
uint8_t RXbuffer_forslave_1[];
е доста хай-текдекларация и трябва да знаеш защо я правиш. Струва ми се ,че не знаеш. :)


Пет Авг 11, 2017 12:54 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Май 12, 2014 11:49 pm
Мнения: 4394
Местоположение: София
Мнение Re: I2C малко помощ
Не само ти се струва :)

Компилаторът упорито плюеше червени редове докато не сложих тези скоби.


Пет Авг 11, 2017 12:58 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 281 мнения ]  Отиди на страница Предишна  1 ... 4, 5, 6, 7, 8, 9, 10 ... 19  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 0 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни