На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Проблема с протоколом I2C , Attiny2313 и DS1307
      Написал программный протокол 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. стоп

      Вот что говорит отладчик
      user posted image

      Как видите на картинке все идет как по алгоритму, но после того как я получаю секунды (22) мне приходят нули за место минут и часов! как будто я не правильно сделал ASK


      Вот код I2C на ассемблере который я написал
      Скрытый текст

      ExpandedWrap disabled
        ////////////////// ПРОЦЕДУРЫ для РАБОТЫ С 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





      А вот код который запрашивает секунды, часы и минуты
      Скрытый текст

      ExpandedWrap disabled
        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)
      Сообщение отредактировано: treeS -
        Цитата treeS @
        1. старт
        2. отправляю 0b11010000 - адрес часов
        3. ACK - ответ от слэйва
        4. отправляю 0 - адрес секунд
        5. ACK - ответ от слэйва

        Попробуй после этого поставить STOP условие. Пусть зафиксирует адрес....И начни новую сессию:
        Цитата treeS @
        6. старт
        7. отправляю 0b11010001 - адрес часов на чтение
        8. ACK - ответ от слэйва
        9. читаю секунда - секунды читаются
        10. ACK - Я ставлю

        и посмотрим, что изменится.... :D
          Просто открылась новая сессия
          user posted image

          И всеравно пришли секунды, а дальше нули

          Добавлено
          Капец!
          Посмотрите, как это понимать?
          http://s3.hostingkartinok.com/uploads/imag...5f118734072.png
            Все, мне помогли найти!!!


            ExpandedWrap disabled
              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
              Цитата
              Все, мне помогли найти!!!

              После выхода на scl остаётся высокий уровень. Да и в других местах косяки.
                Цитата
                После выхода на scl остаётся высокий уровень.

                низкий если быть точнее, а нука в других местах покажи
                  Цитата
                  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 получается.
                  ну и ещё там...
                  Сообщение отредактировано: Prince -
                    Цитата
                    Может я туплю, конечно. Это низкий? По идее, ножка scl переключается на "вход".

                    это высокий

                    Добавлено
                    Цитата
                    Например.
                    если я правильно понимаю написанное:
                    задержка;
                    scl -> 0
                    задержка;
                    sda -> 0
                    задержка;
                    scl -> 1
                    Эт какой-то кривой ACK получается.


                    Спасибо


                    ExpandedWrap disabled
                      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
                    Сообщение отредактировано: treeS -
                      Цитата
                      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

                      Весь ваш код написан так, что практически каждый битовый интервал остаётся незавершенным, хотя, как бы, по идее, завершается в следующем битовом интервале. Имхо, стоит всё вдумчиво переписать.
                      Сообщение отредактировано: Prince -
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0338 ]   [ 17 queries used ]   [ Generated: 27.04.24, 23:11 GMT ]