Вопрос по TWI

Здесь принимаются все самые невообразимые вопросы... Главное - не стесняйтесь. Поверьте, у нас поначалу вопросы были еще глупее :)
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Вот, например, как реализован у меня опрос DS-ки

Код: Выделить всё

receive_iic:                    ; Приём 7-ми байтового буфера
ldi XH,high(clock_buf)
ldi XL,low(clock_buf)
rcall iic_test2line             ; если хоть одна линия занята
brts iic_error0                 ; выводится ошибка 0 и зацикливается
rcall iic_start                 ; даётся на линию start                 
                                ; сначала установим указатель
                                ; адреса внутри 1307 на 0, записав туда
ldi rx1,write1307adr ;          ; передаётся адрес и команду на запись
rcall send_byte
clr rx1                         ; адрес, с какого писать (ноль)
rcall send_byte
rcall iic_stop                  ; отправляется stop на линию
rcall iic_delay
                                ; теперь начинаем читать
ldi rx1,read1307adr ;           ; передаётся адрес и команда на чтение
rcall iic_start                 ; отправляется start на линию
rcall send_byte
release_sda                     ; и отпускаем линию данных
ldi rx9,7
rcall iic_delay
res_0:
  rcall read_byte               ; читаем байт
  st X+,rx1                     ; сохраняем в буфер
  cpi rx9,1                     ; если этот байт не последний
  breq res_1                    ; тогда подтягиваем линию для ASK
  pull_sda                     
  release_scl                   ; и даём синхримпульс
  rcall iic_delay
  pull_scl
  release_sda
  res_1:
  dec rx9
  brne res_0
  rcall iic_delay
rcall iic_stop
ret
Реклама
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Re: Вопрос по TWI

Сообщение GP1 »

Jeka-starik писал(а):Может быть так что он не отвечает потому что я фигово спрашиваю. Подскажите - правильный ли ход моих мыслей - (Слэйв помимо того что имеет свой собственный адрес имеет дофига ячеек со своими адресами) То бишь обращаясь для чтения к одной из ячеек я должен:
1) Сформировать старт
2) Загрузить адрес слэйва с запросом на запись, получить ACK
3) Потом уже непосредственно обратиться к интересующей меня ячейке памяти и вторично получив ACK
4) Сгенерить повстарт
5) Снова загрузить адрес слэйва но уже с запросом на чтение, получить ACK
6) Далее по идее должно начаться чтение с той ячейки которую я указал до повстарта. После приёма каждого байта Мастер отвечает ACK.
7) Приём последнего байта завершаетстя выдачей Мастером NACK.
8) И собсно стоп...

порядок работы именно с этой микрой описан в ДШ на стр.23-25
пример:

Код: Выделить всё

Function Command Protocol 
S  SAddr W  A  MAddr=0FEh  A  FCmd A  P

т.е.
-старт
-адрес DS-ки
- ответ
- 0хFE
- ответ
- команда
- ответ
- стоп.

зы старичек, без обид :wink:
ну люблю позанудствовать :)))
но книжки и ДШ читать обязательно!
Чем дальше, тем больше становлюсь занудой...
Изображение
Реклама
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Да, ещё раз всем спасибо. ДШ читал ещё когда тока схему проектировал и что-то мне показалось, что там тока общие положения по 2-wire а щас перечитал - и правда там что-то по использованию именно по этой микросхеме написано. В ощем как уже упоминал - ещё раз спасибо за помощь. Может потом ещё обращусь как проблема возникнет. :beer:
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Ну так получилось или нет?
Реклама
Эиком - электронные компоненты и радиодетали
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

GP1 - но всёж - таки я прав оказался. ты мне порядок действия для записи в слэйв привёл. А чтение как раз по тому принципу как я описал. (Если по ДШ судить) :)))
[color=#FF0000]Хачу фсё знать!!![/color]
Реклама
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Не ещё не сделал, у меня выходной вчера был - решил отдохнуть от всего. Сёдня с новыми силами берусь за это дело.
[color=#FF0000]Хачу фсё знать!!![/color]
Реклама
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

В общем - слэйв что то отвечать ACK не собирается. Интерфейс работает нормально - проверял коды статуса - делает старт, отправляет адрес слэёву и в ответ NACK. Появилась у меня идея - почему так может поисходить. Привожу кусок даташита:
Изображение
Вот можете подсказать - здесь 7Е это и есть адрес DSки как слэйва в интерфейсе TWI или в этой ячейке как раз адрес DSки и лежит... Ну и если всё же это второй вариант (к чему я тоже склоняюсь), как мне этот адрес узнать.
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Вот можете подсказать - здесь 7Е это и есть адрес DSки как слэйва в интерфейсе TWI или в этой ячейке как раз адрес DSки и лежит... Ну и если всё же это второй вариант (к чему я тоже склоняюсь), как мне этот адрес узнать.

Дай ссылку на даташит, чтоб не ошибиться.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Похоже на то...
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

http://www.spezial.com/doc/maxim/ds2782.pdf ссылка на DS2782 ДШ.
Я ща попробую общим вызовом достсть её, если отзовётся то можно грешить на адрес.
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Ну вот, там же есть и ответ:
PROGRAMMABLE SLAVE ADDRESS
The 2-Wire slave address of the DS2782 is stored in the parameter EEPROM block, address 7Eh. Programming
the slave address requires a write to set the SAWE (Slave Address Write Enable) bit in the Special Features
register, followed by a write to 7Eh with the desired slave address. The new slave address value is effective
following the write to 7Eh, and must be used to address the DS2782 on subsequent bus transactions. The slave
address value is not stored to EEPROM until a Copy EEPROM block 1 command is executed. Prior to executing
the Copy command, power cycling the DS2782 restores the original slave address value. The data format of the
slave address value in address 7Eh is shown in Figure 22. When not writing the slave address, the SAWE bit
should be written to a 0


Slave Address. A6-A0 contains the 7-bit slave address of the DS2782. The factory default is 0110100b.

7E - это адрес регистра, в котором лежит адрес устройства, и его можно переназначить. С завода, по дефолту, адрес устройства - 0110100b
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Да.... Как мог пропустить. :? Не обратил внимания что это не в конце даташита, где про этот интерфейс написано а в середино.
Лузером себя ощущаю... Полным :(
Последний раз редактировалось Jeka-starik Ср апр 13, 2011 15:41:37, всего редактировалось 1 раз.
[color=#FF0000]Хачу фсё знать!!![/color]
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Всё, слэйв отозвался - ACK прислал нам в ответ !!!! :)) :)) :)) . Всем спасибо кто помогал и в особенности тебе ploop. Вроде теперь меня начальство не убьёт. :)))
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Теперь требуй премию! :)))
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Вот возник исчё один вопросик. Вот кусок программы

Код: Выделить всё

; Выдать команду СТАРТ   
       ldi   tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait         
   ;Проверка кода ответа 0x08
      cpi   tmp,TW_START
      brne   twi_err
   ; Если ОК - закрузка и передача адреса
      ldi   tmp,SLA_W
      out   TWDR,tmp   
      ldi   tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait                  
   ; Проверка кода ответа 0x18
      cpi   tmp,MT_SLA_ASK
      brne   twi_err
   ; Если ОК - загрузка указателя адреса
      ldi   tmp,$14
      out   TWDR,tmp
      ldi   tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
         
      in tmp,TWSR
               out PORTD,tmp
loop2:       rjmp loop2

Вот после отправки SLA_W - код статуса как и положено $18. далее я даю адрес уже внутри DS ($14) А он выводит статус $28. Хочется уточнить. Это он в смысле на самом деле посчитал что $14 это уже пакет данных и запихал их в первую попавшуюся ячейку или так и должно быть и на самом деле $14 определилось как адрес внутри DS?
[color=#FF0000]Хачу фсё знать!!![/color]
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Ну вроде теперь точно всё. Прогу написал, всё работает - данные куда надо заносятся и считываются тоже откуда надо. Всем ещё раз спасибо.
[color=#FF0000]Хачу фсё знать!!![/color]
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

И снова здравствуйте, уважаемые. Это снова я со своими глупыми вопросамию :roll:
Решил я в свою программу, которую обсуждал тут же добавить таймер, чтоб с определённой ячейки DSки через определённое время велось считывание данных и отображалось на светодиодах программатора - порт D (для начала, в будущем буду сохранять куда нить в другое место). Модернизировал немного прогу, но что-то не работает. Подскажите - где я накосячил....

Код: Выделить всё

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"
 ; TWI (I2C) Мастер, приём-передача
;результат выводится в порт D
;Подключние файла, объявление имён регистров ATmega8
.equ   TW_START   =   0x08
.equ   TW_RESTART   =   0x10
.equ   MT_SLA_ACK   =   0x18
.equ   MT_DATA_ACK   =   0x28
.equ   MR_SLA_ACK   =   0x40
.equ   MR_DATA_ACK   =   0x50
.equ   MR_DATA_NACK   =   0x58
.equ   SLA_R      =   $69
.equ   SLA_W      =   $68
.def    tmp         =   R17
.cseg
.org 0
 ;---------- Вектора прерываний ----------
          rjmp INIT
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        rjmp TIM0_OVF

;----------


;=============
    ;Считывание из регистра $14 микросхемы DS2782 числа 0b10011001
;=============
twi_r:

   ; Повторный старт
      ldi   tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x10
      cpi   tmp,TW_RESTART
      brne   twi_err
    ; Если ОК - загрузка и передача адреса
       ldi tmp,SLA_W
      out TWDR,tmp
      ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out TWCR,tmp
    ; Ждать окончания операции
       rcall wait
    ; Проверка кода ответа 0x18
       cpi tmp,MT_SLA_ACK
      brne twi_err
   ; Если ОК - загрузка указателя адреса
       ;=============;
       ;    Адрес для считывания!!!    ;
       ;=============;
      ldi   tmp,$14
      out   TWDR,tmp
      ldi   tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x28
      cpi   tmp,MT_DATA_ACK
      brne   twi_err
twi_r1:
   ; Повторный старт
      ldi   tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x10
      cpi   tmp,TW_RESTART
      brne   twi_err
   ; Если ОК - загрузка и передача адреса
       ldi tmp,SLA_R
      out TWDR,tmp
      ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out TWCR,tmp
    ; Ждать окончания операции
       rcall wait
    ; Проверка кода ответа 0x18
       cpi tmp,MR_SLA_ACK
      brne twi_err
    ; Приём байта c подтверждением
      ldi   tmp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода 0x58
      cpi   tmp,MR_DATA_ACK
      brne   twi_err
   ; Данные приняты - считать и сохранить.
      in   tmp,TWDR
        rjmp twi_r1
   ; Сформировать стоп
      ldi   tmp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
      out   TWCR,tmp
      
      ;Начало программы
INIT:                          ;PROG
   ldi  R16,high(RAMEND)
   out  SPH,R16
   ldi  R16,low(RAMEND)
   out  SPL,R16
   ldi  R16,$FF                ;DDRB=$FF
   out  DDRD,R16
;Инициализация TWI,установка частоты SCL
   ldi  R16,$20                ;TWI.SCLfreguency=100K(8Mhz)
   out  TWBR,R16
;Сброс в 0 битов TWPS1:TWPS0 регистра TWSR
   in   R16,TWSR
   andi R16,$FC
   out  TWSR,R16

   
   ldi r16,0b00000101        ; загружаем константу
   out TCCR0,r16             ; делитель таймера CK/1024
 
   ldi r16,$01
   out TIMSK,r16             ; разрешаем прерывание timer0 по переполнению

   ldi r16,$00
   out TCNT0,r16             ;начальное значение счетчика - 0

   sei                       ; разрешить прерывания

   rjmp twi_r                ; возврат в тело  цикла
 ;===========
   ; Обработчик ошибок
twi_err:
          nop   
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      rjmp   twi_end     
;===========
   ; Выход из режима работы с TWI
twi_end:
      ret      
;===========
; Процедура ожидания завершения операции
;===========
wait:
      in   tmp,TWCR
      sbrs   tmp,TWINT
       rjmp   wait
      in   tmp,TWSR
      andi   tmp,0xF8
      ret
;===========
; Обработка прерывания
;===========
TIM0_OVF:
        in tmp,TWDR
      out PORTD,tmp
      reti

PS. Ещё может кто подскажет - как проверять работу TWI с учётом таймера. А то я что-то даже не могу понять - работает он или нет (таймер в смысле).
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Вопрос по TWI

Сообщение ploop »

Сразу вижу косяк в векторах прерываний. Исправь, иначе дальше смотреть проблематично.
Тут показан пример, как это сделать правильно: http://easyelectronics.ru/avr-uchebnyj- ... aniya.html
Jeka-starik
Открыл глаза
Сообщения: 48
Зарегистрирован: Чт апр 07, 2011 11:57:18
Откуда: Санкт-Петербург

Re: Вопрос по TWI

Сообщение Jeka-starik »

Вроде поправил. При пошаговой проверке всё пучком - стрелочка скачет куда надо, в регистры нужное пишется, а врубаю микроконтроллер - и нихрена...

Код: Выделить всё

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"
 ; TWI (I2C) Мастер, приём-передача
;результат выводится в порт D
;Подключние файла, объявление имён регистров ATmega8
.equ   TW_START   =   0x08
.equ   TW_RESTART   =   0x10
.equ   MT_SLA_ACK   =   0x18
.equ   MT_DATA_ACK   =   0x28
.equ   MR_SLA_ACK   =   0x40
.equ   MR_DATA_ACK   =   0x50
.equ   MR_DATA_NACK   =   0x58
.equ   SLA_R      =   $69
.equ   SLA_W      =   $68
.def    tmp         =   R17
.cseg
 ;---------- Вектора прерываний ----------
.org $00  rjmp INIT
        nop
        nop
        nop
        nop
        nop
        nop
        nop
.org $09  rjmp TIM0_OVF

;----------


;=============
    ;Считывание из регистра $14 микросхемы DS2782 числа 0b10011001
;=============
twi_r:

   ; Старт
      ldi   tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x8
      cpi   tmp,TW_START
      brne   twi_err
    ; Если ОК - загрузка и передача адреса
       ldi tmp,SLA_W
      out TWDR,tmp
      ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out TWCR,tmp
    ; Ждать окончания операции
       rcall wait
    ; Проверка кода ответа 0x18
       cpi tmp,MT_SLA_ACK
      brne twi_err
   ; Если ОК - загрузка указателя адреса
       ;=============;
       ;    Адрес для считывания!!!    ;
       ;=============;
      ldi   tmp,$14
      out   TWDR,tmp
      ldi   tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x28
      cpi   tmp,MT_DATA_ACK
      brne   twi_err
   twi_r1
   ; Повторный старт
      ldi   tmp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода ответа 0x10
      cpi   tmp,TW_RESTART
      brne   twi_err
   ; Если ОК - загрузка и передача адреса
       ldi tmp,SLA_R
      out TWDR,tmp
      ldi tmp,(1<<TWINT)|(1<<TWEN)|(1<<TWIE)
      out TWCR,tmp
    ; Ждать окончания операции
       rcall wait
    ; Проверка кода ответа 0x18
       cpi tmp,MR_SLA_ACK
      brne twi_err

    ; Приём байта c подтверждением
      ldi   tmp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
      out   TWCR,tmp
   ; Ждать окончания операции
      rcall   wait
   ; Проверка кода 0x58
      cpi   tmp,MR_DATA_ACK
      brne   twi_err
   ; Данные приняты - считать и сохранить.
      in   tmp,TWDR
        rjmp twi_r1
   ; Сформировать стоп
      ldi   tmp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
      out   TWCR,tmp
      
      ;Начало программы
INIT:                          ;PROG
   ldi  R16,high(RAMEND)
   out  SPH,R16
   ldi  R16,low(RAMEND)
   out  SPL,R16
   ldi  R16,$FF                ;DDRB=$FF
   out  DDRD,R16
;Инициализация TWI,установка частоты SCL
   ldi  R16,$20                ;TWI.SCLfreguency=100K(8Mhz)
   out  TWBR,R16
;Сброс в 0 битов TWPS1:TWPS0 регистра TWSR
   in   R16,TWSR
   andi R16,$FC
   out  TWSR,R16

   
   sei                       ; разрешить прерывания

   ldi r16,0b00000101        ; загружаем константу
   out TCCR0,r16             ; делитель таймера CK/1024
 
   ldi r16,$01
   out TIMSK,r16             ; разрешаем прерывание timer0 по переполнению

   ldi r16,$00
   out TCNT0,r16             ;начальное значение счетчика - 0
               

   rjmp twi_r                ; возврат в тело  цикла
 ;========================
   ; Обработчик ошибок
twi_err:
          nop   
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      rjmp   twi_end     
;========================
   ; Выход из режима работы с TWI
twi_end:
      ret      
;========================
; Процедура ожидания завершения операции
;========================
wait:
      in   tmp,TWCR
      sbrs   tmp,TWINT
       rjmp   wait
      in   tmp,TWSR
      andi   tmp,0xF8
      ret
;========================
; Обработка прерывания
;========================
TIM0_OVF:
        push tmp
      in   tmp,SREG
      push tmp

        in tmp,TWDR
      out PORTD,tmp

exit:   pop tmp
        out SREG,tmp
      pop tmp   
      
      reti
Последний раз редактировалось Jeka-starik Вт апр 19, 2011 12:30:37, всего редактировалось 2 раза.
[color=#FF0000]Хачу фсё знать!!![/color]
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Re: Вопрос по TWI

Сообщение GP1 »

очень интересный принцип построения программы

после выполнения куска с меткой INIT переход rjmp twi_r и по завершении twi_r опять переходим на выполнение INIT и так по кругу, до позеленения
Чем дальше, тем больше становлюсь занудой...
Изображение
Ответить

Вернуться в «Теория»