Например TDA7294

Форум РадиоКот :: Просмотр темы - STM32 новичку в ARM что к чему
Форум РадиоКот
https://radiokot.ru/forum/

STM32 новичку в ARM что к чему
https://radiokot.ru/forum/viewtopic.php?f=59&t=67578
Страница 179 из 423

Автор:  Porada [ Пт май 19, 2017 20:18:49 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Когда я работал с МК серии STMF10x так и было. Но с STM32F071 вышло интересно. Когда я только делал первые шаги с платой VLDiscovery я поначалу вообще тактированием не заморачивался. Работало на "по умолчанию". Здесь же при попытке отконфигурировать выходы управления 4-х разрядным 7-сегментным индикатором, не принимая во внимание тактирование, приводила к случайной конфигурации вкл/выкл выходов, причём на манипуляции с регистром ODR в отладчике Кейла эти выходы не реагировали. Но "вис" МК не из-за этого. В библиотеках Hal, как, ЕМНИП, и в StdPeriph, после запуска HSE или LSE идёт проверка соответствующего бита xxxRDY в регистрах RCC. Проверка происходит в цикле while, и пока вышеуказанный бит не станет 1, программа из цикла не выйдет. Имеем зависание.

Автор:  oleg110592 [ Сб май 20, 2017 07:41:08 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Можно на 100% доверять конфигам периферии от Куба? Для F0, если проблемы с HSE, разве не включается автоматически HSI? Если я случайно перегрел при пайке выводы входов тактирования.

как делает куб:
Код:
  LL_RCC_HSE_Enable();

   /* Wait till HSE is ready */
  while(LL_RCC_HSE_IsReady() != 1)
  {
   
  }

как делала старая ексель утилитка от ST:
Код:
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  /* Enable HSE */   
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++; 
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

имхо кубу доверять не можно

Автор:  amv2000 [ Пн май 22, 2017 12:34:49 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Здравствуйте! ковыряюсь с библиотекой LCD для ST7735s, написана в HAL. В файле main.h описаны определения для управления выводами LCD
Код:
#ifndef MAIN_H
#define MAIN_H

#define LCD_RST1  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_SET);
#define LCD_RST0  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,GPIO_PIN_RESET);
//   LCD_DC
#define LCD_DC1   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_SET);   
#define LCD_DC0   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_RESET);

//  LCD_CS
#define LCD_CS1   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_SET); 
#define LCD_CS0   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_RESET);

void lcd7735_senddata(unsigned char data);
void lcd7735_send16bData(unsigned char msb,unsigned char lsb);
void spi2_8b_init(void);
void spi2_16b_init(void);

#endif
меняю их на CMSIS
Код:
#ifndef MAIN_H
#define MAIN_H

#define LCD_RST1  GPIOA->BSRR=GPIO_BSRR_BS3;
#define LCD_RST0  GPIOA->BSRR=GPIO_BSRR_BR3;
//   LCD_DC
#define LCD_DC1   GPIOA->BSRR=GPIO_BSRR_BS4;
#define LCD_DC0   GPIOA->BSRR=GPIO_BSRR_BR4;

//  LCD_CS
#define LCD_CS1   GPIOA->BSRR=GPIO_BSRR_BS6;
#define LCD_CS0   GPIOA->BSRR=GPIO_BSRR_BR6;

void lcd7735_senddata(unsigned char data);
void lcd7735_send16bData(unsigned char msb,unsigned char lsb);
void spi2_8b_init(void);
void spi2_16b_init(void);

#endif
Дисплей не работает, собственно вопрос, что этой собаке надо?
P.S. Запустил сегодня, работает дисплей. Вероятно не той рукой запускал.

Автор:  isx [ Вт май 23, 2017 01:29:34 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Приветствую всех!
Решил подключить RFID-RC522 по SPI (только он и выведен) к STM32, но сразу столкнулся с проблемой - нигде нет описания протокола общения с чипом. Да что там протокола, я даже настроек для SPI не нашел. Все что удалось найти в даташите по настройке:
Цитата:
Data bytes on both MOSI and MISO lines are sent with the MSB first. Data on both MOSI
and MISO lines must be stable on the rising edge of the clock and can be changed on the
falling edge. Data is provided by the MFRC522 on the falling clock edge and is stable
during the rising clock edge.

Из этого я сделал вывод, что порядок передачи байт - MSB, но как настроить биты SPI_CR1_CPOL и SPI_CR1_CPHA так и не понял.
Впервые сопрягаю устройство по SPI, поэтому такие тупые вопросы (удалось добиться обмена информацией на одном МК по двум SPI интерфейсам, теперь перехожу на сторонние устройства). Если еще подскажете какими командами запросить у чипа RC522 данные с UID, то вообще помру от счастья :))) .
P.S. Даташит читаю, но яснее пока от этого ситуация не становится :dont_know:

Автор:  isx [ Ср май 24, 2017 00:51:12 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Никаких мыслей? :( .

Автор:  Apparatchik [ Ср май 24, 2017 09:20:34 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Посмотрите здесь, у меня все завелось.

Автор:  isx [ Чт июн 01, 2017 02:07:01 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Еще один вопрос. Вот настроили мы SPI. Дальше чтоб прочитать, к примеру, тот же регистр 0x14, то что нужно сделать? Как объяснить что мы именно читать хотим, а не писать в него. Какую последовательность байт отправить для чтения этого регистра?
Что-то не могу найти описание процедуры чтения/записи в даташите. Или может туповат - оно написано, а я не понимаю :dont_know:

Добавлено after 6 hours 52 minutes 45 seconds:
Что за хрень происходит с моим камнем?
Работаю на STM32F3Discovery и пытаюсь присобачить RFID RC522. Впервые серьезно взялся за SPI (так как RFID работает именно через него) и пол дня угробил на непонятный глюк.
Настроил SPI как положено, но ответа от подчиненного нет. Несколько часов колдовал с даташитами и ераташитом, но решения не нашел. Решил подцепить логический анализатор к шине и оказалось, что ответ таки идет, но SPI в МК его почему-то не принимает. Опять стал колдовать с тех. документацией, пока через несколько часов не заметил, что ответ в регистре есть, но он какого-то хрена смещен на 8 бит влево!!! :kill:
Если вживую попереключать в отладчике бит CPOL и CPHA, а потом выставить обратно как и было, то иногда SPI начинает правильно отображать принятые данные в младшем байте регистра DR.
Что с ним такое происходит? Я рукожоп или это особенность периферии камня, так как нигде нет упоминания о том, что входящие данные хранятся именно в старшем байте регистр? :kill: :kill: :dont_know:
Вот настройки SPI:
Код:
  SPI2->CR1 |= SPI_CR1_BR; //Baud rate = Fpclk/256
  SPI2->CR2 |= SPI_CR2_RXNEIE;  // RX buffer Not Empty Interrupt Enable;
  SPI2->CR1 &= ~SPI_CR1_CPOL; //Полярность тактового сигнала
  SPI2->CR1 &= ~SPI_CR1_CPHA; //Фаза тактового сигнала
  SPI2->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2; //8 бит данных
  SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB передается первым
  SPI2->CR1 |= SPI_CR1_SSM; //Программный режим NSS
  SPI2->CR1 |= SPI_CR1_SSI; //Аналогично состоянию, когда на входе NSS высокий уровень
  SPI2->CR1 |= SPI_CR1_MSTR; //Режим Master
  SPI2->CR1 |= SPI_CR1_SPE; //Включаем SPI2


Вот с такими функциями я принимаю нормальный байт от слейва:
Код:
void SPI2_send_byte (uint8_t Byte)
{
   while(!(SPI2->SR & SPI_SR_TXE));
   SPI2_NSS_LOW;
   SPI2->DR = Byte; //Пишем в буфер передатчика SPI2. После этого стартует обмен данными   
}


void SPI2_IRQHandler (void)
{
   if (SPI2->SR & SPI_SR_RXNE)
      {
         SPI2->SR &= ~SPI_SR_RXNE;
         
         SPI2_Got_Byte = (SPI2->DR >> 8);         
         SPI2_NSS_HIGHT;
      }
}
      


И забыл упомянуть самое главное - если отключиться от слейва и перемкнуть выводы МК MOSI и MISO, то байт приходит как положено - в младший байт регистра DR. При этом, логический анализатор при общении МК со слейвом показывает, что они обмениваются реально только по одному байту (0x80 - это правильный отклик слейва):
Изображение

Автор:  isx [ Пт июн 02, 2017 01:41:15 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Проблема оказалась в непонятной особенности работы со SPI в восьмибитном режиме.
Решение подсказал товарищ nahimovv на казусе. Надеюсь никто не будет против копи-паста, может кому пригодится:
Цитата:
При освоении STM32F0XX новички часто испытывают трудности запуска SPI в режиме 8бит и ниже. Причиной этому является значительное расширение возможностей модуля SPI, по сравнению с предшественниками, и некоторые изменения в работе модуля.

Что делать:

1. По умолчанию доступ к SPIx->DR 16бит. Чтобы получить доступ к SPIx->DR как к регистру 8бит пишем:

Код:
#define SPI1_DR_8bit (*(__IO uint8_t *)((uint32_t)&(SPI1->DR)))
#define SPI2_DR_8bit (*(__IO uint8_t *)((uint32_t)&(SPI2->DR)))

Теперь обращаемся к регистру данных так:

Код:
SPI1_DR_8bit = 0x34;
SPI2_DR_8bit = 0x78;

2. По умолчанию и при запрещённых установках DS [3:0]: Data size регистра SPIx_CR2 устанавливается длина данных 16бит (1111: 16-bit). Поэтому при настройке длины данных логичнее сбрасывать, а не устанавливать определённые биты. Иначе при любой попытке записи некорректного значения, регистр SPIx_CR2 автоматически восстановит длину данных 16бит.
Т.е. для того чтобы установить длину 8бит нужно просто сбросить старший бит DS [3:0] регистра SPIx_CR2.

3. Также встречались жалобы на непонятное поведение бита RXNE. Всё дело в бите FRXTH регистра SPIx_CR2, при работе с данными 8бит требуется его установить .


После решения этой проблемы появились новые (кудаж бл* без них :kill: ). Основная беда - это нога NSS. Как только я не пытался заставить МАСТЕРА ее дергаться аппаратно, но он все время показывал мне неприличный жест. В итоге я забил на это и реализовал аппаратный ногодрыг. Но и тут проблемы не закончились. Имеются у меня такие функции записи в регистры слейва данных:
Код:
uint8_t SPI2_send_byte(uint8_t data)
{
   while (!(SPI2->SR & SPI_SR_TXE));
   (*(__IO uint8_t *)((uint32_t)&(SPI2->DR))) = data;
   while (!(SPI2->SR & SPI_SR_RXNE));              
   return  (*(__IO uint8_t *)((uint32_t)&(SPI2->DR)));   
}

void SPI2_write_reg(uint8_t address, uint8_t value)
{
   SPI2_NSS_LOW;   
   SPI2_send_byte(address);
   SPI2_send_byte(value);
   SPI2_NSS_HIGHT;
}

....................................................................................

void RC522_write_register(uint8_t addr, uint8_t val)
{
   addr = (addr << 1) & 0x7E;
    SPI2_write_reg(addr, val);
}

uint8_t RC522_read_register(uint8_t addr)
{
   uint8_t val;

   addr = ((addr << 1) & 0x7E) | 0x80;
   val = SPI2_read_reg(addr);
   return val;   
}



и дефайны для NSS:

Код:
#define SPI2_NSS_HIGHT                        GPIOB->BSRR = GPIO_BSRR_BS_12
#define SPI2_NSS_LOW                        GPIOB->BSRR = GPIO_BSRR_BR_12


В main.c я посылаю серию данных по SPI:
Код:
   SPI2_write_reg(0x02, 0x0F); // RESET
   RC522_write_register(0x2A, 0x8D);
   RC522_write_register(0x2B, 0x3E);
   RC522_write_register(0x2D, 30);           
   RC522_write_register(0x2C, 0);
   RC522_write_register(0x26, 0x70);   
   RC522_write_register(0x15, 0x40);
   RC522_write_register(0x11, 0x3D);


Так вот между посылками команд проходит очень мало времени, из-за чего строб NSS получается ничтожно маленьким. Это сбивает дальнейшее общение по шине. Я сделал топорное решение и после каждой отправки байта в регистр запихал программную задержку в несколько тактов:
Код:
   SPI2_write_reg(0x02, 0x0F); // RESET
   while (Tempi < 100000)
      {Tempi++;}
   Tempi = 0;
   
   RC522_write_register(0x2A, 0x8D);
      while (Tempi < 2)
      {Tempi++;}
   Tempi = 0;
   
   RC522_write_register(0x2B, 0x3E);
      while (Tempi < 2)
      {Tempi++;}
   Tempi = 0;
   
   RC522_write_register(0x2D, 30);           
........................................................

После таких извращений данные передаются и я получаю нормальный ответ от слейва.
Собственно вопрос: Как правильно контролировать длину строба NSS между транзакциями, чтоб она не была слишком мелкой? Может есть какие флаги или хитрости?
Я пробовал работать с BSY, но толку нет. :dont_know:

Автор:  pokk [ Пт июн 02, 2017 10:35:17 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Посмотрите какая вам нужна задержка, если хватает пару тактов,
то их можно внутри дефайна спрятать.
Код:
#define SPI2_NSS_HIGHT                        GPIOB->BSRR = GPIO_BSRR_BS_12; asm("nop");asm("nop");asm("nop");

Автор:  dosikus [ Пт июн 02, 2017 11:26:51 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

isx, почитай мои посты начиная отсюда viewtopic.php?f=59&t=67578&start=2400

pokk, задержки здесь и на не нужны, здесь главное осознать работу SPI и назначение флагов SPI...

Автор:  Myp3ik [ Пт июн 02, 2017 12:32:38 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Цитата:
Может есть какие флаги или хитрости?


Для начала, есть флаги:

SPI_I2S_FLAG_TXE: Transmit buffer empty flag,
SPI_I2S_FLAG_RXNE: Receive buffer not empty flag,

потом можно перейти к прерываниям. Затем к DMA. В SPL индусы нарисовали примеры для каждого случая :idea:

Автор:  isx [ Пт июн 02, 2017 17:53:57 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

pokk писал(а):
Посмотрите какая вам нужна задержка, если хватает пару тактов,
то их можно внутри дефайна спрятать.

Дык в том то и дело, что мне программные задержки вообще не нужны. И циклы while в функции SPI2_send_byte я тоже через прерывания потом переделаю. Касаемо программных задержек - у меня паранойя. Я уже и забыл последнюю программу, в которой они у меня были. Все исключительно через прерывания и таймеры :) .
Myp3ik писал(а):
Для начала, есть флаги:

Ну дык поглядите в мою функцию SPI2_send_byte. Там как раз все через эти флаги и работает. Выход из нее происходит только после очистки RXNE, а к этому времени TXE уже точно сброшен. Вот и получается, что при стробе оба флага уже очищены. :dont_know:
dosikus писал(а):
почитай мои посты начиная отсюда

Ушел читать :) .

Добавлено after 37 minutes 2 seconds:
Прочел, но что-то не нашел ответа. И функция вроде такая же была. Только при DMA появились новые флаги, но DMA у меня пока нет....

Автор:  dosikus [ Сб июн 03, 2017 16:01:57 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

isx,

Для одиночных транзакций, даже если не принимаем :

Данные в буфер
Ждем флаг RXNE
Вычитываем буфер

С BSY :

проверяем TXE
Данные в буфер
Проверяем BSY

Но BSY больше подходит для блочных транзакций ...

Автор:  isx [ Сб июн 03, 2017 22:01:50 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Это понятно. У меня же в функции записи есть return (*(__IO uint8_t *)((uint32_t)&(SPI2->DR))); .
А проблему решил таки. По RM строб у SPI должен быть длительностью не менее одного периода тактовой частоты (на практике оказалось, что работает и с длительностью в пару раз меньше), но у меня он был меньше раза в 3. В настройках SPI биты SPI_CR1_BR были установлены все, что означало делитель тактовой частоты в 256. При 8МГц тактовой ядра мы получаем частоту тактирования SPI примерно 31КГц и период около 32 мкс. Время перехода от конца до начала функции (оно же время строба NSS) у меня составило около 6 мкс. с проверками флагов, чего было явно недостаточно.
Решение: тупо увеличиваем частоту SPI установкой битов SPI_CR1_BR, чтоб период составил не менее 6мкс. (в моем случае).

P.S. С этими бесконтактными картами оказалось все не так просто. Сейчас создам отдельную тему, если кого заинтересует - милости просим :) .

Автор:  wss60 [ Пн июн 05, 2017 03:00:08 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Здравствуйте! Есть контроллер STM32F103ZGT6, который ведет себя как-то странно:
При определённом размере программы может перестать запускается, для того что бы его оживить нужно в произвольном месте программы добавить любую функцию – например delay, или в массивах начинает появляется непонятные значения – мусор. Подозрение что у микроконтроллера битая ОЗУ.
Можно ли как-нибудь проверить память контроллера?

Автор:  aam [ Пн июн 05, 2017 20:39:46 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Скорее, у него битая ПЗУ. Сколько раз уже перепрошивали?

Автор:  isx [ Вт июн 06, 2017 00:36:16 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Попробуйте для начала полностью стереть память чипа. В Кейле для этого нужно в настройках отладчика во вкладке Flash Download в разделе Download Function выбрать Erase Full Chip.
Также, если работаете на высокой частоте, то проверьте делитель для низкоскоростной шины и FLASH. Либо просто прогоните программу на восьми мегагерцах.

Автор:  wss60 [ Вт июн 06, 2017 00:45:58 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Изменил порядок инициализации PLL и вроде пока стало работать нормально. Хотя до этого этот же код на другом контроллере работал нормально.

Спойлер
Код:
void SystemClock_Config (void)
{
   
   RCC->CR|=RCC_CR_HSEON;              // Enable HSE.
   while (!(RCC->CR & RCC_CR_HSERDY)); // wait HSE.

   RCC->CFGR |=  RCC_CFGR_PPRE1_2;   //APB1 - 36MHz Max
   
   RCC->CFGR |=  RCC_CFGR_PLLSRC;      //HSE(8MHz) <- PLL
   RCC->CFGR &= ~RCC_CFGR_PLLXTPRE;    //HSE(8MHz) clock not divided
   RCC->CFGR |= RCC_CFGR_PLLMULL9;     //PLL multiplication
   
   RCC->CR |= RCC_CR_PLLON;
   while(!(RCC->CR&RCC_CR_PLLRDY));
   RCC->CFGR |= RCC_CFGR_SW_PLL;    // <---- перенес сюда

   FLASH->ACR |= FLASH_ACR_PRFTBE;   // Enable Prefetch Buffer
   FLASH->ACR &= ~FLASH_ACR_LATENCY; // Clear
   //FLASH->ACR |= FLASH_ACR_LATENCY_0; //SystemCoreClock <= 24 MHz
   //FLASH->ACR |= FLASH_ACR_LATENCY_1; //24< SystemCoreClock <= 48 MHz
   FLASH->ACR |= FLASH_ACR_LATENCY_2; //48< SystemCoreClock <= 72 MHz
   
   // <---- был здесь
}

Автор:  isx [ Вт июн 06, 2017 01:34:11 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Цитата:
RCC->CFGR |= RCC_CFGR_SW_PLL;

Не хватает флага перехода на PLL. А может и ещё чего (ночь, мозги тормозят :) ).
У меня сначала переключается FLASH, а потом PLL.
Я всегда пользуюсь таким блоком кода:
Код:
//Тактируем ядро   

    RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
   RCC->CR &= ~RCC_CR_PLLON; //Отключаем генератор PLL
   RCC->CR &= ~RCC_CR_HSEON;
   while((RCC->CR & RCC_CR_HSERDY)!=0) {}
   
   RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
   while((RCC->CR & RCC_CR_HSIRDY)==0) {}
   RCC->CFGR |= RCC_CFGR_SW_HSI; //Выбрать источником тактового сигнала HSI
   
         
//FLASH->ACR |= FLASH_ACR_HLFCYA;
  FLASH->ACR |= FLASH_ACR_LATENCY_1; // Пропускаем по два такта (работаем с каждым третьим)
  FLASH->ACR |= FLASH_ACR_PRFTBE; // включаем упреждающее чтение
   while((FLASH->ACR & FLASH_ACR_PRFTBS)==0) {} // ожидаем установки бита
   
   RCC->CFGR |= RCC_CFGR_ADCPRE_1; // ADC Clock devide by 6 (MAX 14 MHz, clock from AHB2 bus)
   
   RCC->CFGR &= ~RCC_CFGR_PLLSRC; //Источник сигнала для PLL - HSE (внешний генератор)
  RCC->CR &= ~RCC_CR_PLLON; //Отключаем генератор PLL
  RCC->CFGR &= ~RCC_CFGR_PLLMULL; //Очищаем биты предделителя
   RCC->CFGR |= RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_2; //Коефициент умножения 9 (при кварце на 8 МГц будет 72 МГЦ)
   RCC->CFGR |= RCC_CFGR_PPRE1_2; // Претделитель низкоскоростной шины APB1 на 2
   RCC->CR |= RCC_CR_PLLON; //Включаем PLL
  while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ждем готовность PLL
   
  //Переключаемся на тактирование от PLL
    
   RCC->CFGR |= RCC_CFGR_SW_1 ; //Источник тактового сигнала - PLL
      
  while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {} //Ждем переключения на PLL

Автор:  wss60 [ Вт июн 06, 2017 02:41:39 ]
Заголовок сообщения:  Re: STM32 новичку в ARM что к чему

Не хватает флага перехода на PLL.

И не только его. Похоже, из-за этого и были глюки при запуске.
Попробовал ваш код - частота упала в два раза. Только потом дошло что PLL, запитан от внутреннего генератора. :)
Спасибо! Теперь вроде разобрался.

Страница 179 из 423 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/