реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> LPC2148 + I2C, скорость переферийной шины
DrGolem
сообщение Nov 10 2008, 00:11
Сообщение #1





Группа: Новичок
Сообщений: 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 зависит от скорости переферийной шины?

Спасибо
Go to the top of the page
 
+Quote Post
SeregaB
сообщение Nov 10 2008, 08:36
Сообщение #2


Участник
*

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



Возьми осцил и погляди, что творится на SCL, ты должен все увидеть сам. Сейчас работаю с 2368 и I2C2 с внутренней подтяжкой. Там спады получаются нормальные, а фронты едва-едва вытягивают на 100кГц.
Еще внимательно проверь делители и задатчик частоты SCL, а то у тебя делилка PCLK то 2, то 4.

Сообщение отредактировал zltigo - Nov 10 2008, 10:06
Go to the top of the page
 
+Quote Post
DrGolem
сообщение Nov 10 2008, 12:45
Сообщение #3





Группа: Новичок
Сообщений: 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 - все работает ОК.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 10 2008, 13:04
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
DrGolem
сообщение Nov 10 2008, 20:22
Сообщение #5





Группа: Новичок
Сообщений: 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МГц (включительно)

может кому-нибудь эта информация будет интересна...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 10 2008, 21:33
Сообщение #6


Гуру
******

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



Цитата(DrGolem @ Nov 10 2008, 23:22) *
может кому-нибудь эта информация будет интересна...

Думаю, что у Вас банальные ошибки в определении констант и переполнение при последующем вычислении результата препроцессором или подобные ляпы, ибо все нормально настраивается и работает ВНЕ зависимости от частоты периферийной шины. Без вариантов.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
DrGolem
сообщение Nov 10 2008, 23:05
Сообщение #7





Группа: Новичок
Сообщений: 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();

Спасибо
Прикрепленные файлы
Прикрепленный файл  test_i2c.zip ( 7.86 килобайт ) Кол-во скачиваний: 28
 
Go to the top of the page
 
+Quote Post
DrGolem
сообщение Nov 11 2008, 05:45
Сообщение #8





Группа: Новичок
Сообщений: 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; //
а я пока сам головой не пробил стену, распахнутой рядом двери и не увидел sad.gif((

Сообщение отредактировал DrGolem - Nov 11 2008, 06:10
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01447 секунд с 7
ELECTRONIX ©2004-2016