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

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 пользователей онлайн

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

    • Какова площадь поверхности данного радиатора?
    • @Богдан Назаренко , 4558 и 5532 на слух не отличить. Да и параметры у них практически одиннаковые. Мне показалось TL072 звучит хуже.
    • @maxim1881  Какой курс  студент ?  Прочитать схему  то умеешь ? И где - то к этой схеме есть описание  ...  Так вот по описанию и можно сделать то что  требуется ...  Я лично  два года учился , пока пришло просветение чтения схем  И так подтолкну  один блок тебе :  DD1.5 , DD1.6 , R9 C5 - генератор ... И так  далее ... Кароче  шукай  описание  в журналах на данную схему и все получится     Датчик пересечения ИК-луча Другая сфера применения аналоговых усилителей на основе микросхемы 4069 - инфракрасный датчик или фотоприемник инфракрасного сигнала. На рисунке 7 показана схема успешно эксплуатируемого уже несколько лет датчика, реагирующего на пересечение либо отражение инфракрасного луча. Интересно то, что в схеме нет широко используемых в таких случаях готовых интегральных фотоприемников. Сигнал принимается обычным ИК-фотодиодом, а усиление производится усилительными каскадами, выполненными на основе инверторов микросхемы 4069. Наличие шести инверторов в одном корпусе микросхемы 4069 позволяет весь датчик, как его приемную, так и передающую части выполнить на одной микросхеме 4069. И так, схема показана на рис. 7. Как обычно, ИК-датчик работающий на отражение или пересечение луча состоит из передатчика ИК-луча и его приемника. Передатчик ИК-луча состоит из ИК-светодиода HL1 (здесь светодиод, такой как в пультах ДУ аппаратуры), токового ключа на транзисторах VТ1 и VТ2 и генератора импульсов частотой около 8-10 kHz. Импульсы с выхода мультивибратора на элементах D1.5 и D1.6 поступают через токовый ключ на VT1 и VT2 на ИК-светодиод HL1. Резистор R11 ограничивает ток через светодиод. HL1 излучает ИК вспышки, следующие с частотой 8-10 kHz. Если существует видимость между HL1 и FH1, излученные вспышки воздействуют на фотодиод FH1 ив нем возникают импульсы тока. Благодаря резистору R1 они преобразуются в импульсы напряжения. Переменное напряжение через конденсатор С1 поступает на первый усилитель на элементе D1.1. Его в усилительный режим переводит резистор R2. Далее, через С2 усиленное переменное напряжение поступает на усилитель на D1.2. В цепи ООС D1.2 есть резистор R3, который смещает его вход в сторону напряжения логической единицы. В результате его выход смещен в сторону логического нуля. Поэтому, в отсутствие входного сигнала напряжение на С3 соответствует логическому нулю. Но при наличии входного сигнала за счет работы детектора на VD1 напряжение на С3 увеличивается до логической единицы. Выходные импульсы формирует триггер Шмитта на элементах D1.3 и D1.4. Фотодиод РН302 можно заменить любым ИК-фотодиодом. Налаживание датчика сводится к подбору сопротивления R3, чтобы при отсутствии сигнала на выходе D1.4 был ноль, а при наличии сигнала - единица. Везде вместо микросхемы 4069 можно попробовать микросхему К561ЛН2. Тюльгин Ю.М. РК-2016-03.  
    • Ух... добавили вы мне оптимизма... Никогда б не подумал что  на такой мелочёвки жулики так заморочились.. Ну как сказать... В своё время я зарабатывал на ремонте 3УСЦТ и старше (само собой и смежной технике). Потом несколько лет ремонт связной спецтехники (основная задача - настройка-обслуживание, а ремонты - то по необходимости). Но последние лет 20 паяльник используется редко и то в основном для пайки проводов-разъёмов и разной мелочёвки.
    • 4558 неплохая микросхема, особо не отличается от 5532, и наушники потянет, если у вас нет завышенных требований.
  • Похожий контент

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