Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ccs -> I2c Вроде ура ,а вроде нет
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
kotopuz
Столкнулся с необходимостью связать вместе 3-и контроллера , или управляет главный конроллеп(то есить уже 4-ый), требуется предача данных в обоих направлениях. Сам пишу в ccs, с недавнего времени стал отлаживать с Proteus вместо PICSIM.
Накидал схемку где есть(к сожеланию с собой нет). В ней 2 микроконтроллера PIC16f873. Воспользовавшись примерами написал программу для мастера и слэйва по I2C. В слэйв микроконтроллере есть прерывание SSP, туда поидее дожно прыгнуть управление при приёме данных(пока просто байт), для регистрации этого я каждый раз мигаю светодиодом, но всё не работает, просто не знаю в чём дело cranky.gif Лазил по сайтам и понял, что я не первый кто не может запустить пример. Может кто то делал симуляцию I2C или проверял на практике программы. Везде пишут про обмен данными между МК и перефирией, я понимаю что принципы те же, но без работающего примера я просто экспериментирую, а метод тыка не всегда хорош. БУду благодарен умным людям за хоть что нибудь рабоатющее,
Спасибо.
medved
Цитата
В слэйв микроконтроллере есть прерывание SSP, туда поидее дожно прыгнуть управление при приёме данных(пока просто байт), для регистрации этого я каждый раз мигаю светодиодом, но всё не работает, просто не знаю в чём дело

Сразу вопрос: Формирование ведущим START-условие выполнено???" На Ведущем выполнена обработка прерывания после формирования старт условия (запись байта в регистр передачи)??? В каком состоянии на ведомом бит BF и SSPOV(SSPSTAT<0>,SSPSTAT<6>) перед приемом данных??? Формируется ли прерывание на ведомом (может просто не разрешил переферию)???? И если формируется, то что дает чтение SSРBUF на ведомом??? Как видите вопрос задан слишком обще, требуются уточнения.
kotopuz
Цитата(medved @ Mar 25 2007, 15:27) *
Сразу вопрос: Формирование ведущим START-условие выполнено???" На Ведущем выполнена обработка прерывания после формирования старт условия (запись байта в регистр передачи)??? В каком состоянии на ведомом бит BF и SSPOV(SSPSTAT<0>,SSPSTAT<6>) перед приемом данных??? Формируется ли прерывание на ведомом (может просто не разрешил переферию)???? И если формируется, то что дает чтение SSРBUF на ведомом??? Как видите вопрос задан слишком обще, требуются уточнения.


Отвечу своими кодами )))
Это для главного

#include <16F873A.h>
#device ICD=TRUE
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#use i2c(Master,Slow,sda=PIN_B1,scl=PIN_B4)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)

void main()
{ BYTE data='5',data2,sec_data='1';

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// enable_interrupts(INT_SSP);
// enable_interrupts(GLOBAL);

// TODO: USER CODE!!
while(true)
{
/*i2c_start(); // Issues a start command when in the I2C master mode.
// i2c_write(0xA0);// Device address
i2c_write(data); // Sends a single byte over the I2C interface.
i2c_stop(); //Issues a stop command when in the I2C master mode.
delay_ms(2);
data=data+1;
*/
/* i2c_start();
i2c_write(0xa0); // Device address
i2c_write(data); // Data to device
i2c_start(); // Restart
i2c_write(0xa1); // to change data direction
data2=i2c_read(0); // Now read from slave
i2c_stop();*/

//my
/* putc(data2-0x80);
printf(" ");
data++;
delay_ms(500);*/

////////////////////////// to secomd MCU
i2c_start();
i2c_write(0x14); // Device address
i2c_write(sec_data); // Data to device
i2c_start(); // Restart
i2c_write(0x15); // to change data direction
data2=i2c_read(0); // Now read from slave
i2c_stop();

//my
putc(sec_data-0x80);
printf("1 ");
sec_data++;
delay_ms(500);

}
}



Для слэйв МК-ов(я сделал пока тоже 873 так как в протэусе нет 818-го)

#include <16F873A.h>
#device ICD=TRUE
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES DEBUG //Debug mode for use with ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#use i2c(Slave,sda=PIN_B1,scl=PIN_B4,address=0xA0)
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xa0)

int1 InterruptWAS=0,KOTdata=0;
BYTE KOTObuf;

#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
/* if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;*/
KOTObuf=incoming;
}
if(state == 0x80) //Master is requesting data
{
//i2c_write(buffer[address]);
//my

i2c_write(KOTObuf);
KOTdata=1;
}
InterruptWAS=1;
}


void main()
{ //int8 out_value=0;
//int i;

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

// TODO: USER CODE!!
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);


while (TRUE)
{ while(InterruptWAS)
{ //printf("s");
if(KOTdata)putc(KOTObuf);
output_a(0b01010101);
output_toggle(PIN_B5); //Mignem Diodom
InterruptWAS=0;
KOTdata=0;
}
}

}

Из выше вставленного точно выполняется:
1. Переход в прерывание от SSP(в данном случае I2C)
2.Передаются и принимаются данные со слэйв контроллера, но при передаче на main почему-то к символу прибавляется 0х80(в HEX) при передаче букв, а с цифрами всё нормально.

Не могу сделать:
Для второго слэйва в программе меняется только адресс(скажем 0x15) и при передаче с главного на оба контроллера поочереди вызывает белеберду какую-то.
Проблема где то тут(вроде ) Я не понимаю участок кода(он из примера) про инициализацию приёма данных slave->master с master контроллера:
i2c_write(0xa1); // to change data direction непонимаю почему 41???
data2=i2c_read(0); // Now read from slave

С одним контроллером ругаться уже по I2C можно, только какие адреса допустимы и как реализовать общеее сообщение???? (я понял что надо адресс 0х00 и тогда все долны слушать)
ВотЪ
urry1
Цитата(kotopuz @ Mar 25 2007, 21:17) *
i2c_write(0xa1); // to change data direction непонимаю почему 41???
data2=i2c_read(0); // Now read from slave

С одним контроллером ругаться уже по I2C можно, только какие адреса допустимы и как реализовать общеее сообщение???? (я понял что надо адресс 0х00 и тогда все долны слушать)
ВотЪ

//---------------------------------------------------------------------
А1 -это идет выдача субадреса устройства на шину. Для 24С32 - самое то. smile.gif
А1- запись, А0 - чтение. Как распорядится субадресами - Ваше дело, зависит от того, сколько живых устройств И2С будет в схеме. Я мог бы дать свой код, но там другой компилятор.
kotopuz
Цитата(urry1 @ Mar 26 2007, 09:41) *
//---------------------------------------------------------------------
А1 -это идет выдача субадреса устройства на шину. Для 24С32 - самое то. smile.gif
А1- запись, А0 - чтение. Как распорядится субадресами - Ваше дело, зависит от того, сколько живых устройств И2С будет в схеме. Я мог бы дать свой код, но там другой компилятор.

Я не знаю что такое суд адресс. Знаю что есть зарезервированные .
Я так понял что запись и чтение определяются младшим, то есть 8-м при передаче битом, поэтому A0 это запись в устройство, а A1 чтение. Я повесил 2-а микроконтроллера у второго вделал адресс 0xb0, тогда вроде чтение с него будет 0xb1. Сейчас контроллеры в симуляторе принимают и отсылают по отдельности, а вот когда в код включаю передачу на оба то вообще ничего не работает. Странно... ninja.gif
А за код я был бы вам благодарен, главное его суметь интерпретировать, он наверно на High Tech ?? smile.gif

Суб адрес, одни очепятки laugh.gif
urry1
Цитата(kotopuz @ Mar 26 2007, 10:51) *
Сейчас контроллеры в симуляторе принимают и отсылают по отдельности, а вот когда в код включаю передачу на оба то вообще ничего не работает. Странно... ninja.gif
А за код я был бы вам благодарен, главное его суметь интерпретировать, он наверно на High Tech ?? smile.gif

На рабочей машине проги нет, зря обещал. Компилятор - Кейл, кстати. smile.gif А прерывания по приему запретил в момент своей передачи ?
dac
Цитата(kotopuz @ Mar 25 2007, 05:22) *
Столкнулся с необходимостью связать вместе 3-и контроллера , или управляет главный конроллеп(то есить уже 4-ый), требуется предача данных в обоих направлениях. Сам пишу в ccs, с недавнего времени стал отлаживать с Proteus вместо PICSIM.


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

если интересно, могу бросить исходник на мыло
upc2
На Микрочипе AN736 описывает сетевой протокол для IIC.Присоединил исходники на асм. и С
Работает хорошо-проверял.
В Протеусе IIC терминал работает плохо.Присоединил модель, которая работает лучше.
kotopuz
Цитата(urry1 @ Mar 26 2007, 14:00) *
На рабочей машине проги нет, зря обещал. Компилятор - Кейл, кстати. smile.gif А прерывания по приему запретил в момент своей передачи ?

Жаль что нет программы. Поискал по инету, я не один такой у кого подобные трудности с I2C в CCS компиляторе, те коды которые откопал не работают, а рекоменлации не помагают. Сегодня днём попробую отменить прерывание, я согласен что туту может быть ошибка. В компиляторе CCS написано что прерывание не на приём или передачу, а на активность на шине I2C. Уже хочу переходить на High Tech, говорят с ним меньше трудностей и примеров полно, плюс я отлаживаю в Proteus.
Спасибо.

Цитата(dac @ Mar 26 2007, 22:21) *
Делал в свое время такое, только на picc18, было несколько глюков, с которыми не дошли руки разобраться, но дивайс реально работает:
1. симуляция в протеусе обмена по и2с не работала вообще, хотя реальные девайсы работали
2. был глюк - при опросе по и2с первого контроллера второй на некоторе время терялся, и наоборот, видимо проблема была связана с обработкой чужого адреса, поскольку времени на разбор не было решил в лоб, разносом опроса по времени.

если интересно, могу бросить исходник на мыло

Я был бы вам очень благодарен. И не могли бы вы указать версию компилятора, я вычитал что в некоторых релизах ест ьпроблемы с I2C. Спасибо.

mail: kotopuz@mail.ru
dac
Цитата(kotopuz @ Mar 27 2007, 12:08) *
Уже хочу переходить на High Tech, говорят с ним меньше трудностей и примеров полно, плюс я отлаживаю в Proteus.


может и не стоит переходить на ХиТеч, а просто написать руками протокол обмена?

по крайней мере обеспечена лицензионная чистота продукции, и из этих соображений хочу в ближайшее время посмотреть в сторону ССS.

Хотя в отношении отлаженности кода хиТеч наверное получше,
очень удобно использование переменных типа bit, с другой стороны страдает переносимость кода, недавно с этим столкнулся когда пришлось переходить с pic18 на dsPIC - к последнему хитековский компилятор кривой, как турецкая сабля.
kotopuz
Цитата(upc2 @ Mar 27 2007, 09:06) *
На Микрочипе AN736 описывает сетевой протокол для IIC.Присоединил исходники на асм. и С
Работает хорошо-проверял.
В Протеусе IIC терминал работает плохо.Присоединил модель, которая работает лучше.


Спасибо большое. Любовь к контроллерам убивает и глазик уже дёргается от натуги blink.gif , так что нады отдохнуть и опять в бой )))) cheers.gif
urry1
попробовал - действительно, инструмент и2с в протеусе работает не совсем корректно в случае, когда подчиненное устройство не дает ответа - бит подтверждения. Выводится какая-то галиматья, хотя по графикам все нормально. Для примера - запись числа 59 по 0 адресу в 24с32.
Код
#include <pic.h>
#include <conio.h>
__CONFIG(HS & WDTDIS & LVPDIS );
// это ведущий контроллер
//////////////////////////main/////////          
main()
{
              TRISA=0xff;
              TRISB=0x00;
              TRISC=0xff;// все на ввод.
        SSPSTAT&=0xbf; // cпецификация и2с
        SSPSTAT|=0x80;// cтандартный режим
        SSPADD=80;//скорость передачи
        SSPCON=0x38;// аппаратная  поддержка ведущего режима
        SSPCON2=0;//
PEIE=0;
SSPIE=1;

GIE=0;// ну зачем ведущему прерывания
        SEN=1; // start
do{
}while(SSPIF !=1);// ждем, пока закончится
SSPIF =0;
SSPBUF=0xA0; // субадрес 24с32
do{
}while(SSPIF !=1); // ответил
SSPIF =0;
SSPBUF=0x00; // адрес
do{
}while(SSPIF !=1); // ответил
SSPIF =0;
SSPBUF=0x00; // адрес
do{
}while(SSPIF !=1); // ответил
SSPIF =0;
SSPBUF=0x59; // данные
do{
}while(SSPIF !=1); // ответил
SSPIF =0;
PEN=1; // стоп
do{
}while(SSPIF !=1);
SSPCON&=0xEF;// тормозим
for(;;)
    {
    }
}

Когда микросхема присутствует (есть бит подтверждения), то все нормально, а когда ее убрать, то ...
Но к вопросу о лицензионной чистоте продукции ... smile.gif У меня не хватает совести указать им на глюк...
kotopuz
Цитата(urry1 @ Mar 28 2007, 10:00) *
Когда микросхема присутствует (есть бит подтверждения), то все нормально, а когда ее убрать, то ...
Но к вопросу о лицензионной чистоте продукции ... smile.gif У меня не хватает совести указать им на глюк...


У меня после 15 часовой отладки проекта, наблюдения и проверки работы I2C в протэусе с одним ведущим и двумя слэйвами показали, что всю дурь на форумах которой пичкают народ можно смело выкинуть в урну. Я очен ьуважаю разработчиков, но видимо тех поддержка просто не успевает. Удалось:
1. Стабильно передавать с контроллера на любой адресс(это МК ЛСД и всё что угодно) плюс чтение, но при работе с двумя подключенными контроллерами получается полная херня. Мне кажеться глюк протэуса, так как протокол работает как часы, жаль нет времени собрать в натуре, а результат должен рработать железно.
Так что решением будет "хост" контроллер ))) с 4-мя RS232, для прерывания аппаратный. К сожалению разочаровался в удобстве I2C, хотя простота на лицо, надеюсь CAN будет удобнее, ну я ещё датащитов и примеров не накачал. Всем спасибо большое за поддержку.
Если кому могу помоч по теории в I2C пишите на мыло, а я спать wink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.