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

 
 
 
Reply to this topicStart new topic
> Tактирование I2C
pashevich
сообщение May 26 2006, 10:32
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 26-05-06
Пользователь №: 17 471



Не могу подключить индикатор через I2C. Скорее всего, проблемы с тактированием CLK. Для шины нужно 100 или 400 кГц. МК по умолчанию должен работать от SMCLK на 1 МГц. Но реально осциллограф показывает 715 кГц, а CLK на шине без использования прескалера 12.5 кГц.
Почему так получается, ведь I2C тоже тактируется от SMCLK?
Читал где-то, что необходима задержка для установления частоты тактирования.. может из-за ее отсутствия?
Go to the top of the page
 
+Quote Post
rezident
сообщение May 26 2006, 10:44
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



По поводу инициализации системы тактирования с внешним кварцем см. соответствующую главу в User's Manual. Или вот в переводе. Алгоритм указан в пункте Использование кварцевого резонатора для формирования MCLK .
Go to the top of the page
 
+Quote Post
pashevich
сообщение May 26 2006, 11:20
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 26-05-06
Пользователь №: 17 471



Спасибо, но я без внешнего кварца тактируюсь! smile.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение May 26 2006, 11:30
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



В таком случае приложите кусок кода инициализации периферии и воспользуйтесь поиском по форуму. Вот вроде схожая тема.
Go to the top of the page
 
+Quote Post
pashevich
сообщение May 26 2006, 16:10
Сообщение #5





Группа: Новичок
Сообщений: 6
Регистрация: 26-05-06
Пользователь №: 17 471



Да, тема схожая, но там нет ключевого момента:

С частотой вроде разобрался.
Нужно было включить знаменитую задержку (см. FAQ) при включении, до переключения на тактирование от кварца.


Где и в каком ФАКе это искать?

Вот код инициализации модуля тактирования (эти значения и так по умолчанию):

BCSCTL1 |= XT2OFF + RSEL2;
DCOCTL |= DCO0 + DCO1; // частота тактирования 1 МГц
BCSCTL2 = 0x00;
P5SEL = 0x20; //SMCLK на вывод P5.0 - наблюдаем ~715 кГц
Go to the top of the page
 
+Quote Post
pashevich
сообщение May 27 2006, 12:34
Сообщение #6





Группа: Новичок
Сообщений: 6
Регистрация: 26-05-06
Пользователь №: 17 471



Подобрал частоту:

BCSCTL1 |= XT2OFF + RSEL2 + RSEL1 ;
DCOCTL |= DCO0 + DCO1; // частота тактирования ... МГц
BCSCTL2 = 0x00;
P5SEL = 0x20; //SMCLK на вывод P5.0 - наблюдаем ~1 MГц

Инициализация I2C:

U0CTL |= I2C + SYNC; // режим I2C
U0CTL &= ~I2CEN; // начало инициализации порта
I2CSA = 0x78; // адрес LCD
U0CTL |= MST; // режим ведущего
I2CTCTL = I2CSSEL_2; // тактирование I2C от SMCLK
I2CPSC = 0x01; // по теории деление MSCLK на 2 - получается около 100 кГц
I2CTCTL |= I2CTRX + I2CRM; // ПО устанавливает "старт" и "стоп"
U0CTL |= I2CEN; // разрешение работы порта в режиме I2C

Далее посылаем старт-адрес ведомого-стоп и не получаем ASK (выставляется флаг NASK)...
т.е. всё-равно ведущий молчит, может он вообще не рабочий? smile.gif
Go to the top of the page
 
+Quote Post
Slonic
сообщение May 30 2006, 11:22
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 3-10-05
Из: Москва-Троицк
Пользователь №: 9 174



Говоря о задержке тактирования, я имел в виду, конечно, работу от внешнего кварца. При работе от DCO никаких задержек не нужно, он начинает работать сразу.

Что касается отправки данных по I2C. Наличие ACK желательно контролировать осциллографом непосредственно на шине. Записывать данные в регистр I2CDRB нужно после того, как инициирована передача, для меня это оказалось нетривиальным моментом.

Привожу код, который в итоге заработал:

signed char i2c_n, i2c_tx_n;
unsigned char i2c_buf[10];

void init_i2c(void)
{
P3SEL |= 0x0a; // Assign I2C pins to module
U0CTL |= I2C + SYNC; // Switch USART0 to I2C mode
U0CTL &= ~I2CEN; // Recommended I2C init procedure
I2CTCTL = I2CSSEL_1; // ACLK
I2CPSC = 0x00; // I2C prescaler
I2CSCLH = 0x07; // High period of SCL
I2CSCLL = 0x07; // Low period of SCL // 6000 / 16 = 375khz
I2CIE = RXRDYIE + NACKIE;
U0CTL |= I2CEN; // Enable I2C, 7 bit addr,
_EINT(); // Enable interrupts
}

void i2c_sendbyte(unsigned char SlaveAddress, unsigned char Value, unsigned char Stop)
{
I2CSA = THERM0_SA;
I2CNDAT = 0x01;
i2c_tx_n = 0;
U0CTL |= MST;

i2c_buf[0] = Value;

I2CIFG &= ~TXRDYIFG;
I2CIFG &= ~ARDYIFG;
I2CIE = TXRDYIE;
if(Stop)
I2CTCTL |= I2CTRX + I2CSTT + I2CSTP;
else
I2CTCTL |= I2CTRX + I2CSTT;
while ((~I2CIFG) & ARDYIFG);
}

#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void)
{
switch(I2CIV)
{
case 0: break; // No interrupt
case 2: break; // Arbitration lost
case 4: // No Acknowledge
uart1_putchar('X');
break;
case 6: break; // Own Address
case 8: break; // Register Access Ready
case 10: // Receive Ready
if(i2c_n < 10)
i2c_buf[i2c_n] = I2CDRB;
i2c_n++;
break;
case 12:
I2CDRB = i2c_buf[i2c_tx_n];
i2c_tx_n = i2c_tx_n-1;
if(i2c_tx_n < 0)
I2CIE &= ~TXRDYIE; // disable interrupts
break; // Transmit Ready
case 14: break; // General Call
case 16: break; // Start Condition
}
}
Go to the top of the page
 
+Quote Post
pashevich
сообщение May 31 2006, 12:21
Сообщение #8





Группа: Новичок
Сообщений: 6
Регистрация: 26-05-06
Пользователь №: 17 471



Спасибо большое!
Я уже тоде нашел работающий вариант! в другом форуме smile.gif
исходник здесь
Go to the top of the page
 
+Quote Post

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

 


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


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