Глюк с DS1307

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 56
Зарегистрирован: Вт май 01, 2007 19:27:30

Сообщение duss1981 »

Коллеги, пишу прогу для работы с DS1307 для atmega 8. Имею странный глюк, при чтении данных из DS1307 функцией (функция состоит из команд запись и чтения регистров) данные считываются, но затем происходит запись в 7 регистр данных D0 07 90 (этой команды в программе нет вообще). Если команды записи и чтения прописать в функции main, то все работает хорошо.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

И чо? ошибка у вас где-то.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Не совсем понял, как эти данные - три байта - помеещаются в один седьмой регистр.

Последний байт с NOACK читается хоть?
Контактная информация:
Открыл глаза
Сообщения: 56
Зарегистрирован: Вт май 01, 2007 19:27:30

Сообщение duss1981 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3221308#p3221308"]Не совсем понял, как эти данные - три байта - помеещаются в один седьмой регистр.

Последний байт с NOACK читается хоть?[/uquote]
последний считается в обоих случаях. Без него все просто останавливалось.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

У меня в вопросе ударение было не на "читается", а на "NOACK".
А вообще, гадать на кофейной гуще, не видя кода - смысла мало.
Контактная информация:
Реклама
Открыл глаза
Сообщения: 56
Зарегистрирован: Вт май 01, 2007 19:27:30

Сообщение duss1981 »

Вот код функции. Немного понял, после выхода из функции происходит перезагрузка МК. Из-за чего заново инициализируется DS1307, но вместо байта данных 00 записывается 90. См. лог во вложении.
Сама функция
void rtc_gettime(unsigned char *hour,unsigned char *min,unsigned char *sec){

I2CStart();
if (I2CWriteByte(0xd0));
if (I2CWriteByte(0x00));
//I2CStop();

I2CStart();
if (I2CWriteByte(0xd1));
if (I2CReadByte(*sec,1));
if (I2CReadByte(*min ,1));
if (I2CReadByte(*hour,0));
I2CStop();
}

P.S. разобрался был перезагруз МК из-за другой функции. Хотя странный в ней был switch от 0 до 9. при вводе в процедуру числа 10, был перезагруз, добавил default тоже самое, пришлось сдeлать проверку if.
Вложения
QIP Shot - Screen 100.png
(47.98 КБ) 242 скачивания
Последний раз редактировалось duss1981 Ср ноя 01, 2017 06:50:39, всего редактировалось 1 раз.
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

А if() зачем?

Опять же, кода недостаточно. Мы не знаем, например, выделена ли память под указатели *sec, *min и *hour. Вангую, что нет, и от этого и перезагрузки МК.

А вообще красивее было бы иметь структуру для хранения времени, и читать в неё. Т.е. что-то вроде:
Спойлер

Код: Выделить всё

typedef struct {
	uint8_t sec;
	uint8_t min;
	uint8_t hour;
} Time_t;

Time_t time;

void rtc_gettime(Time_t *t)
{
  I2CStart();
  if (I2CWriteByte(0xd0));
  if (I2CWriteByte(0x00));

  I2CStart();
  I2CWriteByte(0xd1);
  I2CReadByte(&t->sec, 1);
  I2CReadByte(&t->min, 1);
  I2CReadByte(&t->hour, 0);
}

int main()
{
  ...
  rtc_gettime(&time);
  ...
}
Последний раз редактировалось WiseLord Ср ноя 01, 2017 06:59:14, всего редактировалось 4 раза.
Контактная информация:
Открыл глаза
Сообщения: 56
Зарегистрирован: Вт май 01, 2007 19:27:30

Сообщение duss1981 »

Чтобы сделать проверку что число в диапазоне, говорю default не работает, точнее с ним тоже перезагруз был
ниже пример
switch (digit) {
case 0:
PORTD=0x5F;
break;
case 1:
PORTDIG=0x0C;
break;
case 2:
PORTDIG=0x3B;
break;
case 3:
PORTDIG=0x3E;
break;
case 4:
PORTDIG=0x6C;
break;
case 5:
PORTDIG=0x76;
break;
case 6:
PORTDIG=0x77;
break;
case 7:
PORTDIG=0x1C;
break;
case 8:
PORTDIG=0x7F;
break;
case 9:
PORTDIG=0x7E;
break;
default:
PORTDIG=0x00;
break;
}
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Неужели трудно:
а) помещать код в тег

Код: Выделить всё

?
б) поместить в этот тег ВЕСЬ код целиком, а не жалкие огрызки?

[quote="duss1981"]Чтобы сделать проверку что число в диапазоне, говорю default не работает, точнее с ним тоже перезагруз был
ниже пример[/quote]вот что должно быть мне понятно из этого вашего "примера"? какую цель он преследовал? продемонстрировать ваш навык писать switch методом copy-paste?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

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

PS: Пора уже наверное просто начинать игнорить подобные темы. Пусть люди учатся вопросы нормально задавать, со всеми прикреплёнными максимально-необходимыми данными.
Контактная информация:
Открыл глаза
Сообщения: 56
Зарегистрирован: Вт май 01, 2007 19:27:30

Сообщение duss1981 »

Я говорю перезагруз был если в switch попадало число более 9, пробовал вводит переменнную более 9.
Вот исправленная процедура получения времени (см. ниже), а вот вызов ее main rtc_get_time(&hour,&min,&sec);.
В процедуру передаются адреса переменных (&sec и т.д.), эти адреса передаются функции I2CReadByte(sec,1) без указателя )
сама функция I2CReadByte(sec,1) берет адрес переменной и записывает туда нужное значение. Если ее вызвать напрямую то получится I2CReadByte(&sec,1). Это конечно все учебниках написано, но каждый учится на своих ошибках.

void rtc_get_time(unsigned char *hour,unsigned char *min,unsigned char *sec){
I2CStart();
if (I2CWriteByte(0xd0));
if (I2CWriteByte(0x00));
//I2CStop();

I2CStart();
if (I2CWriteByte(0xd1));
if (I2CReadByte(sec,1));
if (I2CReadByte(min ,1));
if (I2CReadByte(hour,0));
I2CStop();

}
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Аlex писал(а):Пора уже наверное просто начинать игнорить подобные темы
пора :beer:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

duss1981 писал(а):запись в 7 регистр данных D0 07 90 (этой команды в программе нет вообще)
Вот видео демонстрации записи в 7-ой регистр DS1307.
А вот видео демонстрации что default работает.

И действительно

Код: Выделить всё

if (I2CWriteByte(0xd0));
зачем if()?
Ответить

Вернуться в «AVR»