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

Работа с DS1307


-=FISHER=-

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

Здравствуйте!

 

Для работы с DS1307 я использовал следующую библиотеку I2C:

Скрытый текст

#include "twi.h"

void I2C_Init(void)
{
	TWBR=0x20; //скорость передачи (при 8 мГц получается 100 кГц)
}

void I2C_StartCondition(void)
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN
}

void I2C_StopCondition(void)
{
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}

void I2C_SendByte(unsigned char c)
{
	TWDR=c;//запишем байт в регистр данных
	TWCR = (1<<TWINT)|(1<<TWEN);//включим передачу данных
	while(!(TWCR&(1<<TWINT)));//подождем пока установится TWIN	
}

 

Я уже научился настраивать время в DS1307 программно. Делал я это следующим образом:

Скрытый текст

	I2C_Init();
	
	//Устанавливаем время
 	I2C_StartCondition();
 	I2C_SendByte(0b11010000);
 	I2C_SendByte(0);//Переходим на 0x00
 	I2C_SendByte(RTC_ConvertFromBinDec(0)); //секунды
 	I2C_SendByte(RTC_ConvertFromBinDec(31)); //минуты
 	I2C_SendByte(RTC_ConvertFromBinDec(20)); //часы
 	I2C_SendByte(RTC_ConvertFromBinDec(5)); //день недели
 	I2C_SendByte(RTC_ConvertFromBinDec(29)); //дата
 	I2C_SendByte(RTC_ConvertFromBinDec(1)); //месяц
 	I2C_SendByte(RTC_ConvertFromBinDec(16)); //год
 	I2C_StopCondition();

 

Теперь для приближения моих часов к реальности, необходимо добавить возможность установки времени с помощью трёхкнопочного интерфейса. В связи с чем у меня возникли вопросы, а именно:

  1. При первом включении или при включении после отключения аккумулятора, все регистры времени будут пусты и считать с часов вообще ничего не получится, как правильно будет отследить это первое включение и записать в регистры времени значения по умолчанию, предположим 12:00:00 ?
  2. Я планирую выводить на дисплей только часы, минуты и секунды. Значит остальные данные мне не нужны, могу ли настраивать только эти показатели? Будут ли идти часы после такой настройки?
    Скрытый текст
    
     	I2C_StartCondition(); //начало передачи
     	I2C_SendByte(0b11010000); //режим записи
     	I2C_SendByte(0x00);//Переходим на 0x00
    	I2C_SendByte(RTC_ConvertFromBinDec(0)); //устанавливаем секунды
     	I2C_StopCondition();
    
     	I2C_StartCondition(); //начало передачи
     	I2C_SendByte(0b11010000); //режим записи
     	I2C_SendByte(0x01);//Переходим на 0x01
    	I2C_SendByte(RTC_ConvertFromBinDec(0)); //устанавливаем минуты
     	I2C_StopCondition();
    
     	I2C_StartCondition(); //начало передачи
     	I2C_SendByte(0b11010000); //режим записи
     	I2C_SendByte(0x02);//Переходим на 0x02
    	I2C_SendByte(RTC_ConvertFromBinDec(12)); //устанавливаем часы
     	I2C_StopCondition();

     

     

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

1. В DS1307 есть 56 байт RAM, при первом включении там будет не известно что, но вы можете записать туда что-то конкретное, например строку "CLOCK". В программе читаете RAM и смотрите - если там строка есть, значит, не первое включение, если нет - первое.

2. Часы идти будут, но содержимое "календаря" будет некорректным.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

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

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

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

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

@ARV

  1. RAM есть энергонезависимая память? Просто если нет, то после отключения мое слово сотрется?...
  2. Так как я не буду читать содержимое календаря, можно считать что его некорректные значения никак не повлияют на работу моих часов ни через день ни через месяц?
Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

RAM - это ОЗУ, оно не сохраняет содержимое при снятии питания. В случае с DS1307 эта память питается от батарейки и будет хранить содержимое все время, пока батарейка подключена. При отключении батарейки, естественно, "слово" сотрется.

Некорректное состояние календаря никак не повлияет на часы, т.к. календарь меняется по часам, а не наоборот.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

27 минут назад, ARV сказал:

что-то конкретное, например строку "CLOCK"

 

Ну или для упрощения какой-то определённый байт по адресу например 0x08?

 

Скрытый текст

	I2C_StartCondition(); //начало передачи
 	I2C_SendByte(0b11010000); //режим записи
 	I2C_SendByte(0x08);//Переходим на 0x08
	I2C_SendByte(0x05); //записываем определённый байт в ОЗУ DS1307
 	I2C_StopCondition();

 

Спасибо огромное, разобрался!

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

1 байт может быть не очень удачным вариантом, т.к. в момент подачи питания содержимое ОЗУ может быть СЛУЧАЙНЫМ, а байт задает всего 256 комбинаций. Т.е. вероятность того, что случайно содержимое этого байта станет равно вами заданному 1/256. В случае со строкой вероятность кардинально меньше, и чем длиннее строка, тем выша гарантия, что ложных "срабатываний" не будет.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

3 минуты назад, ARV сказал:

1 байт может быть не очень удачным вариантом

Значит мне нужно разбить слово на байты и побайтно зписать в ОЗУ?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Да просто запишите набор байтов с разными значениями. Хоть все 56 байт - 1..2..3..4....
А то сейчас тема дойдёт до "Как записать строку побайтно ?" :)

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

Только что, Alex сказал:

А то сейчас тема дойдёт до "Как записать строку побайтно ?"

Ну так вообще говоря, обмен с внешними устройствами обычно и делается при помощи функции типа write_block(void* data, int data_len) :) ну и чтение аналогично.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

1 минуту назад, Alex сказал:

Ну, вообще, да. Но фразы :

Я не слишком опытен, вот и пишу всякую ахинею порой.

3 минуты назад, ARV сказал:

типа write_block(void* data, int data_len)

Описание это функции в какой библиотеке я могу найти, подскажите пожалуйста?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Описание этой функции должно быть понятно из её названия и параметров: запись блока (указатель на записываемые данные и количество байтов этих данных).

Вы за 5 минут можете написать её самостоятельно из имеющихся у вас функций записи 1 байта и обычного цикла.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

2 минуты назад, -=FISHER=- сказал:

Я не слишком опытен, вот и пишу всякую ахинею порой.

Ничего страшного, это всё пройдёт со временем :)

2 минуты назад, -=FISHER=- сказал:

Описание это функции в какой библиотеке я могу найти, подскажите пожалуйста?

Это был пример. Так сказать, некий шаблон, который обычно реализуют для передачи/приёма данных.

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

Только что, Alex сказал:

Ну, вообще, да. Но фразы ... настораживают :)

Тут, скорее всего, речь не о машинном слове, а о "текстовом" слове :) 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

7 минут назад, ARV сказал:

Тут, скорее всего, речь не о машинном слове

Ну вы же написали

55 минут назад, ARV сказал:

например строку "CLOCK"

Вот я и решил что имеется ввиду обычный текст)

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

@-=FISHER=-

Вот у Вас код :

	//Устанавливаем время
 	I2C_StartCondition();
 	I2C_SendByte(0b11010000);
 	I2C_SendByte(0);//Переходим на 0x00
 	I2C_SendByte(RTC_ConvertFromBinDec(0)); //секунды
 	I2C_SendByte(RTC_ConvertFromBinDec(31)); //минуты
 	I2C_SendByte(RTC_ConvertFromBinDec(20)); //часы
 	I2C_SendByte(RTC_ConvertFromBinDec(5)); //день недели
 	I2C_SendByte(RTC_ConvertFromBinDec(29)); //дата
 	I2C_SendByte(RTC_ConvertFromBinDec(1)); //месяц
 	I2C_SendByte(RTC_ConvertFromBinDec(16)); //год
 	I2C_StopCondition();

Создайте функцию , типа :

void DS_Write(uint8_t addrr, void* pData, uint8_t size){
	uint8_t * p= (uint8_t*)pData;
	I2C_StartCondition(); //начало передачи
	I2C_SendByte(0b11010000); //режим записи
	I2C_SendByte(addrr);//Переходим на addrr
	while(size--)	I2C_SendByte(RTC_ConvertFromBinDec(*p++));
	I2C_StopCondition();
}

и применяйте её для записи в часы, вместо простыни из кучи строк.

Можно создать структуру, в которой будут хранится секунды всякие, минуты, ... И передавать адрес этой структуры в функцию.

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

@Alex Мне очень понравилась Ваше предложение. Только пожалуйста сможете объяснить, желательно на моем уровне понимания, что конкретно делают эти строчки:

  1. void* pData

  2. uint8_t * p= (uint8_t*)pData;

  3. *p++

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Только что, Alex сказал:

Создайте функцию , типа

Ну так теперь можно и не создавать :)

 

Только что, -=FISHER=- сказал:

void* pData

указатель на какой-то участок памяти МК

Только что, -=FISHER=- сказал:

uint8_t * p= (uint8_t*)pData

значение указателя p сделать равным значению pData. Собственно говоря, это по сути лишнее, привести тип указателя можно было бы и сразу в месте, где эти данные требуются, без промежуточного указателя.

Только что, -=FISHER=- сказал:

*p++

Взять байт по указателю и увеличить указатель на 1. 

Вообще говоря, все вышесказанное - азы Си... без знаний этого в Си, как без рук.

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

9 минут назад, -=FISHER=- сказал:

void* pData

Это указатель на блок данных. void - чтобы можно было передавать указатель любого типа, не преобразовывая его явно к uint8_t при передачи в функцию.

9 минут назад, -=FISHER=- сказал:

uint8_t * p= (uint8_t*)pData;

Это обычное преобразование типа void к uint8_t

9 минут назад, -=FISHER=- сказал:

*p++

Это инкремент указателя, с взятием значения по нему.

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

1 минуту назад, Alex сказал:

Это указатель

 

2 минуты назад, ARV сказал:

указатель на какой-то участок памяти МК

Короче я пошел читать про указатели))) До этого как-то обходился только переменными.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

3 минуты назад, ARV сказал:

привести тип указателя можно было бы и сразу в месте, где эти данные требуются, без промежуточного указателя.

Помнится, у меня не получалось инкрементировать указатель на void. Может я что-то неправильно делал, но забил и просто создаю отдельный на uint8.

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

Только что, -=FISHER=- сказал:

пошел читать про указатели

Указатели в Си - это та самая бритва, при помощи которой можно сделать шедевр или кровавое месиво :) 

 

Только что, Alex сказал:

Помнится, у меня не получалось инкрементировать указатель на void

Это да, приводить и тут надо. Собственно, ваш подход я и сам применяю, т.к. придерживаюсь принципа "лучше написать больше, но понятнее".

Изменено пользователем ARV

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

4 минуты назад, ARV сказал:

казатели в Си - это та самая бритва, при помощи которой можно сделать шедевр или

А почему в приведенном выше примере нельзя отделаться использованием переменных и нужны обязательно указатели?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

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

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

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

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

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

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

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

    • 2,4кОм уже заказал, новая сложность))) неполярные электролиты, впервые с ними сталкиваюсь, стоят они как космолет, можно конечно сделать из полярных но получится громоздко
    • Конечно нет. Более того, вышеупомянутой 140уд1 достаточно для 90% всех БП, но новые детали позволяют применять разные схемотехнические решения ранее недоступные - например, отсутствие отрицательного источника питания или цепей балансировки ибо их смещение по входам может оказаться пренебрежимо мало, а крайне малый ток полевикового входа не требует сильного согласования импедансов для выравнивания смещений, создаваемых входными токами. Но в чем тогда интерес в разработке схемы, если это будет всё тот же болгарский БП из 70х, причем на тех же самых деталях и по абсолютно такой же схеме Понятно, что особо улучшать схемотехнику линейных БП некуда. Но со старыми деталями, требующими дополнительные пару вольт питания из-за узкого диапазона синфазных сигналов или имеющих почти микроамперы входного тока приходится схемотехнически возиться как с каким-то пажылым дедушкой - там ему костыль в виде отрицательного питания, тут надо импедансы равные по входам, не то смещение будет (у 140уд1, например, даже нет выводов балансировки, т.е. смещение надо вводить отдельной  цепью по входу), а здесь надо выход повторителем усилить, ибо не может раскачать базу силового транзистора... и т.д. Повозиться из интереса можно, но не знаю какое веселье в который раз изобретать один и тот же болгарский велосипед.   Это даже скорее не БП, а гибрид из БП и  вольтамперметра для всяческих издевательств над детальками. Как пример. И вот ещё. Причем эти "много оу" не просто какие-то там буферы-измерялки, а именно в петле ООС стоят, что прибавляет головной боли схемотехнику. Я пытался повторить их "переключалку петель оос", или просто "клампу", как я ее обзываю, в микрокапе хотяб на моделях ОУ типа 741, с использованием в интеграторе TL071, но ничего не вышло, схема стабильно даёт овершуты под 5-10%, что говорит о неоптимально скорректированной под БП АЧХ. Этот рубеж пока что мне не доступен никак, вот  и вожусь со схемой шелестова на четырёх ОУ.  
    • Думаю тут мини версию усилка сделать. А то валяется коробочка одна, от заброшенного одного проекта) Турецкий фильтр тут плату добиваю неспешно, с ней совместить что ли. TDA7377 норм будет ?  
    • Что за бп такой, что аж 10 оу надо. После керамики идёт предпочтение "индустриальных". а точно эти "новейшие новинки" вот так нужны всегда ?  вполне себе может быть, почему и нет. сомнительный кайф корпеть над мелкотой лишний раз)
    • лапки 3 и 4 IC2 ? Точней 15-16-17 CD разъёма.   что это значит ?  
    • Мне третий раз написать что можно? Или у кого аргументированные возражения будут?
    • Я согласен, что эти корпуса неудобны для ручного монтажа, но брать микросхему хуже по параметрам просто потому что корпус надо устанавливать под лупой эт не оправдание кмк. И древний. Современные детали в керамике достать проблематично. "Точно орига" может быть только при прямой покупке у поставщика, ну или отечественной комплектухи, пока китайцы благо не поняли, что можно на 140уд7 написать 140уд17 и никто не заметит) А про качество - ну посмотрите на сроки сохраняемости, это пожалуй единственный плюс герметичного керамического корпуса для любителя. Но если мне в БП на 10 ОУ пихать каждый корпус керамический... Цена выйдет такая что дешевле взять заводской SMU
×
×
  • Создать...