Форум РадиоКот https://radiokot.ru/forum/ |
|
обмен данными по i2c (от простого к сложному) https://radiokot.ru/forum/viewtopic.php?f=20&t=76194 |
Страница 1 из 2 |
Автор: | jakob291 [ Вт июл 31, 2012 11:44:42 ] |
Заголовок сообщения: | обмен данными по i2c (от простого к сложному) |
Еще раз всем доброго дня. Используя МК mega16 и (в будущем) MAX44007 (датчик освещения) планирую заставить их обмениваться информацией. Знаю, что есть статья про цифровой люксометр, где все описано, прошу же помочь в "стартовом толчке". Итак, пока мне нужно заставить обменяться информацией два MK mega16 в простом варианте: ведущий просит у ведомого байт, ведомый передает байт, ведущий зажигает светодиоды на одном из своих портов. Используя библиотеку Procyon AVRLIB написал две следующих простых программки (дополнительно использую команды в виртуальный терминал для отладки в Proteus) Master (ведущий) Код: #include <avr/io.h> #include <string.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <stdio.h> #include <avr/interrupt.h> #include "\i2c\deps\i2c.h" #include "\i2c\deps\UART_routines.h" #define LOCAL_ADDR 0xA0 #define TARGET_ADDR 0x07 unsigned char buf[100]; unsigned char msgbuf[100]; int main(void) { uart0_init(); _delay_ms(1000); sendStr0("*************TWI MASTER RUNNING*************"); // initialize i2c function library i2cInit(); // set local device address and allow response to general call i2cSetLocalDeviceAddr(LOCAL_ADDR, TRUE); unsigned char mBuf[100]; i2cMasterReceive(TARGET_ADDR, strlen(buf), buf); sprintf(msgbuf,"master received: %s (length %d)",buf,strlen(buf)); transmitString(msgbuf); TX_NEWLINE; Slave (ведомый) Код: #include <avr/io.h> #include <string.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <stdio.h> #include <avr/interrupt.h> #include "\i2c\deps\i2c.h" #include "\i2c\deps\UART_routines.h" #define LOCAL_ADDR 0x07 #define TARGET_ADDR 0xA0 unsigned char buf[40]; unsigned char byteToSend; // slave operations void i2cSlaveReceiveService(u08 receiveDataLength, u08* receiveData) { sprintf(buf,"slave received: %s (length %d)",receiveData,receiveDataLength); transmitString(buf);TX_NEWLINE; } void i2cSlaveSendService(u08 transmitDataLength, u08 byteToSend) { byteToSend=0b00111100; sprintf(buf,"slave sent: %s (length %d)",byteToSend,transmitDataLength); transmitString(buf); TX_NEWLINE; } int main(void) { uart0_init(); //_delay_ms(10); sendStr0("*************TWI SLAVE RUNNING*************"); // initialize i2c function library i2cInit(); // set local device address and allow response to general call i2cSetLocalDeviceAddr(LOCAL_ADDR, TRUE); i2cSetSlaveReceiveHandler( i2cSlaveReceiveService ); i2cSetSlaveTransmitHandler(i2cSlaveSendService ); while(1) { _delay_ms(100); } } Протеус в своих терминалах грустно сообщает, что ведомый передал "нечто" (совпадения бит мне обнаружить не удалось), хотя команды старт и стоп передались нормально. Ведущий же ничего не получил. (длина 0) Судя по всему, я просто где-то что-то не понимаю, потому что, к примеру, у мастера процедура i2cMasterReceive(TARGET_ADDR, strlen(buf), buf); не имеет возвращаемого значения, а записывает результат (как я понимаю) в buf. Собственно, пока прошу помочь исправить программу так, чтобы она выполняла сей несложный алгоритм Спасибо |
Автор: | igor-x [ Вт июл 31, 2012 14:32:23 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
если не ошибаюсь, то младший разряд адреса используется для широковещательных сообщений 0х07 = 0b00000111 возможно дело в адресе? для верности обратитесь в даташит +++ и еще i2cMasterReceive(TARGET_ADDR, strlen( buffer),&RecBuf[0]) ; |
Автор: | jakob291 [ Вт июл 31, 2012 14:50:03 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Дело врядли в адресе. Я эту программу взял из статьи-примера, но там мастер передает, ведомый принимает. Это работает (и у меня в протеусе). Но мне же нужно будет определенный адрес читать ибо люксометр точно будет ведомым. Попытался переделать, но мимо. |
Автор: | igor-x [ Вт июл 31, 2012 14:53:52 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
посмотрите строку из моего примера (см выше). это работает - там адресация к буферу иначе сделана |
Автор: | jakob291 [ Вт июл 31, 2012 16:22:03 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Попробовал. Без перемен. slave sent 32(!!??), master received 0 Если дело и в этом, то не только в этом. привожу пример кода мастера с исправлением, возможно я не так понял строчку кода. Код: #include <avr/io.h> #include <string.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <stdio.h> #include <avr/interrupt.h> #include "\i2c\deps\i2c.h" #include "\i2c\deps\UART_routines.h" #define LOCAL_ADDR 0xA0 #define TARGET_ADDR 0x07 unsigned char buf[100]; unsigned char msgbuf[100]; int main(void) { uart0_init(); _delay_ms(1000); sendStr0("*************TWI MASTER RUNNING*************"); // initialize i2c function library i2cInit(); // set local device address and allow response to general call i2cSetLocalDeviceAddr(LOCAL_ADDR, TRUE); unsigned char mBuf[100]; // sprintf(mBuf,"%s","hello!"); // mBuf[strlen(mBuf)]=0x00; //i2cMasterSend(TARGET_ADDR,strlen(mBuf)+1/*(0x00)*/,&mBuf[0]); char RecBuf[100]; i2cMasterReceive(TARGET_ADDR, strlen(buf), &RecBuf[0]); // sprintf(msgbuf,"master received: %s (length %d)",RecBuf,strlen(RecBuf)/*(0x00)*/); transmitString(msgbuf); TX_NEWLINE; Байт пытался передавать разных, в I2C debugger ничего не меняется |
Автор: | phanis [ Вт июл 31, 2012 16:39:17 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Код: SPI debugger а это здесь зачем?? вроде как i2cЦитата: 0х07 = 0b00000111 младший разряд запись/чтение (1 чтение )Широковещательный адрес 0 |
Автор: | jakob291 [ Вт июл 31, 2012 16:46:22 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Цитата: Код: SPI debugger а это здесь зачем?? вроде как i2c Пардон, о чем думал, то и написал. I2C конечно же. А вот с адресом... я все равно не понял что не так. 0x07 - адрес ведомого, которого я и читаю. Ведомый, будучи МК, сам его себе ставит. Широковещательный адрес мне здесь вроде не нужен, ибо он используется для того, чтобы все ведомые приняли сообщение от ведущего. Попробовал поставить адресом ведомого 0x06 и обращаться к нему же - вообще ничего не меняется Или дело в другом? |
Автор: | phanis [ Вт июл 31, 2012 16:59:55 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Нормально все с адресом. Всего кода же не видно, только часть. Без библиотеки.. А чё она там делает не понятно.. Может отладку вести например так, было прерывание по TWI вывести сообщение или лапкой дернуть. приняли свой адрес другой лапкой .. Да и на дебугере протеуса видно аск был или нет. Сейчас хотя бы наладить аппаратную часть. |
Автор: | phanis [ Вт июл 31, 2012 18:01:06 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Код: void i2cSlaveSendService(u08 transmitDataLength, u08 byteToSend) { byteToSend=0b00111100; sprintf(buf,"slave sent: %s (length %d)",byteToSend,transmitDataLength); transmitString(buf); TX_NEWLINE; } попробуй так Код: u08 i2cSlaveSendService(u08 transmitDataLength, u08* byteToSend)
{ *byteToSend=0b00111100;//записать в переменную по указателю byteToSend // sprintf(buf,"slave sent: %s (length %d)",byteToSend,transmitDataLength); // transmitString(buf); // TX_NEWLINE; return 1; //количество передаваемых байт у тебя один } |
Автор: | jakob291 [ Вт июл 31, 2012 18:27:54 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Та же песня, даже в дебагере сообщение не поменялось. Заставил ведомого подать +5 на PB0 при срабатывании SlaveSendService - срабатывает. Что-то мне подсказывает, что у меня или обработчик неправильно задан, или мастер не оттуда берет этот самый бит. Просто мне подобная программная структура (когда нечто передается параметром в функцию и оно же выступает результатом) кажется какой-то несуразной. В C# так вообще нельзя (передаваемый параметр строго только для чтения), но по опыту, C/C++ иногда такие вещи допускают... |
Автор: | phanis [ Вт июл 31, 2012 18:31:39 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Можно весь проект увидеть?? Одним Архивом.. |
Автор: | jakob291 [ Вт июл 31, 2012 18:47:53 ] | ||
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) | ||
Нет проблем. Только вопрос, сколько Вы его собирать воедино будете: 2 проекта AVR studio 5.1, мастер и ведомый. В папке deps - библиотечки и прочее для i2c (procyon) И файл протеуса. Все с последними правками.
|
Автор: | phanis [ Ср авг 01, 2012 17:08:50 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
МК не успевает должным образом обрабатывать . Код: u08 i2cSlaveSendService(u08 transmitDataLength, u08* byteToSend) { *byteToSend= 0x11;//записать в переменную по указателю byteToSend return 1; //количество передаваемых байт у тебя один } Выход либо тактовую поднять у слейва, либо у мастера i2cSetBitrate(100); сделать меньше например 50. Ну еще можно в библиотеке поковыряться. |
Автор: | jakob291 [ Ср авг 01, 2012 17:30:13 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Собственно, только и делаю, что ковыряюсь в библиотеке. Только толковой документации нет. Изменение битрейта, как я и предполагал, ничего не дало. В I2C debugger сообщение меняется если поменять число передаваемых бит. Но по-прежнему никакого соответствия я не наблюдаю... |
Автор: | phanis [ Ср авг 01, 2012 18:03:09 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
У меня работает передает то что я назначил. Вложение: 0x11 только тактовую на слейве поднял до 8 |
Автор: | jakob291 [ Ср авг 01, 2012 18:35:42 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Да, передача идет. А именно код посмотреть можно? Интересная хрень с частотами, с чего бы ему не успевать... |
Автор: | phanis [ Ср авг 01, 2012 18:52:24 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Вложение: Вот только пути уже по другому, Я АВР студио не работал.Код: i2cMasterReceive(TARGET_ADDR, len, RecBuf); в место лен нужно установить сколь байт считывать в твоем случае 1и там ниже в мастере не обращай внимания. |
Автор: | jakob291 [ Ср авг 01, 2012 20:08:43 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
Ух, работает хреновина) Самое страшное, это же была только имитация реальности) Теперь предо мной встает датчик. А у датчика измерения хранятся в двух байтах, в двух регистрах. А адрес у датчика один) В общем, спасибо за помощь. Тему не закрываю, то ли еще будет) |
Автор: | phanis [ Чт авг 02, 2012 19:40:50 ] |
Заголовок сообщения: | Re: обмен данными по i2c (от простого к сложному) |
И еще как небольшие рекомендации для мастера уметь дрыгать ножкой клок программно. Спасает при коллизиях на шине. Можно засунуть в процесс инициализации шины. И для слейв устройств проходить переинициализацию шины если в течении какого времени мастер не обращается к ниму.. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |