|
|
  |
LPC2148 + I2C, скорость переферийной шины |
|
|
|
Nov 10 2008, 00:11
|
Группа: Новичок
Сообщений: 5
Регистрация: 9-11-08
Пользователь №: 41 499

|
Добрый день.
работаю с lpc2148, разработка под gnu (WinARM), код работает из флеш памяти (MAM включен), кристал 12MHz, процессор работает на 60MHz, скорость переферийной шины 30Mz. I2C0 сконфигурирован на частоту SCL=100KHz пытаюсь работать с микросхемой PCF8583 (часы RTC) - выдаю на I2CO сигнал START, получаю ACK (все ОК - мастер занял шину I2C) - передаю адрес устройства (A2) + WRITE bit, на шине NACK - т.е. PCF8583 не смог подтвердить свой адрес и готовность к работе
Снижаю частоту проца до 48MHz, скорость переферийной шины 12Mhz, I2C0 SCL=100KHz получаю - выдаю на I2CO сигнал START, получаю ACK (все ОК - мастер занял шину I2C) - передаю адрес устройства (A2) + WRITE bit, на шине ACK - т.е. PCF8583 подтверждает свой адрес и дальше все работает как ожидается (данные считываются) если поднимать частоту переферийной шины до 24Mhz или 48Mhz, оставляя I2C0 SCL=100KHz, то опять адрес устройства не подтверждается.
Может кто нибудь объяснить в чем проблема и почему несмотря на одинаковое значение SCL=100KHz, работа I2C зависит от скорости переферийной шины?
Спасибо
|
|
|
|
|
Nov 10 2008, 08:36
|
Участник

Группа: Свой
Сообщений: 55
Регистрация: 6-04-06
Из: Москва, Зеленоград
Пользователь №: 15 863

|
Возьми осцил и погляди, что творится на SCL, ты должен все увидеть сам. Сейчас работаю с 2368 и I2C2 с внутренней подтяжкой. Там спады получаются нормальные, а фронты едва-едва вытягивают на 100кГц. Еще внимательно проверь делители и задатчик частоты SCL, а то у тебя делилка PCLK то 2, то 4.
Сообщение отредактировал zltigo - Nov 10 2008, 10:06
|
|
|
|
|
Nov 10 2008, 12:45
|
Группа: Новичок
Сообщений: 5
Регистрация: 9-11-08
Пользователь №: 41 499

|
Цитата(SeregaB @ Nov 10 2008, 19:36)  Возьми осцил и погляди, что творится на SCL, ты должен все увидеть сам. Сейчас работаю с 2368 и I2C2 с внутренней подтяжкой. Там спады получаются нормальные, а фронты едва-едва вытягивают на 100кГц. Еще внимательно проверь делители и задатчик частоты SCL, а то у тебя делилка PCLK то 2, то 4. осцилографа у меня нет, к сожалению. За делителем я слежу, всегда частота SCL настроена на 100кГц. Похоже, что переферийная шина как-то вляет на передачу I2C, если частота <12MHz (проверено для 3, 6, 12MHz), то все работает нормально, если частота выше (24, 30, 48, 60 Mhz) - присутствие слейв устройство не определяется на шине. Попробовал тот же I2C код с флешкой 24LC32A, SCL=100KHz, PCLK=30MHz - все работает ОК.
|
|
|
|
|
Nov 10 2008, 13:04
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(DrGolem @ Nov 10 2008, 15:45)  За делителем я слежу, всегда частота SCL настроена на 100кГц. А что значит "всегда настроена"? Несколько раз уже употребляете сие выражение. Вы меняете значения SCLH и SCLL в зависимости от частоты переферийной шины? Код какой? Код I2SCLH = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // Set bit rate (half period) I2SCLL = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // Цитата Похоже, что переферийная шина как-то вляет на передачу I2C Самым непосредственным образом - из частоты переферийной шины формируются длительности I2C
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 10 2008, 20:22
|
Группа: Новичок
Сообщений: 5
Регистрация: 9-11-08
Пользователь №: 41 499

|
Цитата(zltigo @ Nov 11 2008, 00:04)  А что значит "всегда настроена"? Несколько раз уже употребляете сие выражение. Вы меняете значения SCLH и SCLL в зависимости от частоты переферийной шины? Код какой? Код I2SCLH = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // Set bit rate (half period) I2SCLL = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // Самым непосредственным образом - из частоты переферийной шины формируются длительности I2C совершенно точно - если я меняю частоту периферии, то всегда меняю значение делителей I2C ( I2C0SCLH + I2C0SCLL = PCLK / I2C_SCL, где PCLK частота переферийной шины, а I2C_SCL частота шины I2C). Вот это меня и смущает - скорость I2C не меняется, меняется только скорость переферийной шины и это сильно влияет на общение со слейв устройствами. Нигде в документации я этого не встречал. Продолжил свои эксперименты с различными чипами i2c, вот результаты микроконтроллер LPC2148 CCLK = 48MHz чип часов реального времени PCF8583 - I2C работает на частоте периферии до 12МГц (включительно) CCLK = 60MHz чип расширения I/O pcf8574a - I2C работает на частоте периферии до 15МГц (включительно) чип флеш памяти 24lc32a - I2C работает на частоте периферии до 30МГц (включительно) может кому-нибудь эта информация будет интересна...
|
|
|
|
|
Nov 10 2008, 23:05
|
Группа: Новичок
Сообщений: 5
Регистрация: 9-11-08
Пользователь №: 41 499

|
Цитата(zltigo @ Nov 11 2008, 08:33)  Думаю, что у Вас банальные ошибки в определении констант и переполнение при последующем вычислении результата препроцессором или подобные ляпы, ибо все нормально настраивается и работает ВНЕ зависимости от частоты периферийной шины. Без вариантов. да я и надеюсь, что это мои ошибки и отсутствие опыта. Раз уж Вы тратите время на мои вопросы, не могли бы Вы взглянуть на код, может сразу подскажите где проблема. Полный код - в приложении к сообщению. ... ставим частоту процессора в 48MHz, переферия - 12MHz setup_pll(clk_48MHz, PCCLK_ONE_FOURTH); инициализация I2C, I20SCLH + I20SCLL = 120 : 12Mhz / 100KHz = 120 i2c_MasterInit(120); ищем адрес какого-нибудь чипа на шине I2C если чип подтвердил свой адрес, на выходе функции будет этот адрес, либо 0, если никто не отозвался addr = i2c_Discovery(); Спасибо
|
|
|
|
|
Nov 11 2008, 05:45
|
Группа: Новичок
Сообщений: 5
Регистрация: 9-11-08
Пользователь №: 41 499

|
Цитата(zltigo @ Nov 11 2008, 08:33)  Думаю, что у Вас банальные ошибки в определении констант и переполнение при последующем вычислении результата препроцессором или подобные ляпы, ибо все нормально настраивается и работает ВНЕ зависимости от частоты периферийной шины. Без вариантов. Ваш вердикт верен - похоже действительно банальные ошибки. Внимательно прочитал юзер мануал и понял, что хоть я и задаю верное значение суммы I2CSCLH + I2CSCLL, я не обращаю внимание на то, что же такое эти I2CSCLH, I2CSCLL. А это: I2SCLH defines the number of PCLK cycles for the SCL high time, I2SCLL defines the number of PCLK cycles for the SCL low time в моих примерах I2CSCLH = 0x08, изменяется только I2CSCLL. Для низких частот все работает, а когда частота переферийной шины растет, то растет и сумма (I2CSCLH + I2CSCLL), соответственно SCL все больше времени проводит в низком уровне и слейв устройство не может узнать свой адрес на шине. Приду домой, проверю правильно ли это предположение. UPDATE: хм, прошу извинить меня за тупость - оказывается zltigo с самого начала говорил мне про это: I2SCLH = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // Set bit rate (half period) I2SCLL = ((configCPU_CLOCK_HZ/configBUS_DIVIDER)/I2C_CLOCK_HZ)/2; // а я пока сам головой не пробил стену, распахнутой рядом двери и не увидел  ((
Сообщение отредактировал DrGolem - Nov 11 2008, 06:10
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|