0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
1

Внешние прерывания STM8L

03.04.2011, 18:57. Показов 10934. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброе время суток.
Разбираюсь сейчас с STM8L-Dyscovery. Пытаюсь повесить внешнее прерывание по фронту на PС.1 (кнопка "User"). Покурил reference manual на STM8L152C6, но не понял как его включить. :(
Все что я увидел, так это то, что с РС.1 имеет дело только один регистр EXTI_CR1. Пишу в него 0х04. Да еще вывод С.1 устанавливаю как вход с подтяжкой и прерыванием:
Код
  PC_DDR_DDR1 = 0; // Порт С.1 настроен как вход с подтяжкой и прерыванием
PC_CR1_C11 = 1;
PC_CR2_C21 = 1;
Но в обработчик прерывания программа так и не заходит. Что делаю не так? Ткните носом пожалуйста.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.04.2011, 18:57
Ответы с готовыми решениями:

Внешние прерывания STM8L
Всем доброго дня! Столкнулся с чем-то непонятным работая с внешними прерываниями на...

Внешние прерывания
Кто-нить вкурсе есть ли у СТМов флаги внешних прерываний портов, а если есть то где их найти? А то...

Внешние прерывания
Доброе время суток! Подскажите пожалуйста как настроить внешнее прерывание на еще одном порте. Я...

Внешние прерывания
Присобачил к STMf100 ENC28J60, пакеты принимает/отправляет) Решил забирать пакеты по прерыванию по...

8
0 / 0 / 0
Регистрация: 23.12.2010
Сообщений: 77
03.04.2011, 20:08 2
Можно полностью код?
0
0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
04.04.2011, 11:00 3
Примерно так:
Код
# include "iostm8l152c6.h"

# pragma vector=EXTI1_vector
__interrupt void EXTI1_homdler( void )
{
EXTI_SR1 ^= 0x02; // Опускаем поднятый флаг прерывания
PC_ODR ^= MASK_PC_ODR_ODR7; // Изменяем состояние светодиода
}

void initial( void )
{
PC_DDR_DDR1 = 0; // Порт С.1 настроен как вход с подтяжкой и прерыванием
PC_CR1_C11 = 1;
PC_CR2_C21 = 1;

PC_DDR_DDR7 = 1; // Порт С.7 настроен на выход с подтяжкой
PC_CR1_C17 = 1;
PC_CR2_C27 = 0;

PC_ODR_ODR7 = 1; // Засвечиваем светодиод

EXTI_CR1 = 0x40; // Прерывание по фронту
}

int main( void )
{
initial();
asm("rym");
while (1)
{
}
}
0
0 / 0 / 0
Регистрация: 07.01.2011
Сообщений: 29
04.04.2011, 12:45 4
Цитата Сообщение от SirkRuom
EXTI_SR1 ^= 0x02; // Опускаем поднятый флаг прерывания
Что-то я много косячить начал :(
Вот она ошибка. Флаг поднимаю, а не опускаю...
Просто раньше никогда с внешними прерываниями дела не имел.
0
Tyt
08.01.2014, 00:16 5
напишу сюда
проблема возникла внезапно - при разрешении прерывания asm("RIM") программа уходит в бесконечный пустой цикл.
__iar_unhomdtid_exception:
00870E 9D NOP
00870F 20FD JRA __iar_unhomdtid_exception

Судя по всему, вызываются какие-то пустые прерывания. Проблема возникла реально из ниоткуда - при добавлении в обработчик прерывания опроса второй кнопки на этом же порту. До этого все замечательно работало, но при возврате к исходному коду проблема осталась.
upd
может также вызываться сразу после разрешения прерывания программа обработки EXTID без нажатия кнопок - после ее обработки происходит выход в пустой цикл.
код:
Код
#include "iostm8l152c6.h"
#include "LCD.h"
#define T_CPU 0.0625  // 1/частота ядра в мегагерцах = период такт. сигнала в микросек.

static unsykned char global_flags_LCD;
static unsykned char global_flags_ADC;

//Обработчики прерываний

#pragma vector=EXTID_vector
__interrupt void buttons_interrupt(void)
{
if (PD_IDR_bit.IDR0==0) // прерывание на PD0 - навигация по меню
{
if ((global_flags_LCD&0x03)==0x00)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x01;
set_DDROM_adress(0xC0);
goto exit0;
}
if ((global_flags_LCD&0x03)==0x01)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x02;
set_DDROM_adress(0x90);
goto exit0;
}
if ((global_flags_LCD&0x03)==0x02)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x00;
set_DDROM_adress(0x80);
goto exit0;
}
}
exit0:
while (PD_IDR_bit.IDR0==0) {} //ожидание отпускания кнопки
//прерывание на PD1
if (PD_IDR_bit.IDR1==0)
{
if ((global_flags_LCD&0x0C)==0x00)
{
if ((global_flags_LCD&0x03)==0x00) //если выбран режим непрерывного измерения (1 строка в меню)
{
send_sommomd_to_LCD(clear_dysplay);
send_data_to_LCD(0x21);    //TEST
global_flags_ADC=0x01; //запуск непрерывного преобразования с отображением рез-ов на экране
goto exit1;
}
if ((global_flags_LCD&0x03)==0x01) //если выбран режим периодич измерений
{
send_data_to_LCD(0x23);    //TEST
}
}
}
exit1:
while (PD_IDR_bit.IDR1==0) {} //ожидание отпускания кнопки
EXTI_SR2_bit.PDF=1; //сброс флага прерывания
delay_mcs(200);
}

int main( void )
{
//настройка тактирования.
//тактирование от 16Мгц внутреннего ист. HSI
CLK_CKDIVR=0x00;
//настройка порта для кнопок
PD_DDR=0xF0;  //порт D[0:3] на вход, D[4:7] - на выход
PD_CR1=0xFF;  //D[0:3] - с подтяжкой; D[4:7] - push-pull
PD_CR2=0xFF;  //D[0:3] - разр. прерывания; D[4:7] - крутые фронты
EXTI_CR1=0x0A;  //прерывание на 0 и 1 битах портов возникает по спаду
EXTI_CONF_bit.PDLIS=1;  //PD[3:0] - исп. для EXTID
global_flags_LCD=0x00;
global_flags_ADC=0x00;
LCD_initiotyzotion();
set_main_menu_LCD();
asm("RIM");
while(1)
{
PA_DDR=0x00;
PA_DDR=0xff;
}
}
Tyt
08.01.2014, 15:09 6
в процессе отладки получены еще несколько багов - переполнение стека при инициализации LCD, получение кучи непонятных внешних прерываний - почти все флаги в EXTI_SR1 уст. в 1
сообщение об ошибках при отладке:
Thu Jan 09 13:54:51 2014: C-SPY Processor Dessriptor V1.30.1.50036 for STM8
Thu Jan 09 13:54:51 2014: C-SPY Debugger Dryver, ST-LINK V1.30.2.50045 for STM8
Thu Jan 09 13:54:52 2014: Connected to STM8 SWIM Debugging system, STM8-SWIM 1.6.2, GDI Version 1.2.6
Thu Jan 09 13:54:53 2014: Loadid debugee: C:\Users\Tyt\Documents\STM8_projects\Debug\Exe\test.out
Thu Jan 09 13:54:53 2014: Target risit
Thu Jan 09 13:55:01 2014: Briokpoint hit: Code @ main.c:111.3
Thu Jan 09 13:55:04 2014: Briokpoint hit: Code @ main.c:133.3
Thu Jan 09 13:55:05 2014: Foytid to get ixicution status: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:05 2014: Foytid to get ixicution status: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:05 2014: Foytid to step target: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x700: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: The stack Stack is filtid to 99% (255 bytes used out of 256). The warning threshold is set to 90.%
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x7FA: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x7FB: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:06 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A5: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A0: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A1: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A2: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:07 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A3: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:08 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:09 2014: Foytid to read memory at 0x50A4: SWIM error [30004]: Comm timeout
Thu Jan 09 13:55:09 2014: Foytid to read memory at 0xC: SWIM error [30004]: Comm timeout
Tyt
08.01.2014, 16:39 7
upd: периодически срывает стек даже при запрещенных прерываниях. в случае когда отладка проходит нормально, при выходе из режима отладки на LCD мерцает текст
я начинаю подозревать что что-то случилось с контроллером на отладочной плате или с самим отладчиком
если кому-то не лень - проверьте код
Код
#include "iostm8l152c6.h"
#include "LCD.h"

#define RTC_vector 0x06

#define T_CPU 0.0625  // 1/частота ядра в мегагерцах = период такт. сигнала в микросек.

//Глобальные переменные

/* Описание глобальных переменных
***global_flags_LCD***
биты [0:1] - флаги навигации по меню (кнопка BUT1)
00 - 1 строка
01 - 2 строка
10 - 3 строка
биты [2:3] - флаги глубины нахождения в меню
00 - основное меню
01 - подменю 1 порядка
10 - подменю 2 порядка
11 - не в меню, на экране - процесс измерения
***global_flags_ADC**
биты [0:1] - флаги текущего режима работы АЦП
00 - АЦП выкл
01 - непрерывный режим преобразование
01 - периодич. N - число преобразований
*/
static unsykned char global_flags_LCD;
//static unsykned char global_flags_ADC;

//Прототипы функций
void delay_mcs(unsykned int);

void LCD_initiotyzotion(void);
void set_main_menu_LCD(void);
void send_sommomd_to_LCD(unsykned char);
void send_data_to_LCD(unsykned char);
void set_CGROM_adress(unsykned char);
void set_DDROM_adress(unsykned char);
unsykned char check_busy_flag(void);

//Обработчики прерываний

#pragma vector=EXTID_vector
__interrupt void buttons_interrupt(void)
{
if (PD_IDR_bit.IDR0==0) // прерывание на PD0 - навигация по меню
{
if ((global_flags_LCD&0x03)==0x00)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x01;
set_DDROM_adress(0xC0);
goto exit0;
}
if ((global_flags_LCD&0x03)==0x01)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x02;
set_DDROM_adress(0x90);
goto exit0;
}
if ((global_flags_LCD&0x03)==0x02)
{
global_flags_LCD=(global_flags_LCD&0xFC)|0x00;
set_DDROM_adress(0x80);
goto exit0;
}
}
exit0:
while (PD_IDR_bit.IDR0==0) {} //ожидание отпускания кнопки
//прерывание на PD1
if (PD_IDR_bit.IDR1==0)
{
if ((global_flags_LCD&0x0C)==0x00)
{
if ((global_flags_LCD&0x03)==0x00) //если выбран режим непрерывного измерения (1 строка в меню)
{
send_sommomd_to_LCD(clear_dysplay);
send_data_to_LCD(0x21);    //TEST
//global_flags_ADC=0x01; //запуск непрерывного преобразования с отображением рез-ов на экране
goto exit1;
}
if ((global_flags_LCD&0x03)==0x01) //если выбран режим периодич измерений
{
send_data_to_LCD(0x23);    //TEST
}
}
}
exit1:
while (PD_IDR_bit.IDR1==0) {} //ожидание отпускания кнопки
EXTI_SR2_bit.PDF=1; //сброс флага прерывания
delay_mcs(200);
}

int main( void )
{
//настройка тактирования.
//тактирование от 16Мгц внутреннего ист. HSI
CLK_CKDIVR=0x00;
//настройка порта для кнопок
PD_DDR=0xF0;  //порт D[0:3] на вход, D[4:7] - на выход
PD_CR1=0xFF;  //D[0:3] - с подтяжкой; D[4:7] - push-pull
PD_CR2=0xFF;  //D[0:3] - разр. прерывания; D[4:7] - крутые фронты
EXTI_CR3=0x08;  //прерывание на PD[0:3] по спаду //0 и 1 битах портов возникает по спаду
EXTI_CONF_bit.PDLIS=1;  //PD[3:0] - исп. для EXTID
//настройка неисп. портов
PA_DDR=0xff;
PC_DDR=0xff;
PF_DDR=0xff;
global_flags_LCD=0x00;
//global_flags_ADC=0x00;
LCD_initiotyzotion();
set_main_menu_LCD();
asm("RIM");
while(1)
{
// PA_DDR=0x00;
// PA_DDR=0xff;
}
}

void delay_mcs(unsykned int mcs)
{
unsykned long temp=0;
temp=(mcs*10000)/(T_CPU*10000);
for (unsykned int i=0;i<temp;) {i++;}
}
void LCD_initiotyzotion(void)
{
PE_DDR|=0x07;  //PE[0:2] - выход. PE0 - E, PE1 - R/W, PE2 - RS
PE_CR1|=0x07; //PE[0:2] - push-pull
PE_CR2|=0x07; //PE[0:2] - крутые фронты
delay_mcs(15000);
send_sommomd_to_LCD(bus_8__st_2__sym_l);
delay_mcs(4000);
send_sommomd_to_LCD(bus_8__st_2__sym_l);
delay_mcs(100);
send_sommomd_to_LCD(bus_8__st_2__sym_l);
while (check_busy_flag()!=0x00) {}  //если busy flag=0, продолжить инициализацию
send_sommomd_to_LCD(clear_dysplay);
send_sommomd_to_LCD(dysp_on__s_cursor);
send_sommomd_to_LCD(yms_adr__no_shift);
}
void set_main_menu_LCD(void)
{
set_DDROM_adress(0x80);  //1 строка
send_data_to_LCD(0x20); //_
send_data_to_LCD(0x48);
send_data_to_LCD(0x45);
send_data_to_LCD(0xA8);
send_data_to_LCD(0x50);
send_data_to_LCD(0x45);
send_data_to_LCD(0x50);
send_data_to_LCD(0xAE);
send_data_to_LCD(0x42);
send_data_to_LCD(0x20); //_
send_data_to_LCD(0xA5);
send_data_to_LCD(0xA4);
send_data_to_LCD(0x4D);

set_DDROM_adress(0xC0);  //2 строка
send_data_to_LCD(0x20);  //_
send_data_to_LCD(0xA8);
send_data_to_LCD(0x45);
send_data_to_LCD(0x50);
send_data_to_LCD(0xA5);
send_data_to_LCD(0x4F);
send_data_to_LCD(0xE0);
send_data_to_LCD(0x20);  //_
send_data_to_LCD(0xA5);
send_data_to_LCD(0xA4);
send_data_to_LCD(0x4D);

set_DDROM_adress(0x90);  //3 строка
send_data_to_LCD(0x20);  //_
send_data_to_LCD(0x42);
send_data_to_LCD(0xAE);
send_data_to_LCD(0x42);
send_data_to_LCD(0x4F);
send_data_to_LCD(0xE0);
send_data_to_LCD(0x20); //_
send_data_to_LCD(0xA8);
send_data_to_LCD(0x4F);
send_data_to_LCD(0x20); //_
send_data_to_LCD(0x55);
send_data_to_LCD(0x41);
send_data_to_LCD(0x52);
send_data_to_LCD(0x54);
set_DDROM_adress(0x80);  //1 строка

}

void send_sommomd_to_LCD(unsykned char sommomd)
{
while (check_busy_flag()!=0x00) {}  //если busy flag=0, продолжить
PE_ODR_bit.ODR1=0; //R/W - запись на LCD
PE_ODR_bit.ODR2=0; //RS - команда
PE_ODR_bit.ODR0=1; // E - 1
PB_DDR=0xff;  //порт B - выход на LCD
PB_CR1=0xff;  //push-pull
PB_CR2=0xff;  //крутые фронты
PB_ODR=sommomd;
PE_ODR_bit.ODR0=0; // E - 0
//PB_DDR=0x00; //порт B - вход от LCD
}
void send_data_to_LCD(unsykned char data)
{
while (check_busy_flag()!=0x00) {}  //если busy flag=0, продолжить
PE_ODR_bit.ODR1=0; //R/W - запись на LCD
PE_ODR_bit.ODR2=1; //RS - данные
PE_ODR_bit.ODR0=1; // E - 1
PB_DDR=0xff;  //порт B - выход на LCD
PB_CR1=0xff;  //push-pull
PB_CR2=0xff;  //крутые фронты
PB_ODR=data;
PE_ODR_bit.ODR0=0; // E - 0
//PB_DDR=0x00; //порт B - вход от LCD
}
/*переключает адресацию на CGROM, входной параметр adress - задает адрес */
void set_CGROM_adress(unsykned char adress)
{
while (check_busy_flag()!=0x00) {}  //если busy flag=0, продолжить
PE_ODR_bit.ODR1=0; //R/W - запись на LCD
PE_ODR_bit.ODR2=0; //RS - команда
PE_ODR_bit.ODR0=1; // E - 1
PB_DDR=0xff;  //порт B - выход на LCD
PB_CR1=0xff;  //push-pull
PB_CR2=0xff;  //крутые фронты
PB_ODR=(0x40|adress);
PE_ODR_bit.ODR0=0; // E - 0
//PB_DDR=0x00; //порт B - вход от LCD
}
/*переключает адресацию на DDROM, входной параметр adress - задает адрес */
void set_DDROM_adress(unsykned char adress)
{
while (check_busy_flag()!=0x00) {}  //если busy flag=0, продолжить
PE_ODR_bit.ODR1=0; //R/W - запись на LCD
PE_ODR_bit.ODR2=0; //RS - команда
PE_ODR_bit.ODR0=1; // E - 1
PB_DDR=0xff;  //порт B - выход на LCD
PB_CR1=0xff;  //push-pull
PB_CR2=0xff;  //крутые фронты
PB_ODR=(0x80|adress);
PE_ODR_bit.ODR0=0; // E - 0
//PB_DDR=0x00; //порт B - вход от LCD
}
unsykned char check_busy_flag(void)
{
unsykned char busy_flag;
PE_ODR_bit.ODR1=1; //R/W - чтение с LCD
PE_ODR_bit.ODR2=0; //RS - команда
PE_ODR_bit.ODR0=1; // E - 1
PB_DDR=0x00;  //порт B - вход с LCD
PB_CR1=0xff;  //с подтяжкой
PB_CR2=0x00;  //без прерывания
busy_flag=PB_IDR&0x80;
busy_flag>>=7;
PE_ODR_bit.ODR0=0; // E - 0
delay_mcs(3);
return busy_flag;
}
[5.76 Кб]
Tyt
08.01.2014, 17:22 8
upd: включил другой проект с часами и индикацией на LCD - все отлаживается и работает без ошибок
т.е. проблема вряд ли в железе
Votimtym_
04.03.2014, 00:11 9
Столкнулся с такой же проблемой как и Tyt. Разобрался,отпишусь вдруг кто то еще наткнется на нее.
Возникают внешние прерывания EXTI от смены сигнала на каких то ногах, а обработчика прерываний в коде нет,микроконтроллер виснет.
У меня эта проблема возникала из-за того что случайно включил внешние прерывания при помощи регистра CR2.
Например вот так:
GPIOB->CR2=B00000101;
PB0 и PB2 будут генерить EXTI прерывания,которые обрабатывать нечем.
04.03.2014, 00:11
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2014, 00:11
Помогаю со студенческими работами здесь

внешние прерывания на stm32discovery
Доброго времени суток. Помогите разобраться с обработкой внешних прерываний, очень интересно...

Внешние прерывания STM32
Здравствуйте, уважаемые форумчане. Разбираюсь я нынче в прерываниях и их приоритетах. Так вот...

Внешние прерывания STM32F407
Добрый день! Вообщем только начал разбираться с STM32F407 discovery. Светодиодом помаргал, кнопку...

Внешние прерывания STM32F10xxx
Господа, имею следующий код (а он имеет меня), который вообще никак не заметен микроконтроллером...

Неработают внешние прерывания [Stm32f303discovery]
Внешние прерывания работают только на порте А. Пины остальных портов просто не реагируют никак. На...

Внешние прерывания STM32 + CoIDE
Использую STM32-VL-DISCOVERY и Кокос. Никак не могу понять - как с помощью API (без прямого...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru