Я использую Arduino и DS1307 для создания RTC, но мой код имеет некоторые проблемы
Я не получаю никаких ошибок, но значения, которые должны отображаться в RTC_read, по какой-то причине не отображаются. Первоначально я думал, что это может быть связано с тем, что код перехватывается где-то в цикле, но это не так. случай. Странно, когда я использую Serial.print() для некоторого значения, все значение не отображается
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
void i2c_init()
{
TWSR=0x00;
TWBR=0x47;
TWCR=(1<<TWEN);
}
void i2c_start()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void i2c_end()
{
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
while(!(TWCR&(1<<TWSTO)));
}
void i2c_write(uint8_t data)
{
TWDR=data;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
uint8_t i2c_read(int ack_val)
{
TWCR=(1<<TWINT)|(1<<TWEN)|(ack_val<<TWEA);
while(!(TWCR&(1<<TWINT)));
return TWDR;
}
void RTC_init()
{
i2c_init();
i2c_start();
i2c_write(11010000);
i2c_write(00000111);
i2c_write(00000000);
i2c_end();
}
void RTC_set_time_date(uint8_t second,uint8_t minute,uint8_t hour,uint8_t day,uint8_t month,uint8_t year)
{
i2c_start();
i2c_write(11010000);
i2c_write(00000000);
i2c_write(second);
i2c_write(minute);
i2c_write(hour);
i2c_write(day);
i2c_write(month);
i2c_write(year);
i2c_end();
}
void RTC_read()
{
char second,minute,hour,day,month,year;
i2c_start();
i2c_write(11010000);
i2c_write(00000000);
i2c_end();
i2c_start();
i2c_write(11010001);
second=i2c_read(1);
minute=i2c_read(1);
hour=i2c_read(1);
day=i2c_read(1);
month=i2c_read(1);
year=i2c_read(0);
i2c_end();
Serial.println(second);
Serial.println(minute);
Serial.println(hour);
Serial.println(day);
Serial.println(month);
Serial.println(year);
Serial.println("Recieving data");
}
int main()
{
Serial.begin(9600);
uint8_t second,minute,hour,day,month,year;
second=00000000;
minute=01000000;
hour=00100011;
day=00000011;
month=00000111;
year=00011001;
Serial.write("abcd");
RTC_init();
RTC_set_time_date(second,minute,hour,day,month,year);
RTC_read();
return 0;
}
@Crdy2k1, 👍0
Обсуждение1 ответ
Начнем с порядка регистров:
seconds -- bit 7 is clock start/stop bit, 0 = enabled
minutes
hours -- bit 6 is selector 12/24 hour,
-- when in 12 hour, bit 5 is am/pm, 1=pm
-- When in 24 hour, bit 5 indicates in hour 20...23
day -- week day 1...7
date -- day of month 1...31
-- where the most significant nibble can contain the values
-- 0, 1, 2, 3
-- where the least significant nibble can contain the values
-- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
month -- 0x1x indicates in upper 10 months
year
control
<other ram>
При записи этих регистров предыдущее время переносится на фон/изображение основных регистров.
Ключевое значение имеет бит подтверждения, который отображается в конце каждого передаваемого байта. Вот подробности:
DS13077 of 12Acknowledge: Каждое принимающее устройство при обращении к нему обязано генерировать подтверждение после приема каждого байта. Ведущее устройство должно генерировать дополнительный тактовый импульс, который связан с этим битом подтверждения. Устройство, которое подтверждает, должно опустить линию SDA во время тактового импульса подтверждения таким образом, чтобы линия SDA была стабильно НИЗКОЙ в течение ВЫСОКОГО периода времени, связанного с подтверждением. часовой пульс. Конечно, необходимо учитывать время установки и удержания. Ведущее устройство должно сигнализировать подчиненному об окончании данных, не генерируя бит подтверждения в последнем байте, который был тактирован из подчиненного устройства. В этом случае ведомое устройство должно оставить линию данных ВЫСОКОЙ, чтобы ведущее устройство могло сгенерировать условие СТОП
Итак, первая проблема, которую я вижу, это то, что последовательность кода не соответствует последовательности регистров. Это ошибка.
вторая проблема, которую я вижу, это то, что биту ACK
присваивается неправильное значение
- Как вызвать функции C из скетча ардуино?
- max7219 связанный дисплей, показывающий зеркальный текст
- Пиринговая коммуникация
- Запуск С для ардуино
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Прерывание ардуино при смене контакта
- GSM-модуль IOT-GA6 Arduino + ошибка CME 58
- Разница между массивом char и массивом unsigned char
это не скетч ардуино, @Juraj
присвоение чисел в main() не является двоичным... это восьмеричное присвоение...
minute=01000000;
равно 262144 минутам.... но загруженное вuint8_t
оно равно нулю минут, @jsotolaНа самом деле значения, записанные (или прочитанные) в устройство, имеют формат BCD, а не двоичный и не восьмеричный., @user3629249
вы пытаетесь запустить RTC в 12- или 24-часовом режиме?, @user3629249
с учетом регистра
минут
. 0x00 - 0 минут. 0x59 составляет 59 минут. Самый значащий полубайт имеет допустимый диапазон 0...5, младший значащий полубайт имеет допустимый диапазон 0...9., @user3629249в функции:
i2c_start()
делает:TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
включает часы и устанавливает линию данных для изменения с низкого уровня на высокий во время высокая часть такта? Т.Е. управляющая последовательность «СТАРТ»?, @user3629249