Шина I2C. Что такое регистры?

Vadim111
Offline
Зарегистрирован: 14.01.2015

Прошу не наказывать строго если вопрос не по адресу.

Я имею опыт создания любительских проектов с использованием шины I2C. Ардуино-мастер посылает слейвам некие значения, а те управляют исполнительными механизмами. Если напряжение логического уровня одинаковое и если это не Arduino DUE, то всё работало как часы.  А библиотека Wire настолько проста и понятна, что я никогда не вникал в дебри теории шины I2C.

Недавно я решил заменить Мастер-устройство шины I2C на Raspberry Pi. (Мой вопрос не о Распбери, пожалуйста дочитайте до конца). Это связано с тем, что я хочу построить управление через Веб интерфейст со сложной формой. Даже для Ардуин Mega и Due загрузка больших форм с карты памяти идёт долго, а плотный поток запросов из формы подвешивает платы. У Raspberry веб сервер работает быстро и чётко. Но у меня возникла неразрешимая проблема с передачей данных по I2C.

У Ардуины в библиотеке Wire для передачи данных надо было указывать только 2 параметра: адрес устройства на шине и передаваемый байт информации (или несколько байт). Это было понятно. У Raspberry в языке Python тоже есть библиотека для работы с I2C (библиотека SMbus). Но там для передачи данных надо указывать три параметра: Адрес слейв устройства на шине, передаваемый байт и регистр.

Вот ссылки на функции этой библиотеки:

http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

https://raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2

В моём случае при использовании Raspberry Pi в качестве Мастера всё, казалось бы, работает: Шина включена, Ардуино-слейвы на шине распознаются. Но если я указываю только 2 аргумента в функции передачи данных (адрес и передаваемый байт), появляется ошибка компилятора. Если я указываю третий аргумент (значение регистра) от фонаря, то значения не передаются вовсе.

Я перечёл много разных объяснений, примеров, задавал вопрос на тамошнем форуме. Но я нигде не могу найти чёткого, внятного ответа и не могу понять, что такое Регистр шины I2C и где брать этот параметр.

МОЙ ВОПРОС:

Если кто-то плотно работал с шиной I2C на Ардуине или вообще знает предмет вопроса, пожалуйста объясните самым примитивным человеческим языком, что такое регистр шины I2C и где теоретически можно узнать это значение (например, для сети из Ардуин и Распбери). Одинаково ли это значение для всех устройств или для каждого слейва своё?

Буду очень благодарен.

Еще раз прошу прощения за отвлечённый вопрос.

rkit
Offline
Зарегистрирован: 23.11.2016

Это просто первый байт последовательности после адреса. Питонисты просто сделали себе такой дурацкий интерфейс, зачем-то, хотя далеко не всегда это нужно.

sadman41
Offline
Зарегистрирован: 19.10.2016

Регистр в I2C устройстве обозначает некую область памяти для чтения или записи. Образно говоря - это элемент массива данных внутри слейва: "Registers are locations in the slave's memory which contain information, whether it be the configuration information, or some sampled data to send back to the master. The master must write information into these registers in order to instruct the slave device to perform a task."

Карта регистров для каждого устройства своя. Ознакомиться с ней можно в даташите на микросхему/устройство.

Возможно, что этот пост будет полезен: https://www.raspberrypi.org/forums/viewtopic.php?p=600515#p600515

В противном случае придётся прибегать к грязным хакам. Например, при записи, в cmd/register совать первый байт данных, а в качестве value указывать второй и последующие.

Vadim111
Offline
Зарегистрирован: 14.01.2015

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

Не могли бы объяснить так, как объясняли бы ребёнку? Буду очень признателен.

Допустим, я хочу передать от Мастера к Слейву число 201 (его эквивалент в двоичной системе занимает 1 байт - 11001001) Функция требует от меня 3 аргумента. Адрес слейва (всё понятно), передаваемое число (всё понятно) и регистр. Что я должен подставлять в аргумент регистр? Вот это передаваемое число? Но это же не регистр!

А если я буду каждую секунду передавать какое-то новое число? Мне каждый раз подставлять новое "значение регистра"? Или подставлять то число, которое я передал первым? Это же нелепо, антилогично и просто непонятно. 

А если я буду каждую секунду передавать какое-то новое Int число, которое занимает 2 байта? Мне нужно передать последовательность из 2-х байтов, но каждый раз эти байты будут разными. Мне каждый раз в аргумент функции "регистр" подставлять новый первый байт?

Будьте добры, объясните, что вы имели ввиду.

Vadim111
Offline
Зарегистрирован: 14.01.2015

sadman41 пишет:

Карта регистров для каждого устройства своя. 

Возможно, что этот пост будет полезен: 

Большое спасибо. Но к сожалению я так и не смог это осилить.

Предлагаемую вами ссылку я читал. Но я решительно не понимаю, о чём там вообще идет речь. Я прекрасно понимаю, что вы можете отправить меня изучать теорию и будете правы. Но Ардуино (да и Распбери)- это все-таки платформы и для любителей. Поэтому я и прошу дать какое-то очень простое и понятное объяснение регистров не в плане классического определения, а в плане практического использования функции по отправке числа от Мастера к Слейву.

В моей схеме я использую Raspberry Pi 3B+ и Arduino Pro Mini atmel atmega328p. Оба 3,3В. 

Открыл даташит на atmega328p. Среди прочего нашёл General Purpose Working Registers. Представлена некая таблица, в которой обозначены сами регистры R0, R1, R2... (всего 31) и их адреса 0х00, 0х01, 0х02... Но как я могу применить это на практике? Какой из этих регистров мне выбрать для подстановки в функцию передачи значений по I2C?

И ещё: Регистры какого устройства (Ардуино или Распбери) мне надо подставлять в функцию в том случае, если я передаю данные от Мастера к Слейву, и наоборот - если от Слейва к Мастеру?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Бросай, не твое это.  

А если бросать не хочешь, прочти сначала хоть одну книжку по Ардуино и программированию, причем, желательно, чтоб это были разные книшки.. В песочнице в приколоченной теме библиография на выбор. Без этого, коль ты в регистры полез, дальнейший разговор бессмысленен. 

nik182
Offline
Зарегистрирован: 04.05.2015

Вот вот. И к тому же регистрами называют ячейки памяти, имеющие специальное назначение. В разных устройствах регистры имеют разное назначение. Реагировать на слово регистр, без понимания что данный регистр делает и для чего нужен просто глупо. Нужно изучить конкретное устройство. А устройств много. И каждое имеет свой набор регистров. Т.е. в первом приближении это просто ячейка памяти, в которую можно записывать и считывать информацию. Во втором ‐ от состояния некоторых регистров может зависеть работа устройства. Учится, учится и учится, как говорил великий ВИЛ. И вопросы отпадут сами. Описание всех регистров есть в мануалах на конкретный чип.

Очень рекомендую прочитать мануал на чип часов DS3231 в части I2C протокол. Там описано, что надо делать, что бы записать или прочитать любой из регистров часов. Для DS3231 малинкина функция работы по i2c подходит идеально. 

sadman41
Offline
Зарегистрирован: 19.10.2016

У меня один вопрос: почему сразу I2C, если ATMega328 - это не I2C устройство? Выберите протокол попроще.

b707
Offline
Зарегистрирован: 26.05.2017

Vadim111 пишет:

Не могли бы объяснить так, как объясняли бы ребёнку? Буду очень признателен.

давай попробуем

Цитата:
Допустим, я хочу передать от Мастера к Слейву число 201 (его эквивалент в двоичной системе занимает 1 байт - 11001001) Функция требует от меня 3 аргумента. Адрес слейва (всё понятно), передаваемое число (всё понятно) и регистр. Что я должен подставлять в аргумент регистр? Вот это передаваемое число? Но это же не регистр!

I2C - транспортный протокол, служит для передачи данных от одного устройства к другому по определенному адресу.  Это похоже на почту, например Почта России :) И адресация в протоколе похожа на почтовую - состоит из двух частей - I2C адрес устройства это номер дома,  и регистр - это квартира в этом доме

Каждый регистр I2C - от совершенно конкретный получатель твоих данных. Из этого очевидно, что отправляя число 201, не надо писать его в номер регистра  и не надо писать какое-то случайное число. Нужно указывать совершенно конкретный регистр - тот, где в слейве находится получатель или обработчик того, что ты передаешь. Точно как на почте - если ты пишешь нежные письма Машеньке - ты будешь адресовать их на машенькимн номер квартиры, а не писать в адресе первое попавшееся число, иначе письма будут приходить невесть кому и над ними будет ухохатываться весь дом.

Цитата:
А если я буду каждую секунду передавать какое-то новое число? Мне каждый раз подставлять новое "значение регистра"? Или подставлять то число, которое я передал первым? Это же нелепо, антилогично и просто непонятно.

Ну и тут, надеюсь, уже все понятно. Если ты каждую секунду передаешь новое число в тот же регистр - то и подставляешь каждый раз тот же номер. Опять же по аналогии с почтой - если ты каждый день строчишь письма Машеньке - ты же всегда пишешь в адресе ее номер квартиры, а не указываешь каждый раз разный :)

 

mixail844
Offline
Зарегистрирован: 30.04.2012
еще очень важный момент : PMBus/SMBus не то же самое что и I2C .
PMBus/SMBus строиться над физикой I2C ,  но не всегда два устройства смогут общаться друг с другом
PMBus/SMBus предопределяет некоторые адресса  регистров и адресса команд для устройства , в I2C адресса регистров устройства зависят от прозиводителя
вот ссылочки на различия между ними (англ) : 
 
 
"The theoretical difference is that PMBus is a superset of SMBus which is a superset of I2C. If you take a look at the 7-layers of the OSI Model, I2C is just the Physical Layer. SMBus adds the Data Link and Network Layers, and PMBus adds the Transport layer and a set of >200 commands that are specific to communicating with power management devices"
 
 
если вы хотите со стороны распберри посылать команды SMBus , то на стороне ардуины вам нужно либо реализовать SMBus либо искать готовую библиотеку.
 
вот примеры как использовать SMBus в пайтоне
 
 
 
 
Logik
Offline
Зарегистрирован: 05.08.2014

А сколько у этой расбери шин i2c? Я с оранджем ковырялся, там их несколько и при работе соответственно требуется указывать с какой именно работаеш. Может оттуда и третий параметр. А цепляется к термину регистр я бы не стал, он в ИТ многозначный. Посмотрел доку по первой ссылке. Адрес, данные никаких регистров... Че за нах?!

b707
Offline
Зарегистрирован: 26.05.2017

а . ну да, Логик напомнил, что надо пояснить ТС вот об этом:

Vadim111 пишет:

Открыл даташит на atmega328p. Среди прочего нашёл General Purpose Working Registers. Представлена некая таблица, в которой обозначены сами регистры R0, R1, R2... (всего 31) и их адреса 0х00, 0х01, 0х02... Но как я могу применить это на практике? Какой из этих регистров мне выбрать для подстановки в функцию передачи значений по I2C?

Эти регистры не имеют ни малейшего отношения к I2C

 

nik182
Offline
Зарегистрирован: 04.05.2015

На Счёт писем Машеньке. В том же ds3231 в мануале написано, что если данных больше чем одно, то происходит автоинкремент номера регистра и данные пишутся последовательно в регистры. Т.е если писем в пачке будет больше одного, то первое придёт Машеньке, а остальные во все квартиры с номерами больше Машенькиной.

b707
Offline
Зарегистрирован: 26.05.2017

nik182, ну да , как я себе это представляю - адресация I2C устроена так, будто на стороне получателя всегда стоит микруха ЕЕПРОМ. куда данные пишутся последовательно по ячейкам. То есть регистр - это адрес первой ячейки для записи или считывания

Vadim111
Offline
Зарегистрирован: 14.01.2015

b707 пишет:

1...Точно как на почте - если ты пишешь нежные письма Машеньке - ты будешь адресовать их на машенькимн номер квартиры...

2... Эти регистры не имеют ни малейшего отношения к I2C...

1. Очень наглядный, понятный, а главное - жизненный пример. :) Но прямо напрашивается вопрос: а как же узнать номер квартиры Машеньки? Я понял, что регистры - ячейки памяти чипа. Я понимаю, что при получении информации из I2C байты помещаются в эти регистры, а потом уже передаются переменным в программе. Я догадываюсь, что для работы с данными шины I2C предназначены какие-то конкретные регистры (ячейки памяти) со своими адресами. Но должно же быть у них какое-то ключевое название?! В даташите к чипу 300 страниц. Слово "Регистр" встречается 1500 раз. Как найти то, что мне нужно?

2. Понял! - ошибся не только с квартирой Машеньки, но даже с подъездом. Ну, хотя бы намекните, как искать, что мне нужно.

nik182 пишет:

Очень рекомендую прочитать мануал на чип часов DS3231 в части I2C протокол. Там описано, что надо делать, что бы записать или прочитать любой из регистров часов.

Спасибо, посмотрел. Да, есть красивая таблица с адресами регистров, битами и значениями, которые хранятся в этих битах (часы, дни и т.п.). Но как это прикрутить к шине I2C? К тому же, записывать в регистр мне ничего не нужно (надеюсь код библиотеки сделает это без меня), мне надо узнать адрес нужного регистра.

sadman41 пишет:

У меня один вопрос: почему сразу I2C, если ATMega328 - это не I2C устройство? Выберите протокол попроще.

Мне казалось, что проще некуда. В связке Ардуино - Ардуино эта же ATMega328 работала отлично. Не хотелось менять код Слейва.

mixail844 пишет:

1...если вы хотите со стороны распберри посылать команды SMBus , то на стороне ардуины вам нужно либо реализовать SMBus либо искать готовую библиотеку.

2...вот примеры как использовать SMBus в пайтоне

1. Т.е. получается, что это приговор? Никаких библиотек SMbus для Ардуины, естественно, нет. Написать сам не смогу. Т.е. не стоит и долбаться? Но в сети же полно примеров I2C связки Распбери - Ардуино. Просто никто ничего не объясняет, вот я и не могу разобраться.

2. Это библиотека SMbus2. Читал отзывы, говорят что она подглючивает, поэтому решил пользоваться старой проверенной SMbus. Но суть не меняется. В примере 4 (мой случай) в функции записи в шину 3 аргумента. Номер регистра стоит 0. Я пробовал ставить 0. Ошибки компилятора нет, но данные не идут.

Logik пишет:

1... А сколько у этой расбери шин i2c?

2... Посмотрел доку по первой ссылке. Адрес, данные никаких регистров... Че за нах?!

1. Шины две. При создании объекта класса SMbus указывается номер шины.

bus = smbus.SMBus (1)

Вроде бы вопросов нет.

2. Функции чтения из шины имеют по два аргумента (адрес и данные). Функции записи в шину - три. Мне надо передавать данные, т.е. записывать данные в шину, нужен 3-й аргумент.

nik182
Offline
Зарегистрирован: 04.05.2015

Vadim111 пишет:
nik182 пишет:

Очень рекомендую прочитать мануал на чип часов DS3231 в части I2C протокол. Там описано, что надо делать, что бы записать или прочитать любой из регистров часов.

Спасибо, посмотрел. Да, есть красивая таблица с адресами регистров, битами и значениями, которые хранятся в этих битах (часы, дни и т.п.). Но как это прикрутить к шине I2C? К тому же, записывать в регистр мне ничего не нужно (надеюсь код библиотеки сделает это без меня), мне надо узнать адрес нужного регистра.

Подсоединить к шине i2c устройство. Посмотреть в мануале на устройство адрес регистра, в который нужно записать байт. Дать команду малинке bus.write_byte(I2C_ADDR, byte), bus.write_i2c_block_data и.т.д. в зависимости от того что, сколько байт и в какой регистр надо записать. Список команд записи - чтения можно найти например здесь  https://micro-pi.ru/smbus-i2c-%D0%BD%D0%B0-python-%D0%B2-rpi-opi-bpi/  И описание примера 4 с этой страницы : Открыть шину I2C «0» и записать масив байтов по адресу 0x39, со смещением 0x0C (адрес регистра). Вы можете записать до 32 байтов за раз.

Есть для i2c  много команд. Как просто чтения-записи одного байта даже без регистра устройства, так и до массива байт начиная с адреса или регистра внутри устройства. Подозреваю что ТС в гугле забанен. Там информации по работе с шиной i2c на малине море. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vadim111, я, честно говоря, не могу понять, что именно Вам непонятно.

Выше уже было сказано, что SMBus - частный случай I2C. 

Из этого непосредственно следует, что все, что можно реализовать SMBus, можно реализовать и на I2C. Обратное - неверно: в частности, тот вариант, о котором Вы писали - "как передать один байт" в рамках протокола SMBus, нереализуем. 

Из этого и нужно исходить. Соответственно, у Вас есть выбор:

- найти для малинки библиотеку именно для I2C, а не для SMBus,

- использовать на Ардуинке протокол SMBus, не пользуясь теми возможностями I2C, что не поддерживаются SMBus (в частности - режим передачи по одному байту).

nik182
Offline
Зарегистрирован: 04.05.2015
А как вот это из приведённой ссылки? SMBus на малинке читает 1 байт.
 
Пример 1: чтение байта
Открыть шину I2C «0» и прочитать один байт от адреса 0x39, со смещением 0x0C (адрес регистра).

import smbus

bus = smbus.SMBus(0)
data = bus.read_byte_data(0x39, 0x0C)
print(data)
bus.close()

 

Vadim111
Offline
Зарегистрирован: 14.01.2015

nik182 пишет:

Подсоединить к шине i2c устройство. Посмотреть в мануале на устройство адрес регистра, в который нужно записать байт.

Вы дали очень подробный, развёрнутый ответ. Но без вот этого: "Посмотреть в мануале на устройство адрес регистра, в который нужно записать байт." я не могу сдвинуться дальше ни на шаг. Именно это я и пытаюсь выяснить на протяжении всей дискуссии. 

Я смотрел даташит на atmega328p. Там описание множества регистров со своими адресами. Но ни в одном нет описания, что он предназначен для получения данных из шины I2C. Т.е. у него должно быть какое-то другое ключевое название. Какое?!

Vadim111
Offline
Зарегистрирован: 14.01.2015

nik182 пишет:

А как вот это из приведённой ссылки? SMBus на малинке читает 1 байт.
 
Пример 1: чтение байта
Открыть шину I2C «0» и прочитать один байт от адреса 0x39, со смещением 0x0C (адрес регистра).

import smbus

bus = smbus.SMBus(0)
data = bus.read_byte_data(0x39, 0x0C)
print(data)
bus.close()

 

Ну, если честно, функции чтения библиотеки SMbus я даже не разбирал - изучал функции записи, но и сейчас всё в принципе понятно. Но почему данные читаются из регистра 0х0С, а не из 0х0В или 0х00, например? Как узнать этот адрес, где глянуть? Или именно 0х0С подходит для всех случаев?

Vadim111
Offline
Зарегистрирован: 14.01.2015

andriano пишет:

Vadim111, я, честно говоря, не могу понять, что именно Вам непонятно.

Выше уже было сказано, что SMBus - частный случай I2C. 

Я, конечно, извиняюсь, но именно это и не понятно. В документации сказано, что библиотека SMBus (это название библиотеки языка Пайтон) предназначена для работы с шиной I2C. В этой библиотеке есть ряд функций для записи/чтения из этой шины и пр. Я не могу применить эти функции, поскольку не могу понять, что нужно подставлять в параметр "номер регистра". 

А как может быть библиотека частным случаем шины, для работы с которой она предназначена я не могу понять даже на уровне языковой морфологии.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vadim111 пишет:

andriano пишет:

Vadim111, я, честно говоря, не могу понять, что именно Вам непонятно.

Выше уже было сказано, что SMBus - частный случай I2C. 

Я, конечно, извиняюсь, но именно это и не понятно. В документации сказано, что библиотека SMBus (это название библиотеки языка Пайтон) предназначена для работы с шиной I2C. В этой библиотеке есть ряд функций для записи/чтения из этой шины и пр. Я не могу применить эти функции, поскольку не могу понять, что нужно подставлять в параметр "номер регистра". 

А как может быть библиотека частным случаем шины, для работы с которой она предназначена я не могу понять даже на уровне языковой морфологии.

Я думаю, в Вашем сообщении затронуты сразу несколько вопросов, которые отчасти связаны, а отчасти могут быть разделены. Но, не понимая взаимосвязи между ними, Вы и не можете их разделить.

1. Протокол SMBus реализуется посредство I2C, соответственно, без i2С ничего передать по SMBus невозможно. Поэтому - да, библиотека предназначена для работы с I2C и ни с какой другой шиной работать не будет. Жигули предназначены для работы на 92 бензине. Но это не значит, что 92 бензин ни для чего кроме Жигулей не подходит.

2. В "номер регистра" нужно подставлять, используя одно из двух соображений:

- реализовать на принимающей стороне именно SMBus поверх I2C и тогда под "номером регистра" понимать в точности то, что понимает под ним принимающая сторона.

- принимающая сторона работает на "чистом" I2C, рассматривая номер порта в качестве первого байта посылки, первый байт SMBus сообщения в качестве второго байта посылки и т. д. При этом есть ограничение, что нельзя передать менее двух байт.

PS. На всякий случай сообщу, что это IMHO, т.к. мне приходилось работать с различными вариантами I2C, но не приходилось налаживать обмен между I2C и SMBus. Но если бы пришлось, я пошел бы по одному из двух предложенных путей.

sadman41
Offline
Зарегистрирован: 19.10.2016

Vadim111 пишет:
Я смотрел даташит на atmega328p. Там описание множества регистров со своими адресами. Но ни в одном нет описания, что он предназначен для получения данных из шины I2C. Т.е. у него должно быть какое-то другое ключевое название. Какое?!

ATMega328 не является I2C устройством, что вы у него ищете уже третий день?

nik182
Offline
Зарегистрирован: 04.05.2015

Vadim111 пишет:

В этой библиотеке есть ряд функций для записи/чтения из этой шины и пр. Я не могу применить эти функции, поскольку не могу понять, что нужно подставлять в параметр "номер регистра". 

А как может быть библиотека частным случаем шины, для работы с которой она предназначена я не могу понять даже на уровне языковой морфологии.

Для общения с arduino номер (адрес) регистра не нужен. Вы просто посылаете или принимаете заданное количество байт, а потом , после приёма, сами пишите в те ячейки памяти, куда Вам надо. У малинки есть команды просто послать байт или байты, без посылки номера регистра. прочитайте как организована передача байтов данных между двумя ардуинами. Между малинкой и ардуинкой всё точно так же.

https://www.arduino.cc/en/Tutorial/MasterReader

   

Vadim111
Offline
Зарегистрирован: 14.01.2015

sadman41 пишет:
Vadim111 пишет:
Я смотрел даташит на atmega328p. Там описание множества регистров со своими адресами. Но ни в одном нет описания, что он предназначен для получения данных из шины I2C. Т.е. у него должно быть какое-то другое ключевое название. Какое?!
ATMega328 не является I2C устройством, что вы у него ищете уже третий день?

Сюрреализм какой-то! У меня есть платка Arduino Pro Mini. На этой платке есть чип ATMega328. Эта платка соединена с Arduino DUE 3-я проводами (3-й - земля) и используя библиотеку Wire получает именно те данные, которые DUE посылает ей (DUE - мастер). Не только получает, но и благополучно их обрабатывает и крутит сервоприводы. Если всё вот это называется не I2C, а как-то иначе, давайте называть это иначе. 

Я хочу заменить Устройство-Мастер вот в этой, фиг пойми какой, связке на Распбери. Но именно Распбери (в отличие от DUE) для отправки данных требует от меня  регистры этой самой Arduino Pro Mini. Я до сих пор не могу понять что это за регистры и где взять их номера. И именно это пытаюсь выяснить третий день.

sadman41
Offline
Зарегистрирован: 19.10.2016

Vadim111 пишет:

Сюрреализм какой-то! У меня есть платка Arduino Pro Mini. На этой платке есть чип ATMega328. Эта платка соединена с Arduino DUE 3-я проводами (3-й - земля) и используя библиотеку Wire получает именно те данные, которые DUE посылает ей (DUE - мастер). Не только получает, но и благополучно их обрабатывает и крутит сервоприводы. Если всё вот это называется не I2C, а как-то иначе, давайте называть это иначе. 

Никакого сюрреализма. То, что Вы умеете читать английские буквы - еще не делает Вас специалистом в области англо-саксонской литературы.

То, что в контроллер общего назначения можно залить прошивку, которая будет ИМИТИРОВАТЬ I2C устройство, не делает его полноценным I2C устройством. Регистры процессора не являются регистрами I2C устройства, которым Вы почему-то ожидаете его видеть. 

Регистр - это просто условное название области памяти. Тот факт, что у двух устройств есть что-то называющееся регистром, не делает их эквивалентами друг другу. У Вас есть мозг, у мыши есть мозг. Вы - есть мышь?

 

negavoid
Offline
Зарегистрирован: 09.07.2016
nik182
Offline
Зарегистрирован: 04.05.2015

Vadim111 пишет:

...Я хочу заменить Устройство-Мастер вот в этой, фиг пойми какой, связке на Распбери. Но именно Распбери (в отличие от DUE) для отправки данных требует от меня  регистры этой самой Arduino Pro Mini. Я до сих пор не могу понять что это за регистры и где взять их номера. И именно это пытаюсь выяснить третий день.

Зачем регистр? Вот функция малинки. Только адрес и байт данных. Никаких регистров.

write_byte()
Запись байта.
 
write_byte(addr,val)
Параметры
int addr — I2C адрес устройства.
char val — Байт данных.
Возвращает
long — Отрицательный errno или ноль в случае успеха.
Vadim111
Offline
Зарегистрирован: 14.01.2015

sadman41 пишет:

Никакого сюрреализма. То, что Вы умеете читать английские буквы - еще не делает Вас специалистом в области англо-саксонской литературы.

То, что в контроллер общего назначения можно залить прошивку, которая будет ИМИТИРОВАТЬ I2C устройство, не делает его полноценным I2C устройством. Регистры процессора не являются регистрами I2C устройства, которым Вы почему-то ожидаете его видеть. 

Регистр - это просто условное название области памяти. Тот факт, что у двух устройств есть что-то называющееся регистром, не делает их эквивалентами друг другу. У Вас есть мозг, у мыши есть мозг. Вы - есть мышь?

Я не пытаюсь казаться кому-то специалистом. Напротив, я прошу помощи, потому что не могу понять даже элементарных вещей. Мало того, я сам потихоньку начинаю приходить к описанным вами выводам даже без глубоких знаний I2C. И уже плюнул бы на эту затею, но меня сбивает только одно обстоятельство, что в сети всё-таки есть проекты с I2C связкой Распбери - Ардуино (в том числе Про Мини) и эти связки благополучно работают.

Ответьте тогда хотя бы на такой вопрос: У других Ардуин (на других чипах) есть эти самые регистры для работы с I2C или все Ардуины имитируют I2C устройства?

Vadim111
Offline
Зарегистрирован: 14.01.2015

negavoid пишет:

Пипец, конечно. Меня не покидает чувство, что вы над нами потихонечку издеваетесь.

https://www.bluetin.io/interfacing/i2c-connect-raspberry-pi-arduino/

https://oscarliang.com/raspberry-pi-arduino-connected-i2c/

https://www.thegeekpub.com/18263/raspberry-pi-to-arduino-i2c-communication/

https://dronebotworkshop.com/i2c-arduino-raspberry-pi/

Все эти ссылки я давно проштудировал. Если бы вы хоть глянули на них, то увидели бы, что к коду там нет никаких комментариев. А море воды о том, как подключить Распбери к компьютеру мне ни к чему. У меня на нём уже Веб сервер работает.

Вот:

bus.write_byte_data(address, 0, value)

0-это номер регистра. Почему 0? Где он его взял? Ни слова объяснения, кроме того, что это номер регистра. У меня с нулем не работает.

sadman41
Offline
Зарегистрирован: 19.10.2016

Известные мне ардуины не являются I2C устройствами (и не имеют регистров, которых Вы ищете), но это не препятствует им ИМИТИРОВАТЬ таковые устройства при наличии соответствующей прошивки.

Если бы Вы сходили по ссылке, которую дал nik182 (https://www.arduino.cc/en/Tutorial/MasterReader), то увидели бы там пример slave_receiver, который как раз, ИМИТИРУЯ I2C устройство, принимает по шине все направленные ему байты. 

А в моей ссылке нарисовано, как тупо с питона шарашить в I2C без всяких там региcтров: https://www.raspberrypi.org/forums/viewtopic.php?p=600515#p600515

 

negavoid
Offline
Зарегистрирован: 09.07.2016

Я-то глянул, не первые же попавшиеся ссылки скопировал. Там, на самом деле, вот так:

bus.write_byte(address, value)
# bus.write_byte_data(address, 0, value)

# - это комментарий в пайтоне.

У известных мне ардуин НЕТ никаких регистров при работе по i2c. Вы можете сами их программно сэмулировать, но это не нужно.

Vadim111
Offline
Зарегистрирован: 14.01.2015

sadman41 пишет:

Известные мне ардуины не являются I2C устройствами (и не имеют регистров, которых Вы ищете), но это не препятствует им ИМИТИРОВАТЬ таковые устройства при наличии соответствующей прошивки.

Если бы Вы сходили по ссылке, которую дал nik182 (https://www.arduino.cc/en/Tutorial/MasterReader), то увидели бы там пример slave_receiver, который как раз, ИМИТИРУЯ I2C устройство, принимает по шине все направленные ему байты. 

А в моей ссылке нарисовано, как тупо с питона шарашить в I2C без всяких там региcтров: https://www.raspberrypi.org/forums/viewtopic.php?p=600515#p600515

Первая ссылка - это код из примеров Arduino IDE. С него я начинал, когда писал связку Ардуино - Ардуино. Я не имел понятия о том, что это имитация I2C, просто использовал его , как образец. Впоследствии я кое-что доработал именно для передачи последовательностей байтов (int), но в принципе - это то, с чем я работал.

Во второй ссылке, если вы имеете ввиду именно рисунок, то я не понимаю, что там нарисовано и как это описать в коде программы. Уж извините. Это тот барьер, за которым я просто откажусь от проекта. Если вы имеете ввиду примеры кода, то там примеры только на чтение, но не на запись последовательности байтов.

sadman41
Offline
Зарегистрирован: 19.10.2016

Давайте не будем рассказывать про "только на чтение"

# PCF8591
   dev = i2c.i2c(0x48, 1) # device 0x48, bus 1

   for i in xrange(256):
      str = chr(0x44) + chr(i)
      dev.write(str)
      time.sleep(0.02)

 

Vadim111
Offline
Зарегистрирован: 14.01.2015

negavoid пишет:

Я-то глянул, не первые же попавшиеся ссылки скопировал. Там, на самом деле, вот так:

bus.write_byte(address, value)
# bus.write_byte_data(address, 0, value)

# - это комментарий в пайтоне.

У известных мне ардуин НЕТ никаких регистров при работе по i2c. Вы можете сами их программно сэмулировать, но это не нужно.

Да, действительно, write_byte - единственная функция, которая не имеет третьего параметра. Я не обратил на это внимание, поскольку изначально пытался передать именно последовательность байтов.

Мне надо передавать значения int. Это двух-байтные значения. Т.е. в шину I2C мне надо посылать последовательность. состоящую из двух байтов. На стороне приёмника я принимаю именно байт за байтом и "суммирую" их в цельное int. Склеить эти байты в int получится, если они придут в одной последовательности. Но если я отправлю по одному байту в каждой отдельной сессии, то смогу ли я их потом склеить? Это, конечно, как мне кажется, очень кривой костыль, но сейчас буду пробовать. 

Vadim111
Offline
Зарегистрирован: 14.01.2015

sadman41 пишет:

Давайте не будем рассказывать про "только на чтение"

# PCF8591
   dev = i2c.i2c(0x48, 1) # device 0x48, bus 1

   for i in xrange(256):
      str = chr(0x44) + chr(i)
      dev.write(str)
      time.sleep(0.02)

 

Да, действительно. Извините, не досмотрелся. Посмотреть можно, но настроение пессимистичное. Пишут, что это доступ в шину без использования библиотеки. Но вместе с этим подключают (как библиотеку) и работают с i2c.

Слишком сложно. Попробую тупо скопировать код. Если заработает, можно разбираться с деталями.

Тут с проверенной, хваленной библиотекой SMbus не хочет работать, а с таким кодом - ...

leksejka
Offline
Зарегистрирован: 11.11.2021

Так никто не ответил на прямой вопрос - где брать адреса регистров и каким образом их выбирать. Хотя человек чуть ли ни в каждом сообщении пытался это вызнать. 

b707
Offline
Зарегистрирован: 26.05.2017

leksejka пишет:

Так никто не ответил на прямой вопрос - где брать адреса регистров и каким образом их выбирать. Хотя человек чуть ли ни в каждом сообщении пытался это вызнать. 

только не начинайте снова.

Все тут ТС обьяснили и даже по нескольку раз. Кратко - если речь о готовом устройстве или микросхеме - регистры прописаны в даташите. Если же вы создаете слейв I2C на контроллере - регистры вы должны выбрать и прописать сами.

Если после 30 сообщений ветки и кучи обьяснений все равно непонятно (вот как ТС) - это означает просто недостаток базовых знаний.

leksejka
Offline
Зарегистрирован: 11.11.2021

b707 пишет:

Все тут ТС обьяснили и даже по нескольку раз. А если он (или Вы) все равно не понял - это только означает недостаток базовых знаний.

Хорошо.  То есть брать их из мануала  конкретного устройства верно?  

b707
Offline
Зарегистрирован: 26.05.2017

leksejka пишет:

Хорошо.  То есть брать их из мануала  конкретного устройства верно?  

в случае работы с чужим устройством - да. Если же Вы проектируете свое - то логично что и регистры вы должны придумать сами.

leksejka
Offline
Зарегистрирован: 11.11.2021

Не спорю, у меня лично не хватает знаний. Пытаюсь разобраться в коде, в котором есть метод:

static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)

 

//smbus шина управления системой Основан на шине I²C. Метод принимает идентификатор файла устройства  (inode),Адрес регистра (команда), байт данных
{
    union i2c_smbus_data data;
    data.byte = value;
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command, I2C_SMBUS_BYTE_DATA, &data);
}

И мне не понятно почему мы должны обращаться регистру, а не к слейв устройству напрямую .
leksejka
Offline
Зарегистрирован: 11.11.2021

b707 пишет:

в случае работы с чужим устройством - да. Если же Вы проектируете свое - то логично что и регистры вы должны придумать сами.

Понял! Спасибо большое за ответ

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Это вы писателя этого когда спросите !

b707
Offline
Зарегистрирован: 26.05.2017

leksejka пишет:

мне не понятно почему мы должны обращаться регистру, а не к слейв устройству напрямую .

похоже вы даже не пытались прочесть тему, в которую пишете.

Все уже было обьяснено ранее. На вопрос "почему мы обращаемся к регистру, а не ко всему устройству" - я например отвечал в #8

Если вы продолжите задавать вопросы, которые до вас уже задавали и на которые отвечено выше - я буду их игнорировать.

rkit
Offline
Зарегистрирован: 23.11.2016

leksejka пишет:

Так никто не ответил на прямой вопрос - где брать адреса регистров и каким образом их выбирать. Хотя человек чуть ли ни в каждом сообщении пытался это вызнать. 

Буквально первый ответ.

leksejka
Offline
Зарегистрирован: 11.11.2021
Как бы я дал ответ на вопрос автора. Может еще кто то незнающий зайдет и прочитает. 

Регистры -это блоки быстрой памяти размером 1 байт. В них находятся настройки для переферии мк (таймеры, счечики, ацп,i2c..)
Меняя регистр даем команду мк что и как нужно делать.  точки зрения кода, регистр – это переменная 8 бит,
которую мы можем читать и писать управляя работой мк 8 бит, принимающих значение 0 и 1, то есть один регистр хранит 8 
настроек, которые можно включить/выключить. Что делает каждый бит и регистр –  подробным образом расписано в даташите мк.
Каждый регистр и бит  имеет имя.Имена всех битов и регистров заданы (заняты, зарезервированы) в компиляторе глобально.
Абсолютно вся работа с регистрами заключается в установке нужных битов в нужном байте(в регистре) в состояние 0 или 1
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

А что так мелко ? стыдно за копипаст ???

leksejka
Offline
Зарегистрирован: 11.11.2021

Не суть что это копипаст, главное что понятно и по существу а не то что было написано выше. Не бэ н  мэ.  Вода и ощущение  непонимания темы.   А человек просил именно такой понятный ответ по существу 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Отвечать в теме 2015 года - НЕКРОПОСТИНГ !!!

sadman41
Offline
Зарегистрирован: 19.10.2016

Где тут ответ "по-существу"?

ТС спрашивал про регистры I2C, а не про таймеры и счётчики.

b707
Offline
Зарегистрирован: 26.05.2017

leksejka пишет:

Не суть что это копипаст, главное что понятно и по существу а не то что было написано выше. Не бэ н  мэ.  Вода и ощущение  непонимания темы.   А человек просил именно такой понятный ответ по существу 

это все замечательно, только это не ответ на вопрос ТС.  В этом тексте написано про регистры контроллера, они к регистрам I2C не имеют никакого отношения.

хотели поумничать и сели в лужу. Еще раз говорю - изучайте основы.