Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.224.37.68] |
|
Сообщ.
#1
,
|
|
|
Написал программный протокол I2C для чтения времени с DS1307, эмулирую пока в протеусе для отладки. Проблема с чтением, запись проходит отлично!
Вот схема http://s5.hostingkartinok.com/uploads/imag...64c70309d93.png Прошу обратить внимания что дата выставлена, и в памяти DS1307 находятся данные Далее я пытаюсь их считать, алгоритм таков 1. старт 2. отправляю 0b11010000 - адрес часов 3. ACK - ответ от слэйва 4. отправляю 0 - адрес секунд 5. ACK - ответ от слэйва 6. старт 7. отправляю 0b11010001 - адрес часов на чтение 8. ACK - ответ от слэйва 9. читаю секунда - секунды читаются 10. ACK - Я ставлю 11. читаю минуты - приходят только нули! 12. ACK - Я ставлю 13. читаю часы - приходят только нули! 14. NACK - Я ставлю 15. стоп Вот что говорит отладчик Как видите на картинке все идет как по алгоритму, но после того как я получаю секунды (22) мне приходят нули за место минут и часов! как будто я не правильно сделал ASK Вот код I2C на ассемблере который я написал Скрытый текст ////////////////// ПРОЦЕДУРЫ для РАБОТЫ С I2C ////////////////////// i2c_init: //Инициализация и2с cbi DDRB, scl cbi DDRB, sda ret i2c_stop: //Отправляет стоповую посылку sbi DDRB, sda rcall delay cbi DDRB, scl rcall delay cbi DDRB, sda ret i2c_start: //Передача стартовой посылки cbi DDRB, scl sbi DDRB, sda rcall delay sbi DDRB, scl ret i2c_recive: //Считывает байт и записывает его в r16 ; обнуляем r17 и r16 ldi r17, 0 ; счетчик битов ldi r16, 0 ; начинаем цикл приема байты OWReadLoop: ; поднимаем scl, а затем опускаем что бы получить один бит sbi DDRB, scl rcall delay rcall delay rcall delay rcall delay cbi DDRB, scl sec ; устанавливаю бит C регистра SREG sbis PINB, sda ; проверяю какое значения на sda, и если 1 то пропускаю следующую команду clc ; если на порту sda 0 то устанавливаем бит C регистра SREG в 0 rol r16 ; запихиваем бит в r16 сдвигом вправо из флага С inc r17 ; увеличиваем счетчик cpi r17,8 ; уже 8? brne OWReadLoop ; нет - продолжаем считывать ret i2c_send: //Будет передан байт из регистра TEMP ldi r17, 8 ; обнуляю счетчик битов r17 ; начинаем цикл отправки байта OWWriteLoop: rol r16 ; Сдвигаем байт вправо через флаг C brcs m1 ; если флаг C = 1 то перескакиваем на m1 sbi DDRB, sda ; если флаг С = 0 то обнуляем sda rjmp m2 ; переходим на m2 m1: cbi DDRB, sda ; флаг С = 1, поднимаю scl, и m2: cbi DDRB, scl ; опускаю scl rcall delay sbi DDRB, scl dec r17 ; увеличиваем счетчик cpi r17,0 ; проверяем на 8 brne OWWriteLoop ; если меньше - следующий бит cbi DDRB, sda rcall ack_send ret ; проверка ask при отправке ack_send: rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl ret ; ask для чтения ask_read: rcall delay sbi DDRB, scl rcall delay sbi DDRB, sda rcall delay cbi DDRB, scl ret ; nask для чтения nask_read: sbi DDRB, scl rcall delay cbi DDRB, sda rcall delay cbi DDRB, scl ret /////////////////////////////////////////////////////////////////////// delay: push r17 ldi r17, 255 md1: nop dec r17 cpi r17, 0 brne md1 pop r17 ret ret А вот код который запрашивает секунды, часы и минуты Скрытый текст DS_get_time: ///считывание времени из часов DS1307 rcall i2c_start // Отправляем стартовую посылку ldi temp,0b11010000 //Адрес микросхемы rcall i2c_send ldi temp,0x0 //Адрес ячейки памяти rcall i2c_send rcall i2c_start //Повторная отправка стартовой посылки ldi temp,0b11010001 //Адрес микросхемы с битом чтения rcall i2c_send rcall i2c_recive //Читаем секунды rcall ask_read sts secunde,r16 rcall i2c_recive //Читаем минуты rcall ask_read sts minute,r16 rcall i2c_recive //Читаем часы rcall nask_read sts hour,r16 rcall i2c_stop //Отправляем стоповую посылку ret И добавляю файл проекта на AVR studio и ISIS7 Прикреплённый файл_________DS1307.rar (87,99 Кбайт, скачиваний: 198) |
Сообщ.
#2
,
|
|
|
Цитата treeS @ 1. старт 2. отправляю 0b11010000 - адрес часов 3. ACK - ответ от слэйва 4. отправляю 0 - адрес секунд 5. ACK - ответ от слэйва Попробуй после этого поставить STOP условие. Пусть зафиксирует адрес....И начни новую сессию: Цитата treeS @ 6. старт 7. отправляю 0b11010001 - адрес часов на чтение 8. ACK - ответ от слэйва 9. читаю секунда - секунды читаются 10. ACK - Я ставлю и посмотрим, что изменится.... |
Сообщ.
#3
,
|
|
|
Просто открылась новая сессия
И всеравно пришли секунды, а дальше нули Добавлено Капец! Посмотрите, как это понимать? http://s3.hostingkartinok.com/uploads/imag...5f118734072.png |
Сообщ.
#4
,
|
|
|
Все, мне помогли найти!!!
i2c_recive: ldi r17, 0 ldi r16, 0 sbi DDRB, scl ; Вот что нужно то было cbi DDRB, sda ; И это OWReadLoop: rcall delay sbi DDRB, scl rcall delay cbi DDRB, scl sec sbis PINB, sda clc rol r16 inc r17 cpi r17,8 brne OWReadLoop ret |
Сообщ.
#5
,
|
|
|
Цитата Все, мне помогли найти!!! После выхода на scl остаётся высокий уровень. Да и в других местах косяки. |
Сообщ.
#6
,
|
|
|
Цитата После выхода на scl остаётся высокий уровень. низкий если быть точнее, а нука в других местах покажи |
Сообщ.
#7
,
|
|
|
Цитата cbi DDRB, scl Может я туплю, конечно. Это низкий? По идее, ножка scl переключается на "вход". Цитата а нука в других местах покажи Цитата ; ask для чтения ask_read: rcall delay sbi DDRB, scl rcall delay sbi DDRB, sda rcall delay cbi DDRB, scl ret Например. если я правильно понимаю написанное: задержка; scl -> 0 задержка; sda -> 0 задержка; scl -> 1 Эт какой-то кривой ACK получается. ну и ещё там... |
Сообщ.
#8
,
|
|
|
Цитата Может я туплю, конечно. Это низкий? По идее, ножка scl переключается на "вход". это высокий Добавлено Цитата Например. если я правильно понимаю написанное: задержка; scl -> 0 задержка; sda -> 0 задержка; scl -> 1 Эт какой-то кривой ACK получается. Спасибо ask_read: rcall delay sbi DDRB, sda rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl ret nask_read: rcall delay cbi DDRB, sda rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl ret |
Сообщ.
#9
,
|
|
|
Цитата ask_read: rcall delay sbi DDRB, sda rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl ret Всё ещё недоACK. Имхо, так будет правильней. Цитата rcall delay sbi DDRB, sda rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl cbi DDRB, sda rcall delay ret nask_read: //rcall delay // cbi DDRB, sda в принципе, лишнее, так как линия sda УЖЕ должна быть отпущена мастером, изначально(все предыдущие битовые интервалы должны быть к тому моменту завершены). Т.е., оставить можно, но не потому что нужно, а на всякий пожарный случай. rcall delay cbi DDRB, scl rcall delay sbi DDRB, scl rcall delay ret Весь ваш код написан так, что практически каждый битовый интервал остаётся незавершенным, хотя, как бы, по идее, завершается в следующем битовом интервале. Имхо, стоит всё вдумчиво переписать. |