|
DS1338 + XMEGA |
|
|
|
Jul 6 2011, 12:14
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
В даташите на эти часики указаны 2 режима работы: Fast mode(400КГц), Standart mode(100КГц). В меге инициализирован RC на 32Мгц. Как между собой связать скорости. или какое время нужно давать при задержке. При коде следующего вида никаких изменений не происходит.. CODE void rtc_init() { RTC_DATA_DIR_SET; RTC_DATA_SET; RTC_SCL_UP; delay_us(1); } void rtc_start() { RTC_DATA_CLR; delay_us(1); RTC_SCL_DOWN; delay_us(1); }
void rtc_stop() {
RTC_SCL_UP; delay_ms(1); RTC_DATA_DIR_SET; RTC_DATA_SET; delay_ms(1); }
void rtc_write (unsigned char buffer) { unsigned char MASK; RTC_DATA_DIR_SET; for(i=8;i>=0;--i) { if(buffer&&MASK ) RTC_DATA_SET; else RTC_DATA_CLR; RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); MASK>>1; }
RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); } unsigned char read_rtc() { unsigned char buffer=0; RTC_DATA_DIR_CLR; for(i=8;i>=0;--i) { buffer|=((buffer<<1)||(PORTE.IN&PIN3_bm)); RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); } return buffer; }
void RTC_ACKNOWLEGDGE_0() { RTC_DATA_DIR_SET; RTC_DATA_SET; delay_ms(1); RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); }
void RTC_ACKNOWLEGDGE_1() { RTC_DATA_DIR_SET; RTC_DATA_CLR; delay_ms(1); RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); }
Сообщение отредактировал IgorKossak - Jul 6 2011, 20:08
Причина редактирования: [codebox]!!!
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Jul 7 2011, 04:55
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Код void rtc_write (unsigned char buffer) { unsigned char MASK; RTC_DATA_DIR_SET; for(i=8;i>=0;--i) { ... MASK>>1; .... } ............. ............. } 1. Где первоначальное задание значения MASK ?? (по умолчанию=0) 2. MASK>>1; - переменная сдвигается (ноль сдвинуть влево!!) , но никуда не записывается, надо "MASK>>=1;" Код unsigned char read_rtc() { unsigned char buffer=0; RTC_DATA_DIR_CLR; for(i=8;i>=0;--i) { buffer|=((buffer<<1)||(PORTE.IN&PIN3_bm)); RTC_SCL_UP; delay_ms(1); RTC_SCL_DOWN; delay_ms(1); } return buffer; } Значение с шины надо считывать ПОСЛЕ подачи тактового сигнала! И вообще, где код вызывающий эти функции, сами они никогда не исполнятся?
|
|
|
|
|
Jul 7 2011, 06:04
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата Значение с шины надо считывать ПОСЛЕ подачи тактового сигнала! Это пропустил. Цитата unsigned char MASK; ошибка при копировании. unsigned char MASK=0х80 Цитата И вообще, где код вызывающий эти функции, сами они никогда не исполнятся? Собственно код Код rtc_start(); //старт rtc_write (DS1338W); // адрес устройства, + запись. DS1338W=0xD0 rtc_write (SecondsReg); // Регистр секунд rtc_write (0x7f); rtc_write (0x3f); rtc_write (0xff); rtc_write (0xff); rtc_write (0xff); rtc_write (0xff); rtc_write (0xff); rtc_stop();
//При чтении rtc_start(); rtc_write (DS1338R); // адрес устройства, + чтение DS1338R=0xD1 RTC_ACKNOWLEGDGE_1(); rtc_write (SecondsReg); RTC_ACKNOWLEGDGE_1(); rtcTime.seconds=read_rtc(); RTC_ACKNOWLEGDGE_1(); rtcTime.minutes=read_rtc(); RTC_ACKNOWLEGDGE_1(); rtcTime.hours=read_rtc(); RTC_ACKNOWLEGDGE_1(); rtcTime.day=read_rtc();; RTC_ACKNOWLEGDGE_1(); rtcTime.date=read_rtc(); RTC_ACKNOWLEGDGE_1(); rtcTime.month=read_rtc(); RTC_ACKNOWLEGDGE_1(); rtcTime.year=read_rtc(); RTC_ACKNOWLEGDGE_0(); rtc_stop();
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 06:06
|
|
|
|
|
Jul 7 2011, 06:39
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
1. А это исправил? Цитата 2. MASK>>1; - переменная сдвигается (ноль сдвинуть влево!!) , но никуда не записывается, надо "MASK>>=1;" 2. Посмотри осциллографом сигналы на шине, в частности наличие сигнала АСК от часов 3. Формат записи в регистры не правильный Код rtc_write (SecondsReg); // Регистр секунд rtc_write (0x7f); rtc_write (0x3f); rtc_write (0xff); rtc_write (0xff); rtc_write (0xff); rtc_write (0xff); Из даташита:
то есть время/дата записывается в формате BCD 4. Общие замечания: имена макросов - прописными буквами, локальных переменных - строчными, глобальных переменных и функций - не полностью прописными 5. Где объявлены переменные i в rtc_write и read_rtc? По сути они должны быть локальные, а не глобальные
Сообщение отредактировал alexeyv - Jul 7 2011, 06:46
|
|
|
|
|
Jul 7 2011, 07:18
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата 1. А это исправил? написал по другому if(buffer&&0x80) .... buffer=buffer<<1; Цитата 2. Посмотри осциллографом сигналы на шине, в частности наличие сигнала АСК от часов Нету высокого уровня сигнала тактирования Цитата Формат записи в регистры не правильный Знаю, но щас смысл передать хоть что-то Цитата 4. Общие замечания: имена макросов - прописными буквами, локальных переменных - строчными, глобальных переменных и функций - не полностью прописными кто как привык.. Цитата 5. Где объявлены переменные i в rtc_write и read_rtc? По сути они должны быть локальные, а не глобальные Перевел в локальную. Была глобальная
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 07:37
|
|
|
|
|
Jul 7 2011, 07:52
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
1. А не забыл в rtc_init что-то типа RTC_SCL_DIR_SET; ?? 2. Не правильно!! Цитата написал по другому
if(buffer&&0x80) Это у тебя логическое выражение, а тебе надо битовое, вместо "&&" надо использовать "&" 3. Цитата кто как привык.. Судя по коду, ты еще не привык. Так что привыкай использовать принятые соглашения. Почитай книжку Ален И. Голуб. "ВЕРЕВКА ДОСТАТОЧНОЙ ДЛИНЫ, ЧТОБЫ…" Москва 2001г. Будет интересно.
Сообщение отредактировал alexeyv - Jul 7 2011, 08:03
|
|
|
|
|
Jul 7 2011, 08:11
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
RTC_SCL_DIR_SET; в инициализации портов Цитата Это у тебя логическое выражение, а тебе надо битовое, вместо "&&" надо использовать "&" "&"="*" "&&"="и" За книжку отдельное спасибо.
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 08:18
|
|
|
|
|
Jul 7 2011, 08:36
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата "&"="*" "&&"="и" Неужели!!!! Почитай еще книгу "Д. Ричи. Б. Керниган. Язык Си." Желательно 2-е издание. "&" == порязрядное "И" "&&" == логическое "И" можешь проверить: Код 0x02 & 0x04 == 0x00; 0x06 & 0x04 == 0x04; 0x02 && 0x04 == 0x01; 0x02 * 0x04 == 0x08; Цитата RTC_SCL_DIR_SET; в инициализации портов В первом листинге не было!!!
Сообщение отредактировал alexeyv - Jul 7 2011, 08:39
|
|
|
|
|
Jul 7 2011, 08:51
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата В первом листинге не было!!! я в листинг не включал.
|
|
|
|
|
Jul 7 2011, 09:01
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата я в листинг не включал. Так может ошибки в тех местах, которых нет в листинге? Весь код относящийся к одному определенному объекту нужно держать в одном месте, а не размазывать по всей программе
|
|
|
|
|
Jul 7 2011, 09:09
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата(alexeyv @ Jul 7 2011, 12:01)  Так может ошибки в тех местах, которых нет в листинге? Весь код относящийся к одному определенному объекту нужно держать в одном месте, а не размазывать по всей программе Есть первый шаг. Получил ответ от часиков в виде данных: 248 из все регистров. (я так понимаю что это 0xff или пустое место памяти)
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 09:14
|
|
|
|
|
Jul 7 2011, 09:29
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата(alexeyv @ Jul 7 2011, 12:17)  Только 248=0xF8, а 0xFF=255. )) Это пустое место? по поводу Acknowledge. При записи между байтами необходимо ждать 0 в DATA А при чтении отправлять?
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 10:16
|
|
|
|
|
Jul 7 2011, 10:23
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
В функции rtc_write после цикла выставления байта на шину, необходимо выставить данные=1, для того, что бы после дополнительного клока проанализировать принятый от часов бит АСК Цитата А при чтении отправлять? Да. Бит АСК всегда формирует приемник. При записи - это часы, при чтении - проц. При чтении последнего байта - формирование NACK
Сообщение отредактировал alexeyv - Jul 7 2011, 10:25
|
|
|
|
|
Jul 7 2011, 10:36
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Код bool RTC_ACKW() { RTC_DATA_DIR_CLR; RTC_SCL_DOWN; delay_us(100); RTC_SCL_UP; while(PORTE.IN&PIN3_bm!=0); delay_us(100); RTC_SCL_DOWN; delay_us(100); return 1; }
void RTC_ACKR() { RTC_DATA_DIR_SET; RTC_DATA_SET; delay_us(100); RTC_SCL_UP; delay_us(100); RTC_SCL_DOWN; delay_us(100); } так пойдет?
Сообщение отредактировал Pavel_Bor - Jul 7 2011, 10:43
|
|
|
|
|
Jul 7 2011, 10:56
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
функцию контроля АСК проще сделать не отдельно, а в rtc_write - выдавать как результат работы функции функцию посылки АСК проще сделать не отдельно, а в read_rtc - принимать как параметр 1= выдача АСК, 0 - выдача НАК Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть? Посмотри здесьОссобенно изучи пост №18.
Сообщение отредактировал alexeyv - Jul 7 2011, 11:05
|
|
|
|
|
Jul 7 2011, 11:04
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть? Подтяжек нет. Цитата Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть? Подтяжек нет. Цитата В функции rtc_write после цикла выставления байта на шину, необходимо выставить данные=1, для того, что бы после дополнительного клока проанализировать принятый от часов бит АСК Направление порта должно быть входом иначе не видно будет АСК. Но какой тогда смысл выставлять данные в 1?
|
|
|
|
|
Jul 7 2011, 11:09
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата Направление порта должно быть входом иначе не видно будет АСК. Но какой тогда смысл выставлять данные в 1? В смысле необходимо переключить порт (DDR_X) как вход, но перед этим записать в PORT_X единицу - этим включаются подтягивающие резисторы на порту посмотри пост №18в архиве - исходники
|
|
|
|
|
Jul 7 2011, 11:21
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Цитата(alexeyv @ Jul 7 2011, 14:09)  В смысле необходимо переключить порт (DDR_X) как вход, но перед этим записать в PORT_X единицу - этим включаются подтягивающие резисторы на порту посмотри пост №18в архиве - исходники а внешние подтягивающие резисторы в схеме нужны?
|
|
|
|
|
Jul 8 2011, 03:00
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата(Pavel_Bor @ Jul 7 2011, 16:21)  а внешние подтягивающие резисторы в схеме нужны? Подтягивающие резисторы обычно рекомендуют ставить. У меня недавно был клюк. На линиях TWI, видать в целях экономии места на плате, не поставили подтяжку. При этом, при касании осциллографом любой из линий, процессор вылетал в неизвестно куда. Пришлось напаять резисторы и проблема исчезла. Нормально отлаженая программа также хорошо работала и без подтягивающих резисторов. Но эта проблема была только на линиях аппаратного TWI. При программной реализации все работало и без подтяжек.
Сообщение отредактировал alexeyv - Jul 8 2011, 03:00
|
|
|
|
|
Jul 8 2011, 07:23
|
Частый гость
 
Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660

|
Я так понимаю время задержки между тактами значения не имеет. Главное чтобы оно было больше минимального. Когда программа получает АСК, пока SCL в "1" ACK никуда не денется до тех пор пока SCL не станет "0"? Есть шаг №2. Читаю с регистров 0. Пошли часы) Не получается записать в регистры новые значения. текущий программа для записи: Код void i2c_tx_soft(unsigned char byte) { unsigned char count; RTC_DATA_DIR_SET; if(i2c_error_soft) return; for(count=0;count<8;count++) { if(byte&0x80) RTC_DATA_SET; else RTC_DATA_CLR; RTC_SCL_UP; delay_ms(5); RTC_SCL_DOWN; delay_ms(5); byte<<=1; } RTC_DATA_DIR_CLR; RTC_SCL_UP; delay_ms(5); while(in_sda()); delay_ms(5); RTC_SCL_DOWN; delay_ms(5); RTC_DATA_DIR_SET; } Вызов ее вот отсюда Код void rtc_set_time(unsigned char hours, unsigned char minutes, unsigned char seconds) { i2c_start_soft(); i2c_tx_soft(DS1338_ADDR|WR); i2c_tx_soft(0); i2c_tx_soft(dec2bcd(seconds)); i2c_tx_soft(dec2bcd(minutes)); i2c_tx_soft(dec2bcd(hours));
i2c_stop_soft(); }
void rtc_set_date(unsigned char date, unsigned char month, unsigned int year) { i2c_start_soft(); i2c_tx_soft(DS1338_ADDR|WR); i2c_tx_soft(3); i2c_tx_soft(dec2bcd(rtcTime.day)); i2c_tx_soft(dec2bcd(date)); i2c_tx_soft(dec2bcd(month)); i2c_tx_soft(dec2bcd(year)); i2c_stop_soft(); }
Сообщение отредактировал Pavel_Bor - Jul 8 2011, 12:11
|
|
|
|
|
Jul 11 2011, 04:39
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата while(in_sda()); Во время подачи клока, по одному фронту производится выставление данных передатчиком(в данном случае мастером), а по другому фронту - считывание приемником ( в данном случае слейвом)! Ждать до бесконечности появления нуля на шине SDA (ACK) НЕЛЬЗЯ, т.к. при подаче фронта SCL слейв ОБЯЗАН выставить ACK, иначе это говорит об отсутствии устройства (слейва) на шине! Посмотри осциллографом физическое наличие сигнала АСК на шине. Еще вопрос - какие-либо прерывания в программе используются ?
|
|
|
|
|
Jul 11 2011, 12:10
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата Прерываний будет много но со временем. (клавиатура, АЦП, УАРТ...) Тогда желательно в функциях чтения/записи I2C расставить: 1. в начале обмена - сохранение регистра статуса и глобальный запрет прерываний 2. в конце обмена - восстановление регистра статуса Это необходимо для сохранения временных параметров доступа к шине.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|