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

 
 
19 страниц V  « < 10 11 12 13 14 > »   
Reply to this topicStart new topic
> Проблема с TWI
bodja74
сообщение Dec 26 2005, 13:54
Сообщение #166


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Я еще слейв в режиме передатчика не делал (небыло надобности)
Сегодня - завтра разберусь и выложу как точно должно быть.

Скорее всего слейв не правильно обрабатывает прерывание и "затягивает"
ACK ,и из за этого "зависает" TWINT и Мастер соответственно не может продолжить
передачу пакета.
Go to the top of the page
 
+Quote Post
Petka
сообщение Dec 26 2005, 15:17
Сообщение #167


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

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



при событии 0xF8 надо просто выйти из прерывания НИЧЕГО не делая.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 27 2005, 23:30
Сообщение #168


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



ВСЕ!!!

Добил.

Думаю разберетесь.

Код мастера

Код
; TWI Master
; Specify Device.
.include "m8def.inc"

      
                    
                    
; Variable Declarations
.def temp     = r16
.def temp_a   = r17
.def adress   = r18
.def data     = r19
.def W        = r24    
.def X        = r26
.def Y        = r28
.def Z        = r30

.cseg                ; CODE segment.

.org 0; origin.

        
                  
PROG:           ldi temp,$04        ; Initialize the stack.
            out SPH,temp
                ldi temp,$5F            
            out SPL,temp
        ldi temp,$00
                out TWBR,temp
                ldi temp,$00
                out TWSR,temp

        ldi temp,$FF
        out DDRD,temp

        ldi   adress,$41;Получаем
                 rcall TWI_START
                rcall TWI_DATA_R_ACK
                rcall TWI_DATA_R_NACK;При при получении последнего байта нужно
        rcall TWI_STOP    ;обязательно указывать NACK
                rcall PAUSE


                ldi   adress,$40       ;Отправляем
                rcall TWI_START
                ldi   data,$FF
                rcall TWI_DATA
                rcall TWI_DATA
                rcall TWI_STOP
                rcall PAUSE

        ldi   adress,$40
                 rcall TWI_START
                rcall TWI_DATA
                rcall TWI_STOP
                rcall PAUSE

        ldi   adress,$41
                 rcall TWI_START
                rcall TWI_DATA_R_ACK
                rcall TWI_DATA_R_NACK
        rcall TWI_STOP
                rcall PAUSE


end:        rjmp end

TWI_START:  
                ldi temp,$A4
                out TWCR,temp
s1:             in  temp,TWCR
                sbrs temp,7
               rjmp s1
            
                out TWDR,adress
                ldi temp,$C4
                out TWCR,temp
s2:             in  temp,TWCR
                sbrs temp,7
                rjmp s2
                ret

TWI_DATA:       out TWDR,data
                ldi temp,$C4
                out TWCR,temp
d1:             in  temp,TWCR
                sbrs temp,7
               rjmp d1  
                ret

TWI_STOP:       ldi temp,$94
                out TWCR,temp
                ret

PAUSE:          ldi temp,$40
              ldi temp_a,$00
p:                dec temp
            cpi temp,$00
                brne p
        ret

TWI_DATA_R_NACK:ldi temp,$84
                out TWCR,temp
d2:             in  temp,TWCR
               sbrs temp,7
                rjmp d2
        in temp,TWDR
        out PORTD,temp
                ret
        
TWI_DATA_R_ACK: ldi temp,$C4
                out TWCR,temp
d3:             in  temp,TWCR
               sbrs temp,7
                rjmp d3
        in temp,TWDR
        out PORTD,temp
                ret


Код слейва

Код
; TWI Slave
; Specify Device.
.include "m8def.inc"

      
                    
                    
; Variable Declarations
.def temp     = r16
.def temp_a   = r17
.def adress   = r18
.def data     = r19
.def W        = r24    
.def X        = r26
.def Y        = r28
.def Z        = r30

.cseg                ; CODE segment.

.org 0          
                rjmp PROG        ; origin.
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        reti
        rjmp TWI_Finished
        reti
           
                          
PROG:           ldi r16,$04    ; Initialize the stack.
            out SPH,r16
                ldi r16,$5F            
            out SPL,r16
                ldi temp,$00    ; Инициализация TWI
        out TWSR,temp
                ldi temp,$00    ;
        out TWBR,temp
                ldi temp,$40
        out TWAR,temp
                ldi temp,$45
        out TWCR,temp
                ldi temp,$FF
        out DDRD,temp
        sei        
end:        rjmp end     ; конец программы          


TWI_Finished:    
        sts $0F1,temp
        in temp,TWSR
                cpi temp,$60
                breq t1
                in temp,TWSR
                cpi temp,$80
                breq t2
        in temp,TWSR
                cpi temp,$A8
                breq t3
        in temp,TWSR
                cpi temp,$B0
                breq t3
        in temp,TWSR
                cpi temp,$B8
                breq t4
       
    
                ldi temp,$C5
        out TWCR,temp
        reti



t1:        ldi temp,$C5    ;Определяем Адресс.Мастер передает
        out TWCR,temp
        
        reti

t2:        in temp,TWDR    ;Получаем данные
        out PORTD,temp
        ldi temp,$C5
        out TWCR,temp
        
        reti

t3:        ldi temp,$01    ;Определяем Адресс.Мастер получает 1 байт
        out TWDR,temp
        ldi temp,$C5
        out TWCR,temp
        ldi temp,$01
        out TWDR,temp
        reti

t4:        ldi temp,$02    ;Мастер получает 2 байт и далее
        out TWDR,temp
        ldi temp,$85    ;$85 последний байт, $C5 далее
        out TWCR,temp
        reti


Пробуйте.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 28 2005, 14:23
Сообщение #169


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Вроде все исправил, но мастер зависает в том же месте.
Слейв2 не хочет принимать свой адрес.
Вопросы:
1. Почему у вас везде TWBR=0? Значение ведь должно быть не менее 10?
2. В вашей проге мастер сначала принимает 2 байта, отправляет 2 байта, отправляет 1 байт, и, наконец принимает 2 байта. Я же сделал, чтобы мастер отправлял 2 байта, а потом принимал 6 байт (впрочем, до приема дело не доходит). Это же не принципиально важно?
3. В проге слейва, в этом месте:

t3: ldi temp,$01 ;Определяем Адресс.Мастер получает 1 байт
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
out TWCR,temp
ldi temp,$01
out TWDR,temp
reti

зачем 2 раза заносить значение в TWDR?

Ситуация у меня, наверное, осложняется присутствием на шине 2-х слейвов. В слейве1 прием данных завершается командой:

STOP: ldi temp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
out TWCR,temp
reti

Слейв1 ничего не передает мастеру - только принимает. После этого идет передача/прием на слейв2.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 28 2005, 16:58
Сообщение #170


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



1.Моя ошибка в мастере(я этот код использовал в симуляторе для ускорения процесса просмотра)
Нужно TWSR=$02 TWBR=$02 ( или по другому по Вашему усмотрению)Для слейва не обязательно,ему все равно с какой скоростью передаются даннные.

2.Да ,не важно ,просто проба разных вариантов.Что нужно учесть я в коментариях написал.

3.Пробовал посто разные варианты заносить данные до и после TWCR,
забыл выбросить 2 отправку когда "чистил" код.

Я еще попробую с двумя слейвами поработать,возможно косяки из за двух слейвов,посмотрим.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 28 2005, 17:25
Сообщение #171


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Вот исправленный код для мастера.
Должен работать с двумя слейвами.
У слейвов код тотже.
Код
; TWI Master
; Specify Device.
.include "m8def.inc"

      
                    
                    
; Variable Declarations
.def temp     = r16
.def temp_a   = r17
.def adress   = r18
.def data     = r19
.def W        = r24    
.def X        = r26
.def Y        = r28
.def Z        = r30

.cseg                ; CODE segment.

.org 0; origin.

        
                  
PROG:           ldi temp,$04        ; Initialize the stack.
            out SPH,temp
                ldi temp,$5F            
            out SPL,temp
        ldi temp,$02
                out TWBR,temp
                ldi temp,$02
                out TWSR,temp

        ldi temp,$FF
        out DDRD,temp



                ldi   adress,$40        
                rcall TWI_START
                ldi   data,$F0
                rcall TWI_DATA
                rcall TWI_DATA
                rcall TWI_STOP
                rcall PAUSE

                ldi   adress,$20        
                rcall TWI_START
                ldi   data,$0F
                rcall TWI_DATA
                rcall TWI_DATA
                rcall TWI_STOP
                rcall PAUSE

        ldi   adress,$41
                 rcall TWI_START
                rcall TWI_DATA_R_ACK
                rcall TWI_DATA_R_NACK
                rcall TWI_STOP
                rcall PAUSE

        ldi   adress,$21
                 rcall TWI_START
                rcall TWI_DATA_R_ACK
                rcall TWI_DATA_R_NACK
                rcall TWI_STOP
                rcall PAUSE

end:        rjmp end

TWI_START:  
                ldi temp,$A4
                out TWCR,temp
s1:             in  temp,TWCR
                sbrs temp,7
               rjmp s1
            
                out TWDR,adress
                ldi temp,$C4
                out TWCR,temp
s2:             in  temp,TWCR
                sbrs temp,7
                rjmp s2
                ret

TWI_DATA:       out TWDR,data
                ldi temp,$C4
                out TWCR,temp
d1:             in  temp,TWCR
                sbrs temp,7
               rjmp d1  
                ret

TWI_STOP:       ldi temp,$94
                out TWCR,temp
                ret

PAUSE:          ldi temp,$40
              ldi temp_a,$00
p:                dec temp
            cpi temp,$00
                brne p
        ret

TWI_DATA_R_NACK:ldi temp,$84
                out TWCR,temp
d2:             in  temp,TWCR
               sbrs temp,7
                rjmp d2
        in temp,TWDR
        out PORTD,temp
                ret
        
TWI_DATA_R_ACK: ldi temp,$C4
                out TWCR,temp
d3:             in  temp,TWCR
               sbrs temp,7
                rjmp d3
        in temp,TWDR
        out PORTD,temp
                ret


Пробуйте.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 29 2005, 11:14
Сообщение #172


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Да не получается ничего. Та же беда.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 29 2005, 13:07
Сообщение #173


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Сделал, ради эксперимента, еще такой финт.
Мастер пересылает слейву2 2 байта, после этого инициализируется как приемник с адресом $60, а слейв2 - как мастер. Должно переслаться 6 байт. Так вот, один раз прием/передача проходит, а потом мастер опять зависает.
Но все-таки хотелось бы, чтобы мастер передавал/принимал данные как положено - без переинициализации.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 29 2005, 13:33
Сообщение #174


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



У вас код слейва2 ,тот же?
Если нет,выкладывайте.
Если у мастера есть проверки TWSR,временно уберите.

Еще не стоит забывать,что у слейва передатчика в 18 раз меньше времени
на обработку прерываения ,чем у слейва приемника,поэтому контроллер слейва
лучше тактировать на максимальной частоте+подпрограмма прерывания должна быть коротенькая.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 30 2005, 06:08
Сообщение #175


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Код слейва2:

Код
;Инициализация TWI:

  ldi  temp,$40 ;Инициализация режима "Приемник" - адрес
  out  TWAR,temp
  ldi  temp,$00
  out  TWSR,temp
  ldi  temp,$14
        out  TWBR,temp
  ldi  temp,(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  sei

;***** Основной Цикл: *****

START: rjmp START

;*******************************************************************
;Режим - подчиненный-приемник/передатчик:

TWI_Obr:in  temp,TWSR
  cpi  temp,$60;Проверка принятого адреса от мастера
  breq Address
  cpi  temp,$80;Прием данных
  breq DataR

  cpi  temp,$A8;Передача данных
  breq DataT1
  cpi  temp,$B0;
  breq DataT1
  cpi  temp,$B8;
  breq DataT2

  ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  reti

;*******
Address:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  reti

;Прием данных:

DataR: in  Byte_1,TWDR ;Прием: байт 1
  rcall TW_NT_n
  in  Byte_2,TWDR ;Прием: байт 2

  rjmp STOP_n

;*******************************************************************
TW_NT_n:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
  out  TWCR,temp

wait2n: in  temp,TWCR ;Ожидаем ответа от мастера
  sbrs temp,TWINT
  rjmp wait2n

  ret

;*******************************************************************
;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)

STOP_n: ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

;*******************************************************************

;Передача данных:

DataT1: out  TWDR,Byte_3 ;Отправка: байт 3
  rcall Write
  out  TWDR,Byte_4 ;Отправка: байт 4
  rcall Write
  out  TWDR,Byte_5 ;Отправка: байт 5
  rcall Write
  out  TWDR,Byte_6 ;Отправка: байт 6
  rcall Write
  out  TWDR,Byte_7 ;Отправка: байт 7
  rcall Write

DataT2: out  TWDR,Byte_8 ;Отправка: байт 8

  ldi  temp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)   ;последний байт
  out  TWCR,temp

  reti
  
;*******************************************************************
Write: ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

wait3n: in  temp,TWCR;Ожидаем ответа от мастера
  sbrs temp,TWINT
  rjmp wait3n

  ret

;*******************************************************************


Код слейва1 такой же, но там только принимаются данные.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 30 2005, 06:21
Сообщение #176


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Код слейва 1:

Код
;Инициализация TWI:

  ldi  temp,$20;Инициализация режима "Приемник"
  out  TWAR,temp
  ldi  temp,$00
  out  TWSR,temp
  ldi  temp,(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  sei

;***** Основной Цикл: *****

START: rjmp START



;*******************************************************************
;Режим - подчиненный-приемник:

TWI_Obr:in  temp,TWSR
  cpi  temp,$60;Проверка принятого адреса от мастера
  breq Address
  cpi  temp,$80;Прием данных
  breq Data
  cpi  temp,$00;
  breq Sob_00
  cpi  temp,$F8;
  breq Sob_F8

  ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  reti

Sob_00: ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp
  reti

Sob_F8: reti

;*******
Address:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp
  reti

;*******
;Прием данных:

Data: in  Byte_1,TWDR ;Прием: байт 1

Data2: rcall TW_NT_n  ;Прием: байт 2
  in  Byte_2,TWDR

Data3: rcall TW_NT_n  ;Прием: байт 3
  in  temp,TWDR
  sts  Byte_3,temp

  rjmp STOP_n

;*******************************************************************
TW_NT_n:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
  out  TWCR,temp

wait2n: in  temp,TWCR ;Ожидаем ответа от мастера
  sbrs temp,TWINT
  rjmp wait2n

  ret

;*******************************************************************
;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)

STOP_n: ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  reti
;*******************************************************************
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 30 2005, 08:04
Сообщение #177


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Почему-то редактирование сообщений не работает, в слейве2 исправить:
;*******************************************************************
;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)

STOP_n: ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
out TWCR,temp
reti
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 30 2005, 15:11
Сообщение #178


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Вот здесь Вы разрешаете прерывание (1<<TWIE)
Write: ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
out TWCR,temp

wait3n: in temp,TWCR;Ожидаем ответа от мастера
sbrs temp,TWINT
rjmp wait3n

ret
Из за чего могут возникнуть коллизии в программе.

Кроме того нужно проверить возможность вкладывать в обработку прерывания
подппрограмму для второго и последющих батов.Буде работать или нет.

Дальше
DataT1: Здесь мы отправляем только первый байт.
DataT2: Здесь мы отправляем второй ,последуюшие и последний байт.
Go to the top of the page
 
+Quote Post
картошка
сообщение Dec 30 2005, 16:05
Сообщение #179


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-12-05
Из: Odessa
Пользователь №: 12 673



Непонимаю радости использовать аппаратный TWI.
Вот отработанный мною годами код к програмной реализации аналога I2C. Может одумаетесь. Особых преимуществ невижу. А на этом коде можно увеличить несущюю CLK cranky.gif .

Определяете четыре константы и все.

.equ DDRX = DDRX (любой порт DDRX - выбора направления)
.equ PINX = PINX (любой порт PINX конечно тотже триады что и DDRX)
.equ XSCL = 0-7
.equ XSDA = 0-7

; Примечание :
; можете цеплять внешние сопротивления и на 1.5 вольта - будет работать. Работала несущая и на 1.5 mbю

InstallI2C:
cbi DDRX,XSCL ; установка линии SCL в 1
cbi DDRX,XSDA ; установка линии SDA в 1
ret
StartI2C:
rcall PausI2C
cbi DDRX,XSDA ; установка в 1
rcall PausI2C
cbi DDRX,XSCL ; установка в 1
rcall PausI2C
sbi DDRX,XSDA ; установка в 0
rcall PausI2C
sbi DDRX,XSCL ; установка в 0
rcall PausI2C
ret
StopI2C:
sbi DDRX,XSDA
sbi DDRX,XSCL
rcall PausI2C
cbi DDRX,XSCL
rcall PausI2C
cbi DDRX,XSDA
rcall PausI2C
ret



; Вход: R24-data и устанавливае фла переноса если ASK=1
DataOutI2C:
ldi r30,8
doq1a: rol r24
brcs doq2a
sbi DDRX,XSDA
rjmp doq3a
doq2a: cbi DDRX,XSDA
doq3a: rcall I2CPulse
dec r30
brne doq1a
cbi DDRX,XSDA
rcall PausI2C
cbi DDRX,XSCL
rcall PausI2C
in r24,PINX
sbi DDRX,XSCL
rcall PausI2C
clc
sbrc r24,XSDA
sec
ret

; Выход: R24-data и устанавливае фла переноса если ASK=1
DataInI2C:
push r30
ldi r30,8
diiq1: rcall PausI2C
cbi DDRX,XSCL
rcall PausI2C
in r31,PINX
sbi DDRX,XSCL
clc
sbrc r31,XSDA
sec
rol r24
dec r30
brne diiq1
rcall PausI2C
sbi DDRX,XSDA ; 0
rcall PausI2C
cbi DDRX,XSCL ; 1
rcall PausI2C
sbi DDRX,XSCL ; 0
rcall PausI2C
cbi DDRX,XSDA ; 0
rcall PausI2C
pop r30
ret

I2CPulse:
rcall PausI2C
sbi DDRX,XSCL
rcall PausI2C
cbi DDRX,XSCL
rcall PausI2C
sbi DDRX,XSCL
rcall PausI2C
ret

PausI2C:
push r30
ldi r30,8
doq33: dec r30
brne doq33
pop r30
ret


Моя будущая веб-страница
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 30 2005, 18:02
Сообщение #180


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



1 А я не вижу радости в программном TWI.Тоже делал,тоже прошел.
2 Не вижу кода для слейва.
3 Код для мастера обсуждался и работает и куда коротче вашего,при таком раскладе.
4 Преимужества?Как насчет возможности использовать мастер по прерыванию и разгрузить основной проц процентов на 90 ?
5 А как насчет того ,если мы захотим вцепить 2 мастера?Ваш код будет дожидаться когда освободиться шина?Или среагирует при арбитраже?
Go to the top of the page
 
+Quote Post

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

 


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


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