Компьютерные подсказки

Вылетает Сталкер: Зов Припяти Программа икс рей 1

Stalker lost alpha гид по прохождению

Pony Express отслеживание почтовых отправлений

Pony Express – время и сроки доставки с Алиэкспресс в Россию

Застряли посылки с Алиэкспресс со статусом Hand over to airline: что делать?

РФ (Nigma) — интеллектуальная поисковая система

Данные для семантики — Яндекс Вордстат

Пиар ВКонтакте при помощи бирж: особенности и использование

Почему я не могу отправить сообщение?

Предупреждение «Подключение не защищено» в Google Chrome по протоколу https Нарушена конфиденциальность данных яндекс браузер

Всё что известно о смартфоне Samsung Galaxy S9 Аккумуляторная батарея Galaxy S9 и мощность

Темы оформления и русификация форума SMF, а так же установка компонента JFusion в Joomla

Автоматическое определение движка форума Позже board powered by smf

Коды в игре скайрим - зелья, ингредиенты, заклинания Код на ингредиенты скайрим

Подробная инструкция, как в "скайриме" открыть дверь золотым когтем

Ds1307 подключение. RTC модуль DS1307 подключение к Arduino

DS1307 ещё называют RTC (Real Time Clock). Данная микросхема представляет из себя часы реального времени и календарь. Связь с микросхемой осуществляется по интерфейсу I 2 C. Её преимущество в том, что она работает (считает время) при выключенном основном питании от резервного источника питания в 3 вольта (например, от батареики типа CR3022). Но в DS1307 есть один недостаток: в ней нет проверки на правильность введённых данных. Для работы с микросхемой потребуется минимальный обвес: кварц на 32768Hz, батарея на 3 вольта и два резистора на 4,7кОм. Схема подключения DS1307:

Работа с DS1307 в BASCOM-AVR

Для начала работы с микросхемой необходимо сконфигурировать порты, к которым подключена микросхема, для этого воспользуемся командой Config :
Config Sda = (Порт микроконтроллера к которому подключена нога SDA микросхемы DS1307)
Config Scl = (Порт микроконтроллера к которому подключена нога SCL микросхемы DS1307)
Например:
Config Sda = Portb.1
Config Scl = Portb.0

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

I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte (переменная в которую запишем секунды) , Ack I2crbyte (переменная в которую запишем минуты) , Ack I2crbyte (переменная в которую запишем часы) , Ack I2crbyte (переменная в которую запишем номер дня недели) , Ack I2crbyte (переменная в которую запишем дату), Ack I2crbyte (переменная в которую запишем номер месяца) , Ack I2crbyte (переменная в которую запишем год) , Nack I2cstop

После чтения данных необходимо перевести их в десятичный формат, вот так:
(переменная секунд) = Makedec((переменная секунд))
(переменная минут) = Makedec((переменная минут))
(переменная часов) = Makedec((переменная часов))
(переменная дня недели) = Makedec((переменная дня недели))
(переменная даты) = Makedec((переменная даты))
(переменная месяца) = Makedec((переменная месяца))
(переменная года) = Makedec((переменная года))

Вот пример чтения времени и даты, а также перевод их в десятичный формат:

I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte Seco , Ack I2crbyte Mine , Ack I2crbyte Hour , Ack I2crbyte Day , Ack I2crbyte Dat , Ack I2crbyte Month , Ack I2crbyte Year , Nack I2cstop Seco = Makedec(seco) Mine = Makedec(mine) Hour = Makedec(hour) Day = Makedec(day) Dat = Makedec(dat) Month = Makedec(month) Year = Makedec(year)

Данные считывать научились, теперь попробуем записывать данные в DS1307. Вот так:
(Переменная которую запишем) = Makebcd((Переменная которую запишем))
I2cstart
I2cwbyte &HD0
I2 cwbyte (Ячейка в которую запишем данные)
I2 cwbyte (Переменная которую запишем)
I2cstop

Обратите внимание, что командаMakebcd переводит переменную в двоично-десятичный формат. Номера и обозначения ячеек:

Вот пример записи переменной секунд:
Seco = Makebcd(seco)
I2cstart
I2cwbyte &HD0
I2cwbyte 0
I2cwbyte Seco
I2 cstop
Кстати, следует учесть, что при первом запуске DS1307 (например, при подключении батареи резервного питания) микросхема будет возвращать в секундах значение 80, это означает, что часы остановлены. Для их запуска запишите в секунды значение 1. Если DS1307 при чтении любых данных возвращает значение 255 или 168 это означает что, микросхема неправильно подключена, либо отсутствует батарея резервного питания.

Практическая работа с микросхемой DS1307

Теперь попробуем поработать с микросхемой DS1307 на практике: соберём простые часы с установкой времени с помощью кнопок. Для этого возьмём саму микросхему DS1307, микроконтроллер Attiny2313, LCD индикатор на контроллере HD44780 и несколько дискретных компонентов. Соберём простую схему:

И напишем простую программу, применяя полученные знания:

$regfile = "attiny2313.dat" $crystal = 4000000 Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2 Config Lcd = 16 * 2 Config Pind.5 = Input Config Pind.4 = Input Config Sda = Portb.1 Config Scl = Portb.0 Dim Seco As Byte Dim Mine As Byte Dim Hour As Byte Initlcd Cls Cursor Off Do I2cstart I2cwbyte &HD0 I2cwbyte &H00 I2cstart I2cwbyte &HD1 I2crbyte Seco , Ack I2crbyte Mine , Ack I2crbyte Hour , Nack I2cstop Seco = Makedec(seco) Mine = Makedec(mine) Hour = Makedec(hour) Locate 1 , 1 Lcd Hour ; ":" ; Mine ; ":" ; Seco ; " " If Pind.5 = 0 Then Incr Mine Mine = Makebcd(mine) I2cstart I2cwbyte &HD0 I2cwbyte 1 I2cwbyte Mine I2cstop Waitms 100 End If If Pind.4 = 0 Then Incr Hour Hour = Makebcd(hour) I2cstart I2cwbyte &HD0 I2cwbyte 2 I2cwbyte Hour I2cstop Waitms 100 End If Loop End

DS1307 - микросхема часов реального времени с интерфейсом I2C(TWI) . Часы / календарь хранят следующую информацию: секунды, минуты, часы, день, дату, месяц и год. Конец месяца автоматически подстраивается для месяцев, в которых менее 31 дня, включая поправку для високосного года. Часы работают в 24-часовом или 12-часовом формате с индикатором AM/PM. DS1307 имеет встроенную схему контроля питания, которая обнаруживает пропадание питания и автоматически переключает схему на питание от батареи.

Vbat - вход батареи для любого стандартного 3 Вольтового литиевого элемента или другого источника энергии. Для нормальной работы напряжение батареи должно поддерживаться между 2.5 и 3.5 В. Уровень, при котором запрещён доступ к часам реального времени и пользовательскому ОЗУ, установлен внутренней схемой равным 1.25 x Vbat. Литиевая батарея ёмкостью 35 mAh или больше достаточна для питания DS1307 в течение более чем 10 лет при отсутствии питания.
SCL (Последовательный Тактовый Вход) - SCL используется, чтобы синхронизировать передачу данных через последовательный интерфейс.
SDA (Вход/Выход Последовательных Данных) - SDA - вход / выход данных для 2-проводного последовательного интерфейса. Это выход с открытым стоком, который требует внешнего притягивающего резистора.
SQW/OUT (Меандр / Выходной Драйвер) - Когда бит SQWE установлен в 1, на выходе SQW/OUT вырабатываются импульсы в форме меандра одной из четырех частот: 1 Гц., 4 кГц., 8 кГц., 32 кГц. Вывод SQW/OUT - с открытым стоком, требует внешнего притягивающего резистора.
X1, X2 - выводы для подключения стандартного кристалла кварца 32.768 кГц. Внутренняя схема генератора рассчитана на работу с кристаллом, имеющим номинальную емкость (CL) 12.5 пФ.
GND – Земля.
VCC – питание 5 вольт.

DS1307 работает как ведомое устройство на последовательной шине. Для доступа к нему надо установить состояние START и передать код идентификации устройства, сопровождаемый адресом регистра. К последующим регистрам можно обращаться последовательно, пока не установлено состояние STOP . Когда VСС падает ниже 1.25 x Vbat, устройство прекращает связь и сбрасывает адресный счетчик. В это время оно не будет реагировать на входные сигналы, чтобы предотвратить запись ошибочной информации. Когда VСС падает ниже Vbat, устройство переключается в режим хранения с низким потреблением. При включении питания устройство переключает питание с батареи на VСС , когда напряжение питания превысит Vbat + 0.2V, и реагирует на входные сигналы, когда VСС станет более 1.25 x Vbat. Когда питание находится в пределах нормы, устройство полностью доступно, и данные могут быть записаны и считаны. Когда к устройству подключена трёхвольтовая батарея и VСС ниже 1.25 x Vbat, чтение и запись запрещены. Однако отсчёт времени при этом работает. Когда VСС падает ниже Vbat, питание ОЗУ и отсчёта времени переключается на внешнюю батарею 3 В.

Информацию о времени и дате получают, считывая соответствующие регистры. Регистры часов показаны в таблице ниже. Время и календарь устанавливаются или инициализируются путём записи байтов в соответствующие регистры. Содержание регистров времени и календаря хранится в двоично-десятичном (BCD) формате, поэтому перед выводом информации на LCD дисплей или семисегментный индикатор необходимо преобразовать двоично-десятичный код в двоичный или ANSII - код.

Бит 7 регистра 0 - это бит остановки хода часов (Clock Halt). Когда этот бит установлен в 1, генератор остановлен. Когда сброшен в ноль, генератор работает, а часы считают время.

DS1307 может работать в 12-часовом или 24-часовом режиме. Бит 6 регистра часов задаёт один из этих режимов. Когда он равен 1, установлен 12-часовой режим. В 12-часовом режиме высокий уровень бита 5 сообщает о послеполуденном времени. В 24-часовом режиме бит 5 - второй бит 10 часов (20-23 часа).

Регистр управления DS1307 предназначен для управления работой вывода SQW/OUT . Бит OUT - управление выходом. Этот бит управляет выходным уровнем на выводе SQW/OUT , когда генерация меандра запрещена. Если SQWE = 0, логический уровень на выводе SQW/OUT равен 1, если OUT = 1, и 0 - если OUT = 0. SQWE - Разрешение меандра. Когда этот бит установлен в 1, разрешается генерация меандра. Частота меандра зависит от значений битов RS0 и RS1. Эти биты управляют частотой меандра, когда его генерация разрешена. В таблице ниже показаны частоты, которые могут быть заданы RS битами.

DS1307 поддерживает двунаправленные 2-проводную шину и протокол передачи данных. Устройство, которое посылает данные на шину, называется передатчиком, а устройство, получающее данные - приемником. Устройство, которое управляет передачей, называется ведущим. Устройства, которые управляются ведущим - ведомые. Шина должна управляться ведущим устройством, которое вырабатывает последовательные такты (SCL), управляет доступом к шине, и генерирует состояния СТАРТ и СТОП. DS1307 работает как ведомое на 2-х проводной шине.

Для работы с DS1307 необходимо организовать функцию чтения из микросхемы и функцию записи.

1. Режим записи в DS1307 . Последовательные данные и такты получены через SDA и SCL. После передачи каждого байта передаётся подтверждающий бит ASK . Состояния START и STOP опознаются как начало и конец последовательной передачи. Распознавание адреса выполняется аппаратно после приема адреса ведомого и бита направления. Байт адреса содержит семибитный адрес DS1307, равный 1101000, сопровождаемым битом направления (R/W), который при записи равен 0. После получения и расшифровки байта адреса DS1307 выдаёт подтверждение ASK на линии SDA. После того, как DS1307 подтверждает адрес ведомого и бит записи, ведущий передает адрес регистра DS1307. Тем самым будет установлен указатель регистра в DS1307. Тогда ведущий начнет передавать байты данных в DS1307, который будет подтверждать каждый полученный байт. По окончании записи ведущий сформирует состояние STOP .

2. Режим чтения из DS1307 . Первый байт принимается и обрабатывается как в режиме ведомого приёмника. Однако в этом режиме бит направления укажет, что направление передачи изменено. Последовательные данные передаются по SDA от DS1307, в то время как последовательные такты - по SCL в DS1307. Состояния START и STOP опознаются как начало и конец последовательной передачи. Байт адреса - первый байт, полученный после того, как ведущим сформировано состояние START . Байт адреса содержит семибитный адрес DS1307, равный 1101000, сопровождаемым битом направления (R/W), который при чтении равен 1. После получения и расшифровки байта адреса DS1307 выдаёт подтверждение ASK на линии SDA. Тогда DS1307 начинает передавать данные, начинающиеся с адреса регистра, на которые указывает указатель регистра. Если указатель регистра не записан перед инициированием режима чтения, то первый адрес, который читается - это последний адрес, оставшийся в указателе регистра. DS1307 должен получить неподтверждение NOASK , чтобы закончить чтение.

Рассмотрим особенности работы с DS1307 на примере простых часов, которые будут показывать часы, минуты и секунды. Данные будут выводиться на LCD дисплей 16х2. Две кнопки "Часы+" и "Минуты+" позволят подвести нужное время. Микроконтроллер Atmega 8 тактируется от внутреннего генератора частотой 1 MHz, поэтому не забудьте поменять фьюзы. Ниже представлена схема подключения.

Управляющая программа включает в себя наборы функций работы с шиной TWI, часами DS1307, LCD дисплеем.

I2CInit - инициализация шины;
I2CStart - передача условия START;
I2CStop - передача условия STOP;
I2CWriteByte - запись данных;
I2CReadByte - чтение данных;
DS1307Read - функция чтения данных из DS1307;
DS1307Write - Функция записи данных в DS1307;
lcd_com - передача команды в LCD;
lcd_data - передача данных в LCD;
lcd_string - функция вывода строки в LCD;
lcd_num_to_str - функция вывода символа типа int;
lcd_init - инициализация LCD.

Ниже представлен код программы:

#include #include // Функция инициализация шины TWI void I2CInit(void) { TWBR = 2; // Настройка частоты шины TWSR = (1 << TWPS1)|(1 << TWPS0); // Предделитель на 64 TWCR |= (1 << TWEN); // Включение модуля TWI } // Функция СТАРТ void I2CStart(void) { TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTA); // Передача условия СТАРТ while(!(TWCR & (1 << TWINT))); // Ожидание установки флага TWINT } // Функция СТОП void I2CStop(void) { TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO); // Передача условия СТОП while(TWCR & (1 << TWSTO)); // Ожидание завершения передачи условия СТОП } // Функция записи данных по шине uint8_t I2CWriteByte(uint8_t data) { TWDR = data; // Загрузка данных в TWDR TWCR = (1 << TWEN)|(1 << TWINT); // Сброс флага TWINT для начала передачи данных while(!(TWCR & (1 << TWINT))); // Ожидание установки флага TWINT // Проверка статуса // Если адрес DS1307+R и принято "подтверждение"(0x18) // или адрес DS1307+W и принято "подтверждение"(0x40) // или передается байт данных и принято "подтверждение"(0x28) if((TWSR & 0xF8) == 0x18 || (TWSR & 0xF8) == 0x40 || (TWSR & 0xF8) == 0x28) return 1; // OK else return 0; // ОШИБКА } // Функция чтения данных по шине uint8_t I2CReadByte(uint8_t *data,uint8_t ack) { // Возвращаем "подтверждение" после приема if(ack) TWCR |= (1 << TWEA); // Возвращаем "неподтверждение" после приема // Ведомое устройство не получает больше данных // обычно используется для распознования последнего байта else TWCR &= ~(1 << TWEA); // Разрешение приема данных после сброса TWINT TWCR |= (1 << TWINT); while(!(TWCR & (1 << TWINT))); // Ожидание установки флага TWINT // Проверка статуса // Если принят байт данных и возвращается "подтверждение"(0x50) // или принят байт данных и возвращается "ненеподтверждение"(0x58) if((TWSR & 0xF8) == 0x50 || (TWSR & 0xF8) == 0x58) { *data = TWDR; // Читаем данные из TWDR return 1; // OK } else return 0; // ОШИБКА } // Функция чтения данных из DS1307 uint8_t DS1307Read(uint8_t address,uint8_t *data) { uint8_t res; I2CStart(); // СТАРТ res = I2CWriteByte(0b11010000); // адрес DS1307+W if(!res) return 0; // ОШИБКА // Передача адреса необходимого регистра res = I2CWriteByte(address); if(!res) return 0; // ОШИБКА I2CStart(); // Повторный СТАРТ res = I2CWriteByte(0b11010001); // адрес DS1307+R if(!res) return 0; // ОШИБКА // Чтение данных с "неподтверждением" res = I2CReadByte(data,0); if(!res) return 0; // ОШИБКА I2CStop(); // СТОП return 1; // OK } // Функция записи данных в DS1307 uint8_t DS1307Write(uint8_t address,uint8_t data) { uint8_t res; I2CStart(); // СТАРТ res = I2CWriteByte(0b11010000); // адрес DS1307+W if(!res) return 0; // ОШИБКА // Передача адреса необходимого регистра res = I2CWriteByte(address); if(!res) return 0; // ОШИБКА res = I2CWriteByte(data); // Запись данных if(!res) return 0; // ОШИБКА I2CStop(); // СТОП return 1; // OK } // Функции работы с LCD #define RS PD0 #define EN PD2 // Функция передачи команды void lcd_com(unsigned char p) { PORTD &= ~(1 << RS); // RS = 0 (запись команд) PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция передачи данных void lcd_data(unsigned char p) { PORTD |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл _delay_us(100); PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция вывода строки на LCD void lcd_string(unsigned char command, char *string) { lcd_com(0x0C); lcd_com(command); while(*string != "\0") { lcd_data(*string); string++; } } // Функция вывода переменной void lcd_num_to_str(unsigned int value, unsigned char nDigit) { switch(nDigit) { case 4: lcd_data((value/1000)+"0"); case 3: lcd_data(((value/100)%10)+"0"); case 2: lcd_data(((value/10)%10)+"0"); case 1: lcd_data((value%10)+"0"); } } // Функция инициализации LCD void lcd_init(void) { PORTD = 0x00; DDRD = 0xFF; _delay_ms(50); // Ожидание готовности ЖК-модуля // Конфигурирование четырехразрядного режима PORTD |= (1 << PD5); PORTD &= ~(1 << PD4); // Активизация четырехразрядного режима PORTD |= (1 << EN); PORTD &= ~(1 << EN); _delay_ms(5); lcd_com(0x28); // шина 4 бит, LCD - 2 строки lcd_com(0x08); // полное выключение дисплея lcd_com(0x01); // очистка дисплея _delay_us(100); lcd_com(0x06); // сдвиг курсора вправо lcd_com(0x0C); // включение дисплея, курсор не видим } int main(void) { _delay_ms(100); DDRC = 0x00; PORTC = 0xFF; lcd_init(); // Инициализация LCD I2CInit(); // Инициализация шины I2C lcd_string(0x81, "«acГ Ѕa DS1307"); // Часы на DS1307 lcd_string(0xC4, " : : "); // Запускаем ход часов uint8_t temp; DS1307Read(0x00,&temp); temp &= ~(1 << 7); // обнуляем 7 бит DS1307Write(0x00,temp); while(1) { unsigned char hour, minute, second, temp; // Читаем данные и преобразуем из BCD в двоичную систему DS1307Read(0x00,&temp); // Чтение регистра секунд second = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F); DS1307Read(0x01,&temp); // Чтение регистра минут minute = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F); DS1307Read(0x02,&temp); // Чтение регистра часов hour = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F); lcd_com(0xC4); lcd_num_to_str(hour, 2); // Выводим на экран часы lcd_com(0xC7); lcd_num_to_str(minute, 2); // Выводим на экран минуты lcd_com(0xCA); lcd_num_to_str(second, 2); // Выводим на экран секунды if((PINC & (1 << PC0)) == 0) // Если нажата кнопка { while((PINC & (1 << PC0)) == 0){} // Ждем отпускания кнопки hour++; // Увеличиваем часы на 1 if(hour > 23) hour = 0; // Преобразуем из двоичной системы в BCD и записываем в DS1307 uint8_t temp; temp = ((hour/10) << 4)|(hour%10); DS1307Write(0x02, temp); _delay_ms(100); } if((PINC & (1 << PC1)) == 0) // Если нажата кнопка { while((PINC & (1 << PC1)) == 0){} // Ждем отпускания кнопки minute++; // Увеличиваем минуты на 1 if(minute > 59) minute = 0; // Преобразуем из двоичной системы в BCD и записываем в DS1307 uint8_t temp; temp = ((minute/10) << 4)|(minute%10); DS1307Write(0x01, temp); _delay_ms(100); } } }

DS1307 – часы реального времени с последовательным интерфейсом, поддерживают. Часами можно управлять, используя микроконтроллер Atmega128 или другой МК, который имеет последовательный двухпроводной интерфейс. DS1307 подключается напрямую к двум портам I/O микроконтроллера, а двухпроводной интерфейс обеспечивается драйверами низкого уровня, которые описываются в разделе.

Основными характеристиками DS1307 являются: низкая потребляемая мощность, полный BCD часы/календарь и 56 байт энергонезависимой памяти SRAM. Адрес и данные передаются последовательно через двухпроводную двунаправленную шину. Часы/календарь выдают следующую информацию: секунды, минуты, часы, дни, месяцы и годы. Конец месяца автоматически устанавливается для тех месяцев, в которых менее 31 дня. Имеется поправка на високосный год. Часы работают в 24-часовом или 12-часовом формате с индикатором AM/PM. DS1307 имеет встроенную схему контроля питания, которая обнаруживает ошибки питания и автоматически переключается на батарейное питание.

DS1307 работает как «ведомое» устройство на последовательной шине. Для доступа к нему нужно установить состояние START и передать следом за адресом регистра идентификационный код устройства. К следующим регистрам можно обращаться последовательно, пока не установлено состояние STOP. Состояния START и STOP генерируются драйверами низкого уровня.

DS1307 имеет двухпроводную шину, подключённую к двум выводам порта I/O МК: SCL – PD0, SDA – PD1. Напряжение VDD равно 5В, схема использует кварцевый (часовой) резонатор с частотой 32.678 кГц.

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

В соответствии с этим должны быть оговорены следующие условия:

Начало передачи данных. Изменение состояния линии данных при переходе из высокого в низкое, в то время как тактовая линия находится в высоком состоянии, определяется как состояние START.

Остановка передачи данных. Изменение состояния линии данных при переходе из низкого в высокое, в то время как тактовая линия находится в высоком состоянии, определяется как состояние STOP.


Действительные данные. Состояние линии данных соответствует действительным данным тогда, когда после условия START линия данных стабильна во время высокого состояния тактового сигнала. Данные на линии должны быть изменены во время низкого состояния тактового сигнала. Один тактовый импульс на один бит данных.

Рис. 2.40. Передача данных по последовательной двухпроводной шине

Каждая передача данных начинается при наступлении состояния START и прекращается при наступлении состояния STOP. Количество байт данных переданных между состояниями START и STOP не ограничено и определяется «ведущим» устройством. Информация передаётся побайтно, и каждый приём подтверждается девятым битом.

Подтверждение приёма. Каждое приёмное устройство, при обращении к нему, вынуждено генерировать подтверждение приёма после получения каждого байта. «Ведущее» устройство должно генерировать дополнительные тактовые импульсы, которые ставятся в соответствие битам подтверждения. Если сигнал подтверждения приёма находится в высоком состоянии, то по приходу тактового импульса бита подтверждения, подтверждающее приём устройство должно переводить линию SDA в низкое состояние. Конечно, должны учитываться время установки и время удержания. «Ведущее» устройство должно сигнализировать об окончании передачи данных «ведомому» устройству, прекращая генерацию бита подтверждения, при получении от «ведомого» тактового импульса подтверждения приёма. В этом случае, «ведомый» должен перевести линию данных в низкое состояние, чтобы позволить «ведущему» генерировать условие STOP.

На рис. 2.40 показано завершение передачи данных по двухпроводной линии. В зависимости от состояния бита R/-W, возможны два типа передачи:

1. Режим «ведомого» приемника (режим записи в DS1307): последовательные данные и такты получены через SDA и SCL соответственно. После передачи каждого байта передаётся подтверждающий бит (рис.2.40). Состояния START и STOP понимаются как начало и конец последовательной передачи. Распознавание адреса выполняется аппаратно после приема адреса «ведомого» и бита направления. Байт адреса является первым байтом, принимаемым после возникновения состояния START, генерируемого «ведущим». Байт адреса содержит семь битов адреса DS1307, равных 1101000, сопровождаемых битом направления (R/#W), который для записи равен 0 (рис. 2.40а). После приёма и декодирования байта адреса DS1307 выдаёт подтверждение на линию SDA. После подтверждения DS1307 адреса «ведомого» и бита записи, «ведущий» передает адрес регистра DS1307. Тем самым будет установлен указатель регистра в DS1307. Затем «ведущий» начнет передавать каждый байт данных с последующим приёмом подтверждения получения каждого байта. По окончании записи «ведущий» сформирует состояние STOP, для прекращения передачи данных.

2. Режим «ведомого» передатчика (режим чтения из DS1307): Первый байт принимается и обрабатывается как в режиме «ведомого» приёмника. Однако в этом режиме бит направления укажет, что направление передачи изменено. Последовательные данные передаются DS1307 по SDA, тактовые импульсы - по SCL. Состояния START и STOP понимаются как начало и конец последовательной передачи (рис. 2.40). Байт адреса является первым байтом, принимаемым после возникновения состояния START, генерируемого «ведущим». Байт адреса содержит семь битов адреса DS1307, равных 1101000, сопровождаемых битом направления (R/-W), который для чтения равен 1. После приёма и декодирования байта адреса DS1307 принимает подтверждение с линии SDA. Тогда DS1307 начинает передавать данные с адреса, на который показывает указатель регистра. Если указатель регистра не записан перед инициализацией режима чтения, то первым прочитанным адресом является последним адрес, сохранённый в указателе регистра. DS1307 должен послать бит «неподтверждения», чтобы закончить чтение (рис. 2.40б).

Схема подключения DS1307 к МК Atmega128 приведена на рис. 2.41, где кнопки SA1 и SA2 предназначены для начальной настройки часов.

Рис. 2.41. Подключение схемы DS1307 микроконтроллеру по интерфейсу IIC (шина TWI)

Контрольные вопросы

1. В чем отличие RISC –процессора от CISC-процессор?

2. В чем преимущества аккумуляторной архитектуры от архитектуры с регистрами общего назначения?

3. Что значит команды с фиксированной разрядностью? Дайте разъяснение.

4. Перечислите периферийные устройства МК и приведите примеры их использования.

5. Назначение отладочных средств. Что дает программисту использования отладчиков?

6. На какие линии делятся МК фирмы Atmel? В чем их отличие.

7. Где используются МК сверхмалым энергопотреблением?

8. Какие меры принимаются для снижения энергопотребления фирмами-разработчиками?

Глава III. Лабораторный практикум по микроконтроллерам семейства AVR фирмы ATMEL

Лабораторный практикум предназначен для изучения студентами специальностей 22.01.00, 23.03.00 и 23.05 всех форм обучения основных принципов построения и программирования, цифровых систем управления и обработки данных и является частью учебно-методических разработок по дисциплинам «Микропроцессорные системы», «Микропроцессорные устройства систем управления», «Микропроцессорные системы управления», «Машинно-ориентированные языки программирования». Приведенные в практикуме лабораторные работы позволят получить практические навыки по разработке аппаратного, алгоритмического и программного обеспечения микроконтроллерных систем управления и обработки данных.

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

Все работы проводятся на учебно-лабораторном стенде УЛС-ATmega8535, разработанным автором по единой схеме «Получение задания [Анализ задания [ Разработка алгоритма решения задачи [ Разработка и отладка программного обеспечения на отладчике AVR Studio 4 [ Программирование реальной системы с использованием PonyProg2000[Проверка работоспособности и демонстрации реальной системы [ Составление и защита отчета».

Отличительными особенностями стенда являются:

· универсальность;

· возможность подключения различных типов датчиков и исполнительных устройств;

· возможность использования современных аппаратно–программных средств отладки и программирования микроконтроллеров в реальных условиях;

Эффективность использования УЛС в учебном процессе определяется:

1. Универсальностью стенда, т.к. стенд позволяет посредством коммутации перестраивать структуру стенда для решения различных задач, что даст возможность на одном стенде проводить большое количество лабораторных работ (более 30);

2. Повышением эффективности проведения занятий, так как отладкапрограммного обеспечения стенда производится на отладчике AVR Studio 4, a программирование реального МК производится с использованием аппаратно-программных средств PonyProg2000;

3. Возможностью решения поставленных задач по схеме «Получение задания [Анализ задания [ Разработка алгоритма решения задачи [ Разработка и отладка программного обеспечения на отладчике AVR Studio 4 [ Программирование реальной системы с использованием PonyProg2000[Проверка работоспособности и демонстрации реальной системы [ Составление и защита отчета» с использованием реальных микроконтроллеров и современных аппаратно–программных средств отладки и программирования микроконтроллерных систем управления и обработки данных.

4. Получением дополнительных навыков по работе с различными периферийными устройствами (системами индикации на основе ЖКИ, интерфейсами UART, SPI, IIC и RS-232) и т.д.;

5. Возможностью разработки собственных вариантов лабораторных работ.

Принципиальная схема УЛС и расположение элементов на печатной плате приведены на рисунках 3.1 и 3.2.

Основные элементы УЛС следующие:

1. Кнопка включения напряжения питание SB9 (В качестве источника питания стенда используется блок питания компьютера +5В, что обеспечивает безопасность работы на стенде).

2. Светодиод HL17 индицирует наличие напряжения +5В.

3. . Микросхема D1 - микроконтроллер Atmega8535 семейства AVR, производства фирмы ATMEL, 8-восьмиразрядный, с тактовой частотой от 0 до 16 МГц. В своем составе имеет – Flash-память программ 8 Кбайт, ОЗУ (оперативное запоминающее устройство) 512 байт, 512 байт EEPROM (электрически перепрограммируемая память), два 8-разрядных и один 16-разрядный таймеры/счетчики, 8-канальный 10-битный АЦП (а налого-ц ифровой п реобразователь), программируемый последовательный интерфейс UART, последовательные интерфейсы SPI и I2C.

4. Жидкокристаллический индикатор (ЖКИ) LCD, подключенный к микроконтроллеру через параллельный порт (8 линий данных и 3 линии управления, разъемы Х8 и Х11 соответственно). ЖКИ дает возможность наглядно устанавливать (посредством кнопок настройки часов) и отображать текущее время и результаты работы АЦП.

5. Кнопки SB1, …, SB8 и светодиодные индикаторы HL1- HL8, предназначены для имитации дискретных сигналов ввода.

6. Линейка индикации дискретных сигналов вывода, реализованной на светодиодах HL9- HL16.

7. Резисторы переменного сопротивления R20, R21 для имитации датчиков угла поворота (задающее устройство в системах управления) или для формирования входного аналогового сигнала АЦП.

8. Кнопки-имитаторы внешних сигналов запроса прерывания S16, S17.


В этом материале будет рассмотрен топорный вариант работы с TWI модулем на примере часов реального времени - микросхемы DS1307. Топорный, потому что обмен по I2C будет организован без прерываний и анализа статусных кодов, чтобы сильно не грузить начинающих.

DS1307

Микросхема DS1307 предназначена для счета времени - секунд, минут, часов, дней, месяцев и лет. То есть по сути, это часы с календарем.

Она тактируется от собственного кварцевого генератора с частотой 32768 Гц и может работать от двух источников питания - основного и резервного. Важная фишка этой микросхемы заключается в низком потреблении - меньше 500 nA в рабочем режиме. При таком потреблении DS1307 может проработать от трехвольтовой батарейки (типа CR2032 емкостью ~200 мА*ч) несколько лет. Также DS1307 может генерировать на одном из выводов меандр и в ее составе есть 56 байт оперативной памяти, которую можно использовать для хранения данных.

Минимальная схема подключения DS1307 включает в себя часовой кварц и один источник питания. Обмен данными с микросхемой осуществляется по I2C, причем DS1307 может работать на шине только как подчиненное устройство (слейвом).

С чего начать?

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

Скорость обмена DS1307




Адрес, по которому DS1307 отзывается на I2C шине




Карта памяти DS1307

Карта памяти показывает, по каким адресам расположены регистры микросхемы и сколько их вообще.

По нулевому адресу располагается регистр секунд. Младшие 4 разряда регистра отведены для единиц, там может быть число от 0 до 9. Старшие - для десятков секунд.


Это так называемый двоично-десятичный формат представления чисел (BCD).При таком формате один байт может представить числа только от 0 до 99. Остальные регистры часов и календаря содержат данные в таком же формате.

7-й разряд регистра секунд - управляющий. 0 в этом разряде разрешает работу часов, 1 - запрещает. При подачи питания этот разряд устанавливается в 1.

По первому адресу расположен регистр минут. С ним все понятно.

По второму адресу располагается регистр часов. 6-й бит этого регистра задает формат представления времени. Если он установлен в 1 используется 12 часовой формат, если сброшен -24 часовой.

По седьмому адресу располагается регистр, управляющий выводом SQW. На него можно выводить внутренний тактовый сигнал разной частоты. Значения битов описаны в даташите. Нас они сейчас не интересуют.

Ну и адреса с 8 по 63-й отведены для оперативной памяти. Их можно использовать для хранения данных.

Как записать данные в DS1307

DS1307 может работать в двух режимах: как подчиненный приемник и как подчиненный передатчик. В первом режиме ведущее устройство передает DS1307 данные, а DS1307 принимает их. Во втором - ведущее устройство принимает от DS1307 данные, а та в свою очередь передает их. (Но обмен в обоих случаях начинает ведущий!)

Для каждого режима в даташите есть описание и диаграмма обмена. Запись данных выполняется согласно следующей последовательности.



2. Ведущий выдает на шину адрес DS1307 с нулевым битом квитирования (адресный пакет), что сигнализирует ведомому о последующей записи данных.
3. Если на шине присутствует микросхема DS1307, она отвечает ведущему - ACK.
4. После получения ответа ведущий передает DS1307 адрес регистра, с которого начнется запись данных. Это значение записывается во внутренний счетчик адреса DS1307.
5. DS1307 снова отвечает ведущему.
6. Получив ответ, ведущий передает ведомому байт данных, который предназначен для записи в регистр DS1307.
7. DS1307 отвечает ведущему.
8. Шаги 6, 7 повторяются несколько раз.
9. Ведущий формирует на шине состояние СТОП.

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



1. Ведущий формирует на шине состояние СТАРТ.
2. Ведущий выдает на шину адрес DS1307 с установленным битом квитирования, что сигнализирует ведомому о последующем чтении данных.
3. DS1307 отвечает ведущему.
4. DS1307 передает ведущему байт данных, на который указывает внутренний счетчик адреса.
5. Ведущий отвечает, что принял данные.
6 . Шаги 4, 5 повторяются несколько раз.
7. DS1307 передает ведущему байт данных.
7. Ведущий неформирует ответ DS1307.
8. Ведущий выдает на шину состояние СТОП.

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

Код

Теперь можно перейти к коду. Нам понадобится минимум три функции:

Функция инициализации,
- функция записи данных,
- функция чтения данных.

Инициализация


#define F_I2C 50000UL
#define TWBR_VALUE (((F_CPU)/(F_I2C)-16)/2)

#if ((TWBR_VALUE > 255) || (TWBR_VALUE == 0))
#error "TWBR value is not correct"
#endif

void RTC_Init(void)
{
TWBR = TWBR_VALUE;
TWSR = 0;
}

Скорость задается с помощью макроса TWBR_VALUE. Здесь используется формула, разобранная в предыдущей части. При компиляции расчетное значение проверяется с помощью директив препроцессора, чтобы убедиться, что оно не выходит за диапазон.

Передача данных

Передача данных начинается с состояния СТАРТ. Чтобы сформировать его, нужно включить TWI модуль, установить бит TWSTA и сбросить флаг прерывания TWINT. Это выполняется в одну строчку, записью в управляющий регистр TWCR.

Когда микроконтроллер выдаст на шину состояние СТАРТ, установится бит TWINT и в статусном регистре TWSR изменится статусный код. Микроконтроллер должен дождаться установки бита TWINT, прежде чем перейдет к следующей операции. Ожидание в нашем случае выполняется циклическим опросом (тупо поллингом.. не путать с троллингом).


TWCR = (1< while(!(TWCR & (1<

Каждая установка бита TWINT сопровождается определенным статусным кодом в регистре TWSR. По хорошему, мы должны проверять эти коды, чтобы контролировать успешность операций. Но поскольку код у нас торный (учебный), мы не будем этого делать.

Далее на шину нужно выдать адресный пакет. В регистр данных TWDR загружаем адрес, а бит квитирования устанавливаем нулевым. После загрузки адреса сбрасываем бит TWINT, инициируя дальнейшую работу TWI модуля, и дожидаемся, когда она завершится, опрашивая TWINT.


/*выдаем на шину пакет SLA-W*/
TWDR = (DS1307_ADR<<1)|0;
TWCR = (1<while(!(TWCR & (1<

Посылаем на шину адрес, с которого будет производиться запись в DS1307. Для этого загружаем в регистр данных требуемое значение, сбрасываем бит TWINT и дожидаемся его установки.



TWDR = adr;
TWCR = (1<while(!(TWCR & (1<


/*формируем состояние СТОП*/
TWCR = (1<

Полный код функции записи будет выглядеть примерно так.


void RTC_SetValue(uint8_t adr, uint8_t data)
{
/*формируем состояние СТАРТ*/
TWCR = (1< while(!(TWCR & (1<

/*выдаемна шину пакет SLA-W*/
TWDR = (DS1307_ADR<<1)|0;
TWCR = (1< while(!(TWCR & (1<

/*передаем адрес регистра ds1307*/
TWDR = adr;
TWCR = (1< while(!(TWCR & (1<

/*передаем данные или пропускаем*/
if (data != RTC_RESET_POINTER){
/*это чтобы привести данные к BCD формату*/
data = ((data/10)<<4) + data%10;

TWDR = data;
TWCR = (1< while(!(TWCR & (1< }

/*формируем состояние СТОП*/
TWCR = (1<}

С помощью этой функции можно производить запись отдельных регистров и инициализировать внутренний регистр адреса DS1307 для последующей операции чтения данных. Пример использования функции есть в тестовых проектах.

Чтение данных из DS1307

Формируем состояние СТАРТ.


/*формируем состояние СТАРТ*/
TWCR = (1< while(!(TWCR & (1<

Посылаем на шину адресный пакет - адрес и установленный бит квитирования.


/*выдаемна шину пакет SLA-R*/
TWDR = (DS1307_ADR<<1)|1;
TWCR = (1< while(!(TWCR & (1<

Получаем данные. Сбрасываем бит TWINT, инициирую работу TWI модуля. Бит TWEA должен быть установлен в 1, чтобы ведущее устройство сигнализировало ведомому о приеме очередного байта.
Когда бит TWINT снова установится в 1, в регистре данных будет байт принятый от ведомого.


/*считываем данные с подтверждением*/
TWCR = (1< while(!(TWCR & (1< data = TWDR;


/*считываем данные без подтверждения*/
TWCR = (1< while(!(TWCR & (1< data = TWDR;

/*формируем состояние СТОП*/
TWCR = (1<

Полный код функции чтения одного байта данный из DS1307 будет выглядеть примерно так.


uint8_t RTC_GetValue(void)
{
uint8_t data;

/*формируем состояние СТАРТ*/
TWCR = (1< while(!(TWCR & (1<

/*выдаем на шину пакет SLA-R*/
TWDR = (DS1307_ADR<<1)|1;
TWCR = (1< while(!(TWCR & (1<

/*считываем данные*/
TWCR = (1< while(!(TWCR & (1< data = TWDR;

/*формируем состояние СТОП*/
TWCR = (1<

Return data;
}

Тестовый проект для DS1307

Как обычно тестовый проект, объединяющий все выше сказанное. Программа простая. Инициализируем периферию, загружаем в DS1307 начальное значение. Далее в цикле считываем временя и выводим на LCD. Для общения с DS1307 используются всего три функции.

Обновлено 23.07.2018. Всем привет. Для работы с часами, в прошлой статье был рассмотрен интерфейс TWI, на который мы сегодня будем ссылаться. Ну что ж начнем. Данные часы являются TWI совместимыми, т.е. принцип обмена данными по шине будет таким же как мы и рассматривали.

На рисунке ниже представлено расположение выводов, описание, и сам вид наших часов или как далее будем их называть RTC (Real-time clock) — часы реального времени или генератор импульсов времени. Данный “девайс” DS1307 считает секунды, минуты, часы, день месяца, месяц, день недели и год вместе с високосными. Календарь действителен до 2100 года. Я думаю на наш век хватит:).

Как видно из описания имеется вход для аварийного питания от батареи, при отключенном внешнем питание. В этом режиме RTC поддерживает только свое основное назначение – отсчет времени, без внешних запросов. Напряжение питания батареи должно быть 2 – 3.5V. В техническом описание пишется что при заряде более 48 мА/ч, при температуре 25 град Цельсия, наша схема продержится около 10 лет. Более чем надо. На рисунке ниже представлена “таблеточка” CR2032 и крепление, которые будем использовать.

Теперь пройдемся по внешнему питанию. Рабочее напряжение часов 5В с небольшим диапазоном 4,5 -5,5В. Напряжение от батареи 3В(минимум 2, максимум 3,5В) Работа RTC делится на три режима по напряжению:

1. Vcc=5В – чтение, запись, отсчет;
2. Vcc= ниже 1,25*Vbat , но выше Vbat +0.2V — только отсчет батареи от внешнего питания.
3. Vcc ниже Vbat: RTC и ОЗУ переходит на питание от батареи. Потребление в активном состоянии 1,5 мА, от батареи 500-800нА.
Напряжение для передачи/приема информации:
Логический 0: -0.5В — +0.8В
Логическая 1: 2.2 В – Vcc+0.3В

Как и в прошлых постах попробуем запустить в Proteus. Отладим код. И перенесем все в железо. Ниже приведена схема подключения.

Где SQW/OUT – это вывод часов который можно запрограммировать на вывод частоты 1Гц, 4.096Гц, 8.192Гц и 32,768Гц. Т.е. можно использовать для внешнего прерывания контроллера с периодичностью в 1 с. Очень полезная функция. Но нам не пригодится. Кстати он тоже с открытым коллектором, поэтому необходим подтягивающий резистор. Номинал 4,7 кОм.

Выводы Х1 и Х2 – к ним подключаем кварцевый резонатор с частотой 32,768 кГц. Либо можно применить внешний тактовый генератор с той же частотой. Но при этом вывод X1 подключается к сигналу, а X2 остаётся неподключенным (висеть в воздухе.).

Ну и выводы SDA и SCL, с которыми мы познакомились в прошлой статье.

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

2. Ширину трассы также по возможности делать меньше, для уменьшения вероятности принятия помех с других источников.

3. Контур в виде защитного кольца необходимо поместить вокруг кристалла, что помогает изолировать кристалл от шума.

4. Проводники поместить в кольцо и и подключить к заземлению.

5. Припаиваем резонатор к земле. Если земля разведена верно и есть уверенность.

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

Как подключать разобрались. Идем далее – разберемся как с ним работать. RTC является программируемым и имеет 8 байт специальных регистров для его конфигурации и энергонезависимую статическую память 56 байтов. Для обмена информации необходима 2-х проводная шина данных, т.е. последовательная шина данных- который мы рассмотрели в прошлой статье. Итак для работы пробежимся по даташиту. Что нам необходимо:

Таблица регистров. Рисунок ниже. Первые восемь регистров – для вывода и программирования наших часов. При обращении по адресу 00H к 7-му биту(CH) и установкой его в 0 –запускаем часы. Хочется отметить, что конфигурация регистров может быть любая, поэтому при первом запуске необходимо его настроить под свои требования. Остальные семь битов единицы и десятки секунд.

01H – Минуты.
02H – Часы, которые настраиваются:
— Бит 6 – при 1 вывод 12 часовой формат, 0 – 24.
— Бит 5 – при 1 (при 12 часовом формате) PM , 0-AM
— Бит 5 – (при 24 ч формате) это вывод второго десятка часов (20-23часа.)
— Бит4 – первый десяток часов, остальные биты это единицы часов.
03H – день недели;
04H – дата;
05H – месяц года
06H – год.

Ну и последний регистр 07H. Данный регистр является управляющим.Где OUT отвечает за управление выводом SQW/OUT. Ниже таблица включения вывода.

OUT
SQWE
SQW/OUT
1
0
1
0
0
0

SQWE – при установке этого бита в,1 на вывода выходят импульсы с заданной частотой,которая устанавливается,битами RS1 и RS0.

Этот вывод нам не пригодится в проекте. Хотя для него я развел на плате дорожку. В качестве экспериментов может быть где то в будущем и применим, ведь здесь можно сделать прерывании в 1 с.

Теперь имея всю необходимую информацию, напишем функции для работы с часами. А также запустим проект в Proteus . Который будет иметь следующий вид:

Обратите внимание, что резонатор в Proteus, можно и не подключать к часам(обведенное красным).

На рисунке выведен терминал часов, который отображает время, которое в свою очередь привязано к системному времени. Терминал отладчика протокола I2C или TWI, на котором отображается время отправки и приема сигнала, где D0 – передаваемая команда, D1 - прием. Ниже я буду выводить скриншоты терминала с результатом работы программы.

Программа. Рассмотрев основные настройки часов напишем функцию инициализации.

/*Функция инициализации включает в себя установку скорости обмена данных по формуле(в предыдущей статье), установка пред делителя и включение модуля TWI*/
void init_DS1307 (void)
{
TWBR = 2; /*При частоте 1 МГц */
TWSR = (0 << TWPS1)|(0 << TWPS0); /*Пред делитель на 64*/
TWCR |= (1 << TWEN); /*Включение модуля TWI*/
}

void write_DS1307 (uint8_t reg, uint8_t time) /*передаем два параметра: адрес регистра, к которому будем обращаться и передаваемую информацию*/
{
/* Формируем состояние СТАРТ, выставляя разряды регистра управления*/
TWCR = (1<
/*Разрешить работу модуля TWEN; Сформировать состояние старт TWSTA; Сбросить флаг TWINT */
/*Ждем окончания формирования условия старт, т.е. пока не установится флаг, код статуса = 08*/
while (!(TWCR & (1<
/*Далее перелаем пакет адреса (адрес устройства). Содержимое пакета загружается в регистр TWDR*/
TWDR = 0xd0; /*0b1101000 + 0 – адрес + бит записи*/
/*Сбрасываем флаг для передачи информации*/
TWCR = (1<
/*Ждем установки флага*/
while (!(TWCR & (1<
/*передаем регистр к которому будем обращаться*/
TWDR = reg;
TWCR = (1<
while (!(TWCR & (1<
/*Передаем информацию для записи в байт регистра*/
TWDR = time;
TWCR = (1<
while (!(TWCR & (1<
/*формируем состояние СТОП*/
TWCR = (1<
}

В этой функции мы передали три байта, адрес устройства, адрес регистра и байт информации для записи в этот регистр и сформировали состояние СТОП.

Осталась последняя функция чтения. Ниже формат чтения.

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

Если мы будем обращаться к часам в формате чтения, то при повторном обращении к часам указатель сдвигается на один байт вниз включая 56 байт ОЗУ, от 00H до 3FH. При достижении последнего адреса, указатель переходит на адрес 00.

/*Функция чтения данных из DS1307*/
uint8_t read_DS1307 (uint8_t reg) /*Передаем адрес регистра*/
{
uint8_t time;
/*формируем состояние СТАРТ*/
TWCR = (1<
while (!(TWCR & (1<
TWDR = 0xd0; /*Передаем адрес + бит записи*/
TWCR = (1<
while (!(TWCR & (1<
TWDR = reg; /*Адрес регистра*/
TWCR = (1<
while (!(TWCR & (1<
/*формируем состояние ПОВСТАР*/
TWCR = (1<
while (!(TWCR & (1<
TWDR = 0xd1; /*Передаем адрес + бит чтения*/
TWCR = (1<
while (!(TWCR & (1<
/*считываем данные*/
TWCR = (1<
while (!(TWCR & (1<
time = TWDR;
time = (((time & 0xF0) >> 4)*10)+(time & 0x0F);
/*формируем состояние СТОП*/
TWCR = (1<
return time;
}

Итак выше мы написали три функции, которые нам необходимы для работы с часами. Используя эти функции запустим программу в Proteus. Выведем, например дату.

#include
#include
uint8_t time;
void init_DS1307 (void);
uint8_t read_DS1307 (uint8_t reg);
void write_DS1307 (uint8_t reg, uint8_t time);
int main (void)
{
DDRC = 0×00; /*Выставляем порт как вход*/
PORTC = 0xFF; /*Подтягиваем сопротивление*/
init_DS1307;
while (1)
{
_delay_ms (50);
read_DS1307 (0×04); /*Чтение регистра даты*/
}
}

Ниже результат выполнения программы чтение даты.

В окне отладчика I2C (TWI ) видно что сначала посылается адрес регистра в RTC (зеленый кружочек), в данном случае 04, который отвечает за дату месяца, и далее часы передают ответ 21 (красный кружочек).

Когда мы запустим часы в железе, нам необходимо будет занести настоящее время. Ниже пример программы изменения минут.

while (1)
{
_delay_ms (500);
read_DS1307 (0×01); /*Считываем минуту*/
_delay_ms (500);
write_DS1307 (0×01, 15); /*Записываем необходимую минуту*/
_delay_ms (500);
read_DS1307 (0×01); /*Считываем минуту*/
}

На рисунке видно, что сначала идет обращение к регистру 01, считывается минута 23. Далее мы используем функцию записи, и вносим значение 15. При следующей функции чтения у нас на табло часов значение 15.

Ну и последний пример программы это вывод значений всех регистров

while (1)
{
delay_ms (500);
read_DS1307 (0×00);
_delay_ms (500);
read_DS1307 (0×01);
_delay_ms (500);
read_DS1307 (0×02);
_delay_ms (500);
read_DS1307 (0×03);
_delay_ms (500);
read_DS1307 (0×04);
_delay_ms (500);
read_DS1307 (0×05);
_delay_ms (500);
read_DS1307 (0×06);
_delay_ms (500);
}

На рисунке ниже видно, что вывелись данные 7-ми регистров.

Исходник с проектом прилагается:

(Скачали: 601 чел.)

На этом все. В следующей статьеподключим часы в железе, выведем время на индикатор и познакомимся с двоично-десятичным форматом для работы с часами. Всем пока.

Вам также будет интересно:

Читы и консольные команды для Counter-Strike: Global Offensive Команда в кс го чтобы летать
В этой статье мы рассмотрим некоторые из наиболее полезных и забавных консольных команд в...
Arduino и четырехразрядный семисегментный индикатор Семисегментный индикатор 4 разряда распиновка
В сегодняшней статье поговорим о 7-сегментных индикаторах и о том, как их «подружить» с...
«Рабочие лошадки» Hi-Fi: собираем бюджетную систему Хороший бюджетный hi fi плеер
Выбор плеера - это сложный процесс, иногда человек желает получить не просто коробочку,...
Как правильно пользоваться сургучными печатями
На самом деле, сургуч - это смесь смол, окрашенная в определенный цвет. Если у вас на руках...
Лагает fallout 4 как снизить графику
10 ноября состоялся релиз долгожданной игры на ПК, PlayStation 4 и Xbox One, и постепенно...