Перейти к содержанию

Помогите перейти на аппаратный TWI


Гость химик

Рекомендуемые сообщения

Я так понимаю, на I2C в твоей реализации сидят 2 слейва - RTC и еще что-то? Конечно, их обоих можно дергать по аппаратной реализации TWI, повесив параллельно на аппаратные выводы SDA и SCL. Надо выбрать частоту шины, поддерживаемую обоими девайсами, и убедиться, что у них разные адреса на шине.

Управление аппаратной реализацией очень подробно описано в даташитах на МК.

 

Добавлено после раздумий:

Посмотрел исходники из первого поста - там нет i2c.h. Судя по скриншоту из последнего поста, это программная реализация I2C, и её надо удалить из проекта.

Из первого поста:

My_I2C.h - тоже программная реализация.

twi.h - аппаратная реализация, лучше использовать её.

Н а i2c у меня сидят 4 слейва. И как я уже писал у меня была проблема, зависание МК. Проблему я нашел в работе шины. А сейчас,как мне кажется проблема найдена в лице DS1307. Она у меня опрашивается в цикле main();, и кажется сбивает шину.

 

Насчет my_i2c.h, так это я ж писал, что пробывал несколько разных библиотек twi, в том числе и i2c, поетому по запарке скинул не тот файл о котором писал.

 

Ниже файл с библиотеками twi и ds1307_twi, там же и хидеры. Для компиляции их нужно поместить в папки программы cvavr inc и lib соответственно. В папке RTC файлы проекта и эмуляции Proteus v7.7. Сейчас компилится нормально, но в Proteus не работает. Получается так, что при запуске эмуляции шина работает 1сек. После обе линии утанавливаются либо в высокий, либо в низкий логический уровень и не с места. Что-то такое я читал про аппаратный twi, что если выскакивает ошибка, появляется бит NACK и вешает шину. Извиняюсь если не правильно высказался.

RTC.rar

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 29
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Увы, никогда не работал в CVAVR, использую IAR, поэтому нюансы, связанные со средой разработки мне недоступны.

 

В ds137_twi.h подключается некий i2c.h, вместо него видимо должен быть twi.h?

RTC имеет адреса на запись/чтение 0xD0/0xD1 соотв. Не совпадают ли эти адреса с адресами других устройств на шине?

Еще как вариант - какие-нибудь проблемы с таймерами или прерываниями, вдруг они вмешиваются в работу шины. Как-то подозрительно, что шина виснет спустя целую секунду. Хотя вроде бы на PC0 и PC1 висят только TWI и сам порт...

Может, попробовать физически отключить от шины все устройства, и затем подключать их по очереди, добиваясь работоспособности поэтапно?

 

Сам когда-то писал работу через аппаратный TWI с RTC PCF8563 и еще одним МК в качестве слейвов, никаких проблем не возникало... Попробую завтра с работы выложить свою библиотеку TWI, если найду.

Изменено пользователем mczarin
Ссылка на комментарий
Поделиться на другие сайты

Вот самая простаря реализация аппаратного i2c

// TWI init

TWBR=0x02;
TWCR=1<<TWEN;

// TWI start
TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write / write addr
TWDR = TMP275_adr;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI read byte
TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};
temp=TWDR;

// TWI stop   
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);

 

Смотрим либу цавра ds1307:

 

void rtc_init(unsigned char rs,unsigned char sqwe,unsigned char out)
{
rs&=3;
if (sqwe) rs|=0x10;
if (out) rs|=0x80;
i2c_start();
i2c_write(0xd0);
i2c_write(7);
i2c_write(rs);
i2c_stop();
}

void rtc_get_time(unsigned char *hour,unsigned char *min,unsigned char *sec)
{
i2c_start();
i2c_write(0xd0);
i2c_write(0);
i2c_start();
i2c_write(0xd1);
*sec=bcd2bin(i2c_read(1));
*min=bcd2bin(i2c_read(1));
*hour=bcd2bin(i2c_read(0));
i2c_stop();
}

void rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec)
{
i2c_start();
i2c_write(0xd0);
i2c_write(0);
i2c_write(bin2bcd(sec));
i2c_write(bin2bcd(min));
i2c_write(bin2bcd(hour));
i2c_stop();
}

void rtc_get_date(unsigned char *date,unsigned char *month,unsigned char *year)
{
i2c_start();
i2c_write(0xd0);
i2c_write(4);
i2c_start();
i2c_write(0xd1);
*date=bcd2bin(i2c_read(1));
*month=bcd2bin(i2c_read(1));
*year=bcd2bin(i2c_read(0));
i2c_stop();
}

void rtc_set_date(unsigned char date,unsigned char month,unsigned char year)
{
i2c_start();
i2c_write(0xd0);
i2c_write(4);
i2c_write(bin2bcd(date));
i2c_write(bin2bcd(month));
i2c_write(bin2bcd(year));
i2c_stop();
}

 

И начинаем ее методично переписывать под себя:smile: (приведу пример для одной из ф-ций)

 

void rtc_set_date(unsigned char date,unsigned char month,unsigned char year) {

// TWI start
TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write addr
TWDR = 0xD0;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write
TWDR = 4;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write
TWDR = bin2bcd(date);
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write
TWDR = bin2bcd(month);
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI write
TWDR = bin2bcd(year);
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};

// TWI stop   
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

 

Думаю остальное сами допишите :smile:

Изменено пользователем torip3ng
Ссылка на комментарий
Поделиться на другие сайты

А еще вот такое

data=twi_read(0);

//TWI Read byte
TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) {};
data=TWDR;

 

twi_read(0) - 0 означает что мы читаем последний байт с устройства.

Изменено пользователем torip3ng
Ссылка на комментарий
Поделиться на другие сайты

Переписал библиотеку, запускаю симуляцию покадрово.

post-2789-1321453644_thumb.jpg

Пачка из четырех байт, видимо инициализация часов.

post-2789-1321453657_thumb.jpg

Через 0,24сек пошла вторая пачка из 7 байт. И вот здесь видно что условие стоп не появляется, на линии SDA логический 0!

Хотя напряжение на нем изменяется пилообразно от 0 до 1 вольта. И дальше,

post-2789-1321453672_thumb.jpg

такая "пила" пробегает с интервалом около 0,9сек, появляется и исчезает.

 

Вывод: что то не дает появится условию Stop. Что именно?

Последнее обновление файлов:RTC.rar

Ссылка на комментарий
Поделиться на другие сайты

Повторюсь, надо вводить сущности постепенно. Иначе искать можно очень долго.

Попробуй сначала вообще чистый проект с подключенной библиотекой TWI, который опрашивает RTC в бесконечном цикле (без таймеров, LCD и т.д.). Соотв. в эмуляторе убери из схемы вообще всё, кроме МК и RTC.

Ссылка на комментарий
Поделиться на другие сайты

из rtc.c убрать

#asm
  .equ __i2c_port=0x15;PORTC
  .equ __sda_bit=1
  .equ __scl_bit=0	
#endasm

 

из ds1307_twi убрать

#include <twi.h>

 if(PIND.6 == 0){
  tmp=bin2bcd (hour);
  tmp++;
  if(tmp >= 36) tmp=0;						 // oгpaничeниe peгyлиpoвки чacoв
  hour=bcd2bin (tmp);
  rtc_set_time(hour,min,sec);				  // yвeличивaeм знaчeниe чacoв

 

надо так

 

 if(PIND.6 == 0){
  tmp=hour;
  tmp++;
  if(tmp >= 24) tmp=0;						 // oгpaничeниe peгyлиpoвки чacoв
  hour=tmp;
  rtc_set_time(hour,min,sec);				  // yвeличивaeм знaчeниe чacoв

в rtc_set_time уже выполняется bcd2bin

Ссылка на комментарий
Поделиться на другие сайты

...

надо так

 

 if(PIND.6 == 0){
  tmp=hour;
  tmp++;
  if(tmp >= 24) tmp=0;						 // oгpaничeниe peгyлиpoвки чacoв
  hour=tmp;
  rtc_set_time(hour,min,sec);				  // yвeличивaeм знaчeниe чacoв

в rtc_set_time уже выполняется bcd2bin

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

 

Вобщем зависает шина в функции rtc_get_time

post-2789-1321549734_thumb.jpg

в строке где должен формироваться импульс Stop, отладка переступает эту строку и на осцилографе видно, что этого условия не произошло. Далее при следующей попытке запустить условие Start, программа зависает на строке

post-2789-1321549749_thumb.jpg

 

Почему не состоялось условие Stop?

Ссылка на комментарий
Поделиться на другие сайты

После

// TWI stop  
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);

поставь

while (!(TWCR & (1<<TWINT))) {};

и сообщи об результатах :smile:

может принудительная отправка NACK нужна протеусу.

Изменено пользователем torip3ng
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...