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

Работа с 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=-

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

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

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

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

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

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

@ARV

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

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

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

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

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

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

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

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

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

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

 

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

 

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

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

 

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

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

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

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

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

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

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