реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> DS1307 может оживить время?, Помогите прочитать с DS1307 больше одного байта! плиз..
AVRdeveloper
сообщение Jul 24 2008, 12:43
Сообщение #1





Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857



Всем доброе время суток! У меня проблема с DS1307. Использую Мегу16
После инициализации МК произвожу чтение с этой МС раз в секунду таким способом:
Первый байт принимаеться каждый раз с новым значением, а второй - постоянно $FF
Как принять последовательность из нескольких байт?


call TWI_init ; инитим I2C МК
call TWI_stop
call TWI_start
ldi r16,0b11010001
call TWI_send_adr
ldi r16,0 ; r16 используеться для передачи след. ф.-ии значений
call TWI_send_data
call get_byte1 ; При приеме первого байта считываеться случаqное число регистра данных TWI
call get_byte2 ; При приеме второго байта постоянно принимается $FF
call TWI_stop
..
..
..
TWI_init:
ldi r16,(0<<TWPS0)|(1<<TWPS1)
out TWSR,r16
ldi r16,9 ; битрейт при частоте 8МГц меньше 100кГц
out TWBR,r16
ldi r16,(1<<TWEA)|(1<<TWEN)|(0<<TWIE);
out TWCR,r16
ret
;
;
TWI_start:

ldi r16, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR, r16; формирование режима START

waitST:
in r16,TWCR ; Проверка бита TWINT
sbrs r16,TWINT
rjmp waitST ; Не получен TWINT - цикл

RETURN:
ret

TWI_send_adr:

// проверим, что предидущее состояние было старт
// в регистре r16 содержится адрес адрессуемого устройства
push r16

in r16,TWSR ; Проверка кода ответа
andi r16,0xF8
cpi r16,$08
breq dalee11
cpi r16,$10
breq dalee11 ; Правильный код -выход из подпрограммы
brne TWI_error ; Нет - повтор.

dalee11:
pop r16
out TWDR, r16
ldi r16, (1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(0<<TWIE)
out TWCR, r16



wait2:
in r16,TWCR
sbrs r16,TWINT
rjmp wait2
// передача не происходит? или установка флага не происходит из-за другой причины?
in r16,TWSR
andi r16, 0xF8
cpi r16, $18
breq tsa_00
cpi r16, $40
brne TWI_ERROR
tsa_00:
ret
;
get_byte1:
in r16,TWCR
sbrs r16,TWINT
rjmp get_byte1
in r16,twdr
ldi XH,high(secs_twi1)
ldi XL,low(secs_twi1)
st x,r16 // Секунды в БЦД формате записали
ldi r16,(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(0<<TWIE)
out TWCR,r16
ret
;
;
get_byte2:
in r16,TWCR
sbrs r16,TWINT
rjmp get_byte2
in r16,twdr
ldi XH,high(secs_twi2)
ldi XL,low(secs_twi2)
st x,r16 // Секунды в БЦД формате записали
ldi r16,(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(0<<TWIE)
out TWCR,r16
ret
;
TWI_send_data:
out TWDR, r16
ldi r16, (0<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR, r16;
wait3:
sei
nop
cli
in r16,TWCR
sbrs r16,TWINT
rjmp wait3
in r16,TWSR
andi r16, 0xF8
cpi r16, $28;MT_DATA_ACK
breq tsa_01
cpi r16,$58
breq tsa_01
cpi r16,$50
brne TWI_error
TSA_01:
ret

Сообщение отредактировал AVRdeveloper - Jul 24 2008, 12:44
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 24 2008, 13:09
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



ACK, нaверное, не выставляется после 1-о чтения.
Go to the top of the page
 
+Quote Post
Шалапут:-)
сообщение Jul 24 2008, 13:55
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 11-01-07
Пользователь №: 24 303



Цитата(aaarrr @ Jul 24 2008, 16:09) *
ACK, нaверное, не выставляется после 1-о чтения.

При приёме первого байта
get_byte1:
in r16,TWCR
sbrs r16,TWINT
rjmp get_byte1
in r16,twdr
ldi XH,high(secs_twi1)
ldi XL,low(secs_twi1)
st x,r16 // Секунды в БЦД формате записали
ldi r16,(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(0<<TWIE); Флаг (1<<TWEA) - для формирования АСК!
out TWCR,r16
ret

Ещё:
TWEA - TWI Enable Acknowledge Bit
Я устанавливаю этот бит после и перед приемом (т.е. после отправки адресса), и после приема первого байта..
наверное, АСК выставляеться...


--------------------
Роботы делают роботов - предел автоматизации
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jul 24 2008, 14:24
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



TWI_send_data:
out TWDR, r16
ldi r16, (0<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR, r16;

Ничего, что здесь разрешаете прерывания от twi?

И при выходе по ошибке из TWI_send_adr у Вас портится стек (в нем остается R16).
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 24 2008, 14:27
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Шалапут:-) @ Jul 24 2008, 16:55) *
TWEA - TWI Enable Acknowledge Bit
Я устанавливаю этот бит после и перед приемом

TWEA нужно устанавливать перед приемом НЕ последнего байта данных. Во всех остальных случаях его устанавливать не нужно и даже вредно.
Go to the top of the page
 
+Quote Post
AVRdeveloper
сообщение Jul 25 2008, 05:23
Сообщение #6





Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857



Цитата(Александр Куличок @ Jul 24 2008, 17:24) *
TWI_send_data:
out TWDR, r16
ldi r16, (0<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR, r16;

Ничего, что здесь разрешаете прерывания от twi?

И при выходе по ошибке из TWI_send_adr у Вас портится стек (в нем остается R16).

Ой... точно.. а я то думаю, почему МК паразагружаеться при ошибке.. Исправил.
И запретил прерывания при отправке данных. Сейчас узнаем, что происходит smile3046.gif
Go to the top of the page
 
+Quote Post
AVRdeveloper
сообщение Jul 25 2008, 14:56
Сообщение #7





Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857



Цитата(AVRdeveloper @ Jul 25 2008, 08:23) *
Ой... точно.. а я то думаю, почему МК паразагружаеться при ошибке.. Исправил.
И запретил прерывания при отправке данных. Сейчас узнаем, что происходит smile3046.gif

Всё равно, второй байт постоянно FF...

После чтения первого байта из TWDR устанавливаю разрешение АСК:

get_byte1:
in r16,TWCR
sbrs r16,TWINT
rjmp get_byte1
in r16,twdr
ldi XH,high(secs_twi1)
ldi XL,low(secs_twi1)
st x,r16
ldi r16,(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(0<<TWIE); бит TWEA = 1
out TWCR,r16
ret

Значит, второй байт должен быть отправлен микросхемой на шину..
Я думаю проблема может быть в протоколе обмена:
По даташиту:
При чтении из DS1307 нужно сделать Старт -> Отправка адреса(R/W = 1), проверяем АСК-> читаем байт, делаем АСК-> читаем байт, делаем неАСК->Стоп

В этом случае программа при отладке ведёт себя нормально, даже считываються разные значения 2-х байтов..А при запуске в реал-тайм прога зацикливаеться в этом месте при формировании старт:
waitST:
in r16,TWCR
sbrs r16,TWINT
rjmp waitST


Как делаю я:
Старт -> Отправка адреса(R/W = 1), проверяем АСК-> Отправляю "0" -> читаем байт, делаем АСК-> читаем байт, делаем неАСК->Стоп
В таком режиме читаеться первый байт
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jul 25 2008, 17:41
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(AVRdeveloper @ Jul 25 2008, 18:56) *
Как делаю я:
Старт -> Отправка адреса(R/W = 1), проверяем АСК-> Отправляю "0" -> читаем байт, делаем АСК-> читаем байт, делаем неАСК->Стоп
В таком режиме читаеться первый байт

По логике работы шины надо чуть изменить:
Старт -> Отправка адреса(R/W = 1), проверяем АСК->делаем АСК-> Отправляю "0" -> читаем байт->делаем неАСК-> читаем байт->Стоп
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 25 2008, 22:12
Сообщение #9


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(AVRdeveloper @ Jul 25 2008, 17:56) *
Старт -> Отправка адреса(R/W = 1), проверяем АСК-> Отправляю "0" -> читаем байт, делаем АСК-> читаем байт, делаем неАСК->Стоп

Что значит - "Отправляю "0"?
В SLA-R ничего отправлять нельзя, это не SPI где можно и читать и писать одновременно.

Цитата
По логике работы шины надо чуть изменить:

и еще чуть изменить:
Цитата
Старт -> Отправка адреса(R/W = 1), проверяем АСК->делаем АСК-> Отправляю "0" -> читаем байт->делаем неАСК-> читаем байт->Стоп



Цитата
После чтения первого байта из TWDR устанавливаю разрешение АСК:

Не после чтения, а перед нужно устанавливать.
Я же ж написал выше
Цитата
TWEA нужно устанавливать перед приемом НЕ последнего байта данных. Во всех остальных случаях его устанавливать не нужно и даже вредно.
Go to the top of the page
 
+Quote Post
AVRdeveloper
сообщение Jul 28 2008, 07:14
Сообщение #10





Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857



Цитата(defunct @ Jul 26 2008, 01:12) *
Старт -> Отправка адреса(R/W = 1), проверяем АСК->делаем АСК-> читаем байт->делаем неАСК-> читаем байт->Стоп

Сделал так. с JTAG в пошаговой эмуляции работает.. читаються разные байты данных.. а если программу запустить в реал тайме, она зацыкливаеться в месте проверки флага TWINT, после формирование сост. "Старт"..
Ещё: Поменял частоту TWI. Для 8 МГц она = 97,56 кГц
TWI_init:
ldi r16,(0<<TWPS0)|(0<<TWPS1)
out TWSR,r16
ldi r16,21 // 97кГц
out TWBR,r16
ldi r16,(1<<TWEA)|(1<<TWEN)|(0<<TWIE)
out TWCR,r16
ret

Сообщение отредактировал AVRdeveloper - Jul 28 2008, 07:18
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 28 2008, 09:58
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(AVRdeveloper @ Jul 28 2008, 10:14) *
TWI_init:
...
ldi r16,(1<<TWEA)|(1<<TWEN)|(0<<TWIE)

не надо TWEA где попало ставить.
Посмотрите еще раз где он должен быть!
Go to the top of the page
 
+Quote Post
AVRdeveloper
сообщение Jul 28 2008, 12:37
Сообщение #12





Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857



Цитата(defunct @ Jul 28 2008, 12:58) *
не надо TWEA где попало ставить.
Посмотрите еще раз где он должен быть!

Убрал 1<<TWEA с инициализации..
теперь последовательность выполняемых подпрограмм такая (выполняем раз в секунду):

call TWI_start
ldi r16,0b11010001
call TWI_send_adr
call get_byte1
call get_byte2
call TWI_stop

При отладке в пошаговом режиме программа выполняеться, а реал-тайм зависает при втором опросе DS1307 в ожидании установки флага TWINT в подпрограмме TWI_start..

Подпрограммы в приложении.Прикрепленный файл  TWI.txt ( 1.58 килобайт ) Кол-во скачиваний: 271
Go to the top of the page
 
+Quote Post
OlegH
сообщение Jul 30 2008, 13:57
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 14-01-06
Из: Украина, г.Харьков
Пользователь №: 13 168



вот мои библиотеки для работы с DS1307 для IAR C, Mega16 (может помогут)...

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

DS1307_WriteByte(7, 0x80); // No output on pin 7
if (DS1307_Read(0)==0 AND (DS1307_Data & 0x80)) DS1307_WriteByte(0, 0);


Периодически читаем время c помощью:

DS1307_ReadRTC();

Сообщение отредактировал Олег Хохлов - Jul 30 2008, 14:00
Прикрепленные файлы
Прикрепленный файл  i2c_ds1307.zip ( 2.12 килобайт ) Кол-во скачиваний: 92
 
Go to the top of the page
 
+Quote Post
Шалапут:-)
сообщение May 17 2012, 09:12
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 11-01-07
Пользователь №: 24 303



Всем спасибо, ваши советы помогли, но все равно перешел на Си, где все заработало сразу)


--------------------
Роботы делают роботов - предел автоматизации
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение May 17 2012, 11:49
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Шалапут:-) @ May 17 2012, 13:12) *
Всем спасибо, ваши советы помогли, но все равно перешел на Си, где все заработало сразу)

Да как быстро летит время . 4 - года и всё таки помогли советы lol.gif


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 15:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01505 секунд с 7
ELECTRONIX ©2004-2016