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

Stm32F103C8+Soft_I2C = Ds1307


den2life

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

Здравствуйте форумчане.

МК - stm32f103c8t6

RTC - ds1307

Прошу Помочь мне в интерфейсе i2c. Написал программный i2c, так как в старых версиях данного МК аппаратный i2c не работает (или не хочет работать).

Выдаю Вам осциллограмму. Если что еще что то(схема, код) нужно для устранения проблемы прошу требуйте выложу.

подтяжки 1k8 ставил в начале 4k8, проблема не решилась.

Ds1307 не реагирует на команду. то есть конфигурирую его вывод sqw на генерацию 1Гц. Pullupы все необходимые имеются, то есть на SCL, SDA, SQW/OUT.

А на диаграмме вроде подтверждает или что это? ACK? если убрать ds1307 от выводов то 9 бит ставиться как надо - лог1.

Частота SCL примерно 50-70 кГц (осциллограф показывает)

SDA SCL - GPIOB - Output Open-Drain, 2MHz

1 байт - 0xD0

2 байт - 0x07

3 байт - 0x10

post-144830-0-29496000-1384918075_thumb.png

post-144830-0-65590900-1384918286_thumb.png

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

uint16_t flag_error_slave_ack = 0;  //Флаг ошибки подтверждения ведомым

uint8_t soft_i2c_write (uint8_t slave_add, uint8_t rw, uint8_t add_reg, uint8_t data)
{

 static uint8_t first_bit = 0;
 uint8_t count = 0;
 uint16_t clk =1;
 uint8_t ack = 0;

#ifdef SDA_LSB_FIRST
 first_bit = 0x01;
#define  SDA_SHIFT SDA_SHIFT_RIGHT(slave_add);
#else 
 first_bit = 0x80;
#define SDA_SHIFT SDA_SHIFT_LEFT(slave_add);
#endif

   SDA_LOW;  //GENERATION START BIT
   Delay_us(5); //Thd.sta


   for (clk = 1; clk < 11; clk++)
   {  

     if(clk<=9)
     {
               SCL_LOW;
               Delay_us(1);  //Thigh
               if (((slave_add|rw)&first_bit)||(clk==9) )
               {SDA_DATA_LOG1;
               if((!SDA_ACK_SLAVE)&&(clk == 9)) {ack = 1;}               

               }
               else              
               { SDA_DATA_LOG0;}

               SDA_SHIFT;
               Delay_us(1);

               SCL_HIGH;

               Delay_us(5);  //Tlow
            if (clk == 9)
             {SCL_LOW;
             SDA_DATA_LOG0;}
     }    

     else{

           clk = 0;
           if (++count == 1)           //такты для передачи 3 байт
               slave_add = add_reg;   //ПРИСВОЕНИЕ №2
           else if (count == 2)
               slave_add = data;       //ПРИСВОЕНИЕ №3
           else
           {
              clk = 12; 
              count = 0;
           }
         }

   }
               Delay_us(4);
               SCL_HIGH;
               Delay_us(4);
               SDA_HIGH;   //GENERATION STOP BIT

               if (ack) return ack;
               else return 0;
}

код написал сам, в спешке :crazy:

Тут передача сразу 3 байт информации, СТАРТ и СТОП сразу включены в функцию, они не генерируются пока из цикла не выйдет, то есть пока не передаст все 3 байта.

Описание функции soft_i2c_write: СТАРТ->ПЕРЕДАЧА 9бит=DATA+ACK->ПРИСВОЕНИЕ №2 СЛЕД-ИХ 8БИТ->ПЕРЕДАЧА 9бит=DATA+ACK->ПРИСВОЕНИЕ №3 СЛЕД-ИХ 8БИТ->ПЕРЕДАЧА 9бит=DATA+ACK->СТОП

Это в headere:

Макрос SDA_LSB_FIRST задефанен -

//#define SDA_LSB_FIRST

Еще:

#define SDA_ACK_SLAVE (GPIO_SOFT_I2C->IDR &(1<<SDA_SOFT_I2C))
#define SDA_SHIFT_LEFT(DATA) (DATA <<= 1)
#define SDA_SHIFT_RIGHT(DATA) (DATA >>= 1)

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Скорее всего Вам это тоже пригодится для оказания помощи:

Это в хеадер:

#define GPIO_SOFT_I2C GPIOB

#define SDA_SOFT_I2C 11
#define SCL_SOFT_I2C 10

#define SDA_LOW  (GPIO_SOFT_I2C->BRR |= (1<<SDA_SOFT_I2C))
#define SDA_HIGH (GPIO_SOFT_I2C->BSRR |= (1<<SDA_SOFT_I2C))


#define SCL_HIGH (GPIO_SOFT_I2C->BSRR |= (1<<SCL_SOFT_I2C))
#define SCL_LOW  (GPIO_SOFT_I2C->BRR |= (1<<SCL_SOFT_I2C))


#define SDA_DATA_LOG1 (GPIO_SOFT_I2C->ODR |= (1<<SDA_SOFT_I2C))
#define SDA_DATA_LOG0 (GPIO_SOFT_I2C->ODR &= ~(1<<SDA_SOFT_I2C))


#define SCL_DATA_LOG1 (GPIO_SOFT_I2C->ODR |= (1<<SCL_SOFT_I2C))
#define SCL_DATA_LOG0 (GPIO_SOFT_I2C->ODR &= ~(1<<SCL_SOFT_I2C))

Ядро работает на частоте 8МГц (HSI) через PLL. То есть как понимаете CLK/2*PLL*2 = PCLK, делители на шинах не ставил.

Спрашивайте что нужно еще.

func main:

int main()
{
 InitCpuClk();

Delay_us(100000);
init_soft_i2c();

  while(1)
  {
    Delay_us(1050000);
       init_ds1307(0,1,0);


  }

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

Вообщем (так как я тему оформил не очень - не читабельно (редко общаюсь на форумах)) прошу можете прокомментировать осциллогамму I2C, сверьте со своей рабочей передачей. Если есть знатоки данного интерфейса, прошу поставить диагноз диаграммы и т.д. Не стоит смотреть на страшное оформление, знатокам достаточно посмотреть на осциллограмму:

1) что это за 9 бит?

2) какой он должен быть?

3) ACK должен быть вместе с 9 тактом или чуть позже(раньше)

ПОСТАВЬТЕ ДИАГНОЗ!

А дальше код я сам напишу. Главное Ваш опыт в данной проблеме и всё.

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

Активным уровнем для АСК бита является низкий. Формируется он во время 9-го тактового импульса.

Сам же АСК формируется DS1307, для подтверждения получения данных. Камень не должен формировать АСК бит, он его только принимает

Как я понял, в вашем случае АСК формируется МК.

Попробуйте убрать его из отправляемых МК сообщений и проверьте результат. Все должно заработать.

Камень должен формировать АСК только тогда, когда он принимает данные, а не когда передает.

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

Убрал девятый бит, но теперь выскакивает SDA сразу же после 9 такта

КОД тоже пришлось заменить полностью:

 uint8_t ack = 0;
void soft_i2c_start(void)
{

 SDA_LOW;  //GENERATION START BIT
 Delay_us(10); //Thd.sta
 SCL_LOW;
 Delay_us(10); //Thd.sta
}

void soft_i2c_stop(void)
{
 SDA_DATA_LOG0;
 Delay_us(2);
 SCL_HIGH;
 Delay_us(6);
 SDA_DATA_LOG1;

}
uint8_t soft_i2c_write (uint8_t data)
{

 uint8_t first_bit = 0;

 #ifdef SDA_LSB_FIRST
 first_bit = 0x01;
#define  SDA_SHIFT SDA_SHIFT_RIGHT(data);
#else 
 first_bit = 0x80;
#define SDA_SHIFT SDA_SHIFT_LEFT(data);
#endif

   for (uint8_t clk = 0; clk < 8; clk++)
   {
         //Delay_us(1);
         if ((data)&first_bit)
         {SDA_DATA_LOG1;}
         else              
         {SDA_DATA_LOG0;}


     SCL_HIGH;
     Delay_us(10);
     SDA_SHIFT;
     SCL_LOW;
     Delay_us(2);
   }
   SDA_HIGH;
   SCL_HIGH;
    Delay_us(9);  
    ack = SDA_ACK_SLAVE; //Подтверждение
    SCL_LOW;

 return ack;
}

Повторюсь, режим GPIO SDA SCL ОТКРЫТЫЙ СТОК!

Может дело в конфигурации портов, Выводы портов SDA SCL ставить на Open-drain? Или pulldown?

цикл в main

Delay_us(150000);
 soft_i2c_start();
 soft_i2c_write((uint8_t)0xd0);
  soft_i2c_write((uint8_t)0x07);
soft_i2c_write((uint8_t)0x10);
  soft_i2c_stop();

SDA видимо от slave получаю. В программе я не формирую данный бит, формирую только сразу же после 8 бита, то есть во время 9 бита. Это значит NACK от слэйва идет?

post-144830-0-14429700-1385003511_thumb.png

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

Проблема решилась, это ACK :crazy:

Но теперь проблема в том, что, почему, то не генерируется 1Гц на выходе Ds1307. но работает просто OUT,(как порт), поставив:

soft_i2c_start();
soft_i2c_write((uint8_t)0xd0);
soft_i2c_write((uint8_t)0x07);
soft_i2c_write((uint8_t)0x80);   //Pin SQW/OUT лог1
soft_i2c_stop();

или в цикле:

delay_us(100000);
soft_i2c_start();
soft_i2c_write((uint8_t)0xd0);
soft_i2c_write((uint8_t)0x07);
soft_i2c_write((uint8_t)0x80);  //Pin SQW/OUT лог1
soft_i2c_stop();
delay_us(100000);

soft_i2c_start();
soft_i2c_write((uint8_t)0xd0);
soft_i2c_write((uint8_t)0x07);
soft_i2c_write((uint8_t)0x00);//Pin SQW/OUT лог0
soft_i2c_stop();

а записав код для генерации 1 ГЦ в main(не в цикле):

soft_i2c_start();
soft_i2c_write((uint8_t)0xd0);
soft_i2c_write((uint8_t)0x07);
soft_i2c_write((uint8_t)0x10);   //Pin SQW/OUT 1Hz
soft_i2c_stop();

их нет, генерации нет. вечный лог. 0

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

Попробуйте после записи значения в регистр ds'ки прочитать то, что туда записалось.

Если запись происходит корректно, то есть всего две возможных причины неработоспособности:

1. 1307 частично нерабочая.

2. Для начала генерации есть еще дополнительные условия. Посмотрите в даташите.

И я все же советовал бы использовать аппаратный I2C.

I/О порты конфигурируются как открытый сток.

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

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

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