![]() |
|
Компьютеры Уголок для решения бытовых компьютерных проблем. |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
![]() |
#51 |
![]()
попробую переписать программу с внесенными предложениями, и выложу на обозрение.
так-же и схему устройства предоставлю
__________________
Надейся на лучшее, расчитывай на худшее Люблю Таврооргию. Такого пох№зма и подъ№балова нигде не встретишь! (c) Lusi |
|
![]() |
![]() |
![]() |
#52 |
ЗАДОЛБЛО
Адрес: Адреса - нова пошта в рiзних мiстах україни.
Возраст: 51
Сообщений: 1,032
Длина: 2170мкм
Диаметр: 28мм
|
![]()
По поводу АВР, подскажите среду ... а то я в ардуине, но хотелось бы устройство перенести в железку. Чтобы было меньше и универсальней.
__________________
Просіть і буде вам дано, шукайте і знайдете, стукайте і відчинять вам |
![]() |
![]() |
![]() |
#53 |
Адрес: Днепропетровск
Сообщений: 11,717
Машина: Tesla model S 85, Таврия 1.3 инж.
Длина: 65820мкм
Диаметр: 33мм
|
![]()
Среду чего? Программирования на С? Разные есть. IAR, но он навороченный слишком, новичка может отпугнуть. Codevision демократичнее. Я использую ImageCraft ICC7, очень нравится своей простотой и наличием аппликейшн билдера, автоматически генерирующего правильный код настройки периферии буквально за несколько кликов мышкой.
|
![]() |
![]() |
![]() |
#54 |
![]()
Для своих поделок CVAVR самое оно.
А IAR он не навороченный, он как-раз тупо голый. Но у него с оптимизацией более правильно сделано. |
|
![]() |
![]() |
![]() |
#55 |
Адрес: Днепропетровск
Сообщений: 11,717
Машина: Tesla model S 85, Таврия 1.3 инж.
Длина: 65820мкм
Диаметр: 33мм
|
![]()
Не знаю, меня оптимизатор ИмиджКрафта очень даже устраивает. Компилил как-то один и тот же код ИАРом и Крафтом, у Крафта код получился меньше. К тому же там есть очень полезная фича "Code Compression", уменьшает размер кода примерно на 12% за счет небольшого снижения скорости работы. Незаменимо, когда проект чуть-чуть не влазит в выбранный чип, а менять чип уже не хочется.
|
![]() |
![]() |
![]() |
#56 |
Адрес: Вишгород
Возраст: 53
Сообщений: 2,052
Машина: ржавый корч плюс второй ржавый корч
Длина: 32860мкм
Диаметр: 26мм
|
![]()
Вопросы ТС, уточнение по энкодеру (точнее по табличке):
в случае "х" (нельзя задать) на вход МК таки будет приходить 0 или 1? Также интересен вопрос по "-". Ясно, что не учитывается, какое оно будет реально? Я вижу в кусках кода включение резисторов подтяжки.. Вероятно, кнопки коротят входы МК на землю, а на разомкнутых контактах будет "1"? Еще один важный вопрос - в табличке PA5-7 и PB0-3 поданы как исходные данные, а PD2-6 как результат. Да и в программе порты сконфигурированы соответствующим образом. Однако, я посмотрел внимательно на табличку и увидел закономерность: кроме строк 6 и 7, PA5-7 однозначно описывают состояния выходов. А для того, чтобы отличить строки 6 и 7, достаточно будет посмотреть состояние PB0. Выходит, на задатчике достаточно одной кнопки? Или я что-то не так понял? Ну и это - там правильно подсказали: не работают почему-то простейшие вещи, так что попробуйте для начала проверить состояние одного пина и в ответ давать 1 или 0 на другой. |
![]() |
![]() |
![]() |
#57 |
Адрес: Вишгород
Возраст: 53
Сообщений: 2,052
Машина: ржавый корч плюс второй ржавый корч
Длина: 32860мкм
Диаметр: 26мм
|
![]()
И прошу прощения у ТС, раз заговорили об оптимизации, задам свой вопрос:
Есть поверье, что t = ((t << 7) | (t >> 1)) некоторые компиляторы компилируют в ROR. У меня не вышло такого добиться. Кто-то с этим сталкивался? На чем-то получалось? |
![]() |
![]() |
![]() |
#58 |
![]()
всмысле? всё выражение в один ROR? Такого же не бывает. )
|
|
![]() |
![]() |
![]() |
#59 |
Адрес: Вишгород
Возраст: 53
Сообщений: 2,052
Машина: ржавый корч плюс второй ржавый корч
Длина: 32860мкм
Диаметр: 26мм
|
![]()
Ну так по сути это ROR и есть.
Просто для SHL и SHR в C есть << и >>. А для ROL, ROR нет ничего. Их можно заменить: int rol(int value, int places) { return (value<<places)|(value>>(WORD_LENGTH-places); } int ror(int value, int places) { return (value>>places)|(value<<WORD_LENGTH-places); } Но напрямую это скомпилируется в SHR и SHL для каждой функции. Вот в каких-то интернетах чувак утверждал, что с включенной оптимизацией компилер понял, что это именно ROL и ROR и соптимизировал. Мой gcc не удалось заставить это понять. |
![]() |
![]() |
![]() |
#60 |
![]()
ну как только ROR если команду ИЛИ тоже надо выполнить.
и в авр нет SHL и SHR, есть LSL и LSR, отличие от ROL и ROR только в переносе старшего бита в младший. В SHL и SHR этого переноса нет. Только никак не применю к вашему выражению, о котором ходит поверье... ) Последний раз редактировалось Kino; 07.11.2013 в 21:17. |
|
![]() |
![]() |
![]() |
#61 |
Адрес: Вишгород
Возраст: 53
Сообщений: 2,052
Машина: ржавый корч плюс второй ржавый корч
Длина: 32860мкм
Диаметр: 26мм
|
![]()
На любой восьмибитной переменной результат такой функции:
__asm { mov eax,MyVar; rol eax,1; mov MyVar,eax; } абсолютно эквивалентен MyVar = (MyVar << 1 | MyVar >> 7) - (сдвиг влево на один бит) или (сдвиг право на семь бит //перенос старшего бита в младший). Ну или для наглядности: rol 10110110 на 1 даст 01101101 вторая функция даст 00000001 or 01101100, т.е. тот же 01101101 По поводу LSL, LSR - да. Это я уже по привычке. |
![]() |
![]() |
![]() |
#62 |
![]()
это наверное сильно надо раздуть прогу, чтобы реально места не хватало. а так, что включена оптимизация, что выключена - по шарабану.
|
|
![]() |
![]() |
![]() |
#63 | ||||
![]() Цитата:
в строке, где "-" возможно только определить положение энкодера (и индицировать его), но выбрать задатчиком это положение нельзя. Это конструктивная особенность энкодера, там ввели лишнюю позицию, которая не используется. Цитата:
Цитата:
Ее (в данном случае) достаточно только чтоб разделить 6ю и 7ю позиции задатчика, а для остальных позиций используются остальные кнопки тоже. Цитата:
но мне тоже кажется, что проблема в настройках ПО для компиляции.
__________________
Надейся на лучшее, расчитывай на худшее Люблю Таврооргию. Такого пох№зма и подъ№балова нигде не встретишь! (c) Lusi |
|||||
![]() |
![]() |
![]() |
#64 |
![]()
ну в общем, есть вариант (недопиленный пока что) программы без GoTO (на функциях):
/* * encoder.cpp * * Created: 28.10.2013 16:50:50 * Author: PVD */ #include <avr/io.h> #include <delay/io.h> char com; char comander; char enc; //Задатчик; //Таблица соответствия состояния энкодера / задатчика положения / индикации положения; // № | PA4 PA5 PA6 | PB0 PB1 PB2 PB3 | PD2-6; // --------------------------------------------------; // 1 | 0 1 1 | 1 1 x 1 | 00010; // 2 | 0 0 1 | 0 1 0 1 | 11010; // 3 | 1 0 1 | 0 1 1 1 | 10010; // 4 | 1 0 0 | x x x 0 | 00001; // 5 | 1 1 0 | - - - - | 00001; // 6 | 0 1 0 | 0 0 x 1 | 11110; // 7 | 0 1 0 | 1 0 x 1 | 00110; int GetEncoder(int) { enc=(PORTA & 0b0111000); if (enc==0b01100000) {(PORTD=0b00010000); return 1;} else if (enc==0b01000000) {(PORTD=0b00010110); return 2;} else if (enc==0b01010000) {(PORTD=0b00010010); return 3;} else if (enc==0b00010000) {(PORTD=0b00100000); return 4;} else if (enc==0b00110000) {(PORTD=0b00100000); return 5;} else if (enc==0b00100000) {(PORTD=0b00011110); return 6;} else { PORTD=0b10000000; if (PORTB0==1) {ErrorHi();} else {ErrorLo();} } } int ErrorHi(void) { PORTC=0b00000000; while (PORTA0==0) {PORTC0=1;}; PORTC=0b00000000; PORTD=0b10011110; while (PORTB0==1) { PORTC2=PINB0; if (PINA3==0 && PINC2==0) {(PIND0=0); (PIND1=0);} else if (PINA3==0 && PINC2==1) {(PIND0=0); (PIND1=1);} else if (PINA3==1 && PINC2==0) {(PIND0=0); (PIND1=1);} else (PINA3==1 && PINC2==1) {(PIND0=1); (PIND1=1);} while (PINB7=0) {Manual();} } ErrorLo(); } int ErrorLo(void) { PORTC=0b00000000; while (PORTA0==0) {PORTC1=1}; PORTC=0b00000000; PORTD=0b10000010; while (PORTB0==0) { while (PINB7=0) {Manual();} } ErrorHi(); } int Manual(int) { PORTC2=PINB0; if (PINA3==0 && PINC2==0) {(PIND0=0); (PIND1=0);} else if (PINA3==0 && PINC2==1) {(PIND0=0); (PIND1=1);} else if (PINA3==1 && PINC2==0) {(PIND0=0); (PIND1=1);} else (PINA3==1 && PINC2==1) {(PIND0=1); (PIND1=1);} enc=(PORTA & 0b0111000); if (enc==0b01100000) {PORTD=0b00010000;} else if (enc==0b01000000) {PORTD=0b00010110;} else if (enc==0b01010000) {PORTD=0b00010010;} else if (enc==0b00010000) {PORTD=0b00100000;} else if (enc==0b00110000) {PORTD=0b00100000;} else if (enc==0b00100000) {PORTD=0b00011110;} else PORTD=0b00011110; } int Critical(void) { while (1) { PORTD=0b10000000; _delay_ms(1000); PORTD=0b00000000; _delay_ms(1000); } } while(1) { int main(void) PORTA=0b11111111; DDRA=0b00000000; PORTB=0b11111111; DDRB=0b00000000; PORTC=0b00000000; DDRC=0b11111111; PORTD=0b00000000; DDRD=0b11111111; PORTD=0b11111111; _delay_ms(2000); PORTD=0b00000000; while (1) { { while (PINB7=0) {Manual()}; { com=(PORTB & 0b00001111) while (comander=0) { _delay_ms(100) if (com==0b00001011) comander=1 else if (com==0b00001010) comander=2 else if (com==0b00001110) comander=3 else if (com==0b00000000) comander=4 else if (com==0b00001000) comander=6 else if (com==0b00001001) comander=6 else comander=0; } } if (GetEncoder() < comander) { PORTC=0b00000000; while (GetEncoder() < comander) {PORTC=0b00000001}; while ((GetEncoder() = comander) && (PINA7 = 1)) {PORTC=0b00001001}; PORTC=0b00000000; if (GetEncoder() = comander) {} else {ErrorHi()}; } else if (GetEncoder() > comander) { PORTC=0b00000000; while (GetEncoder() > comander) {PORTC=0b00000010}; while ((GetEncoder() = comander) && (PINA7 = 1)) {PORTC=0b00001010} PORTC=0b00000000; if (GetEncoder() = comander) {} else {ErrorLo()} } else { PORTC2=PINB01; if (PINA3==0 && PINC2==0) {(PIND0=0) (PIND1=0)} else if (PINA3==0 && PINC2==1) {(PIND0=0) (PIND1=1)} else if (PINA3==1 && PINC2==0) {(PIND0=0) (PIND1=1)} else (PINA3==1 && PINC2==1) {(PIND0=1) (PIND1=1)}; } } }
__________________
Надейся на лучшее, расчитывай на худшее Люблю Таврооргию. Такого пох№зма и подъ№балова нигде не встретишь! (c) Lusi Последний раз редактировалось Pilot; 18.11.2013 в 18:22. |
|
![]() |
![]() |
![]() |
#65 |
![]()
А вот и старый вариант
Порты другие, но сути не меняет /* * TCCM.cpp * * Created: 16.07.2013 11:20:09 * Author: dombrugov_pv */ #include <avr/io.h> #include <util/delay.h> int main(void) { unsigned char E,C; while(1) { // PA.0 - out - display 4 |green; // PA.1 - out - display 4 |red; // PA.2 - out - display lock |green; // PA.3 - out - display lock |red; // PA.4 - out - display low yellow; // PA.5 - out - display 2 green; // PA.6 - out - display N |green; // PA.7 - out - display N,error |red; // PB.0 - in - commander 2/4; // PB.1 - in - commander H/L; // PB.2 - in - commander Lc; // PB.3 - in - commander N; // PB.4 -; // PB.5 -; // PB.6 -; // PB.7 -; // PC.0 - out - motor UP; // PC.1 - out - motor DOWN; // PC.2 - out - front axle control; // PC.3 -; // PC.4 -; // PC.5 -; // PC.6 -; // PC.7 -; // PD.0 - in - encoder A; // PD.1 - in - encoder B; // PD.2 - in - encoder C; // PD.3 - in - encoder P; // PD.4 -; // PD.5 -; // PD.6 - in - front axle state; // PD.7 - in - motor overload; PORTA=0x00; DDRA=0b11111111; PORTB=0x00; DDRB=0b00000000; PORTC=0x00; DDRC=0b00000111; PORTD=0x00; DDRD=0b00000000; PORTA=0b11111111; _delay_ms(2000); PORTA=0b00000000; START: if ((PIND0==1)&&(PIND1==0)&&(PIND2==0)) // Чтение данных с энкодера; { E=0b000001; // преобразование в унитарный код; PORTA&= ~(1<<2); PORTA&= ~(1<<3); // Вывод информации; PORTA&= ~(1<<4); // о состоянии энкодера; PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==1)&&(PIND1==1)&&(PIND2==0)) { E=0b000010; PORTA|=1<<2; PORTA|=1<<3; PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==0)) { E=0b000100; PORTA|=1<<2; PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==1)) { E=0b001000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==0)&&(PIND1==0)&&(PIND2==1)) { E=0b010000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==1)&&(PIND1==0)&&(PIND2==1)) { E=0b100000; PORTA|=1<<2; PORTA|=1<<3; PORTA|=1<<4; PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else { goto ERROR; } if ((PIND6==0)&&(PINC2==0)) // Вывод информации; { // о состоянии; PORTA&= ~(1<<0); // переднего моста; PORTA&= ~(1<<1); } else if ((PIND6==1)&&(PINC2==1)) { PORTA|=1<<0; PORTA|=1<<1; } else { PORTA&= ~(1<<0); PORTA|=1<<1; } READ_C: if (PINB3==1) // Чтение данных с задатчика; { // и преобразование в унитарный код; C=0b001000; } else if ((PINB3==0)&&(PINB1==1)) { C=0b100000; } else if ((PINB3==0)&&(PINB1==0)&&(PINB0==0)) { C=0b000001; } else if ((PINB3==0)&&(PINB1==0)&&(PINB0==1)&&(PINB2==1)) { C=0b000010; } else if ((PINB3==0)&&(PINB1==0)&&(PINB0==1)&&(PINB2==0)) { C=0b000100; } else { goto READ_C; } // Сравнение состояний энкодера и задатчика; if (E<C) // Если состояние энкодера ниже задатчика; UP: { PORTC&= ~(1<<2); PORTC|=1<<0; // Вращение энкодера; PORTC&= ~(1<<1); if ((PIND0==1)&&(PIND1==0)&&(PIND2==0)) // Чтение данных с энкодера; { E=0b000001; // преобразование в унитарный код; PORTA&= ~(1<<2); // Вывод информации о положении энкодера; PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==1)&&(PIND1==1)&&(PIND2==0)) { E=0b000010; PORTA|=1<<2; PORTA|=1<<3; PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==0)) { E=0b000100; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==1)) { E=0b001000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==0)&&(PIND1==0)&&(PIND2==1)) { E=0b010000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==1)&&(PIND1==0)&&(PIND2==1)) { E=0b100000; PORTA|=1<<2; PORTA|=1<<3; PORTA|=1<<4; PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else { goto ERROR; } if ((PIND6==0)&&(PINC2==0)) // Вывод информации о состоянии переднего моста; { PORTA&= ~(1<<0); PORTA&= ~(1<<1); } else if ((PIND6==1)&&(PINC2==1)) { PORTA|=1<<0; PORTA|=1<<1; } else { PORTA&= ~(1<<0); PORTA|=1<<1; } // чтение энкодера; if ((E==C)&&(PINA3==1)) // Остановка мотора по достижении заданной поз-ии; { PORTC&= ~(1<<0); PORTC&= ~(1<<1); goto START; } else if ((E>C)||(PIND7==1)) // переход к программе ошибки при пропуске заданного положения; { // или срабатывании токового реле мотора; goto ERROR; } else { goto UP; } } else if (E>C) // Если состояние энкодера выше задатчика; DOWN: { PORTC&= ~(1<<2); PORTC&= ~(1<<0); // Вращение энкодера; PORTC|=1<<1; if ((PIND0==1)&&(PIND1==0)&&(PIND2==0)) // Чтение данных с энкодера; { E=0b000001; // преобразование в унитарный код; PORTA&= ~(1<<2); // Вывод информации о положении энкодера; PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==1)&&(PIND1==1)&&(PIND2==0)) { E=0b000010; PORTA|=1<<2; PORTA|=1<<3; PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==0)) { E=0b000100; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else if ((PIND0==0)&&(PIND1==1)&&(PIND2==1)) { E=0b001000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==0)&&(PIND1==0)&&(PIND2==1)) { E=0b010000; PORTA&= ~(1<<2); PORTA&= ~(1<<3); PORTA&= ~(1<<4); PORTA&= ~(1<<5); PORTA|=1<<6; PORTA|=1<<7; } else if ((PIND0==1)&&(PIND1==0)&&(PIND2==1)) { E=0b100000; PORTA|=1<<2; PORTA|=1<<3; PORTA|=1<<4; PORTA|=1<<5; PORTA&= ~(1<<6); PORTA&= ~(1<<7); } else { goto ERROR; } if ((PIND6==0)&&(PINC2==0)) // Вывод информации о состоянии переднего моста; { PORTA&= ~(1<<0); PORTA&= ~(1<<1); } else if ((PIND6==1)&&(PINC2==1)) { PORTA|=1<<0; PORTA|=1<<1; } else { PORTA&= ~(1<<0); PORTA|=1<<1; } // чтение энкодера; if ((E==C)&&(PIND3==1)) // Остановка мотора по достижении заданной поз-ии; { PORTC&= ~(1<<0); PORTC&= ~(1<<1); goto START; } else if ((E<C)||(PIND7==1)) // переход к программе ошибки при пропуске заданного положения; { // или срабатывании токового реле мотора; goto ERROR; } else { goto DOWN; } } else // Если состояние энкодера соответствует задатчику; { if ((PINB0==1)&&(PINB3==0)) // Управление состоянием переднего моста; { // в установленном состоянии энкодера; PORTC|=1<<2; } } goto START; ERROR: PORTA=0b100000; // Подпрограмма ошибки; if (PINB1==0) // при некорректной работе энкодера; { goto ERR_H; } else { goto ERR_L; } ERR_H: PORTC&= ~(1<<2); // Переключение энкодера; if (PIND7==1) // в состояние РК 2H по сигналу токового реле; { goto ERR_H; } else { while (PIND7==0) { PORTC&= ~(1<<0); PORTC|=1<<1; } } ERR_H2: PORTC&= ~(1<<0); // Вывод информации о положении энкодера на индикатор; PORTC&= ~(1<<1); PORTA&= ~(1<<2); PORTA&= ~(1<<4); PORTA|=1<<5; if ((PIND6==0)&&(PINC2==0)) // Вывод информации о состоянии переднего моста; { PORTA&= ~(1<<0); PORTA&= ~(1<<1); } else if ((PIND6==1)&&(PINC2==1)) { PORTA|=1<<0; PORTA|=1<<1; } else { PORTA&= ~(1<<0); PORTA|=1<<1; } if (PINB1==0) { goto ERR_H2; } else { goto ERR_L; } ERR_L: PORTC&= ~(1<<2); // Переключение энкодера; if (PIND7==1) // в состояние РК 4L по сигналу токового реле; { goto ERR_L; } else { while (PIND7==0); { PORTC|=1<<0; PORTC&= ~(1<<1); } } ERR_L2: PORTC&= ~(1<<0); // Вывод информации о положении энкодера на индикатор; PORTC&= ~(1<<1); PORTA|=1<<2; PORTA|=1<<4; PORTA|=1<<5; if ((PIND6==0)&&(PINC2==0)) // Вывод информации о состоянии переднего моста; { PORTA&= ~(1<<0); PORTA&= ~(1<<1); } else if ((PIND6==1)&&(PINC2==1)) { PORTA|=1<<0; PORTA|=1<<1; } else { PORTA&= ~(1<<0); PORTA|=1<<1; } if (PINB1==1) // Управление состоянием переднего моста; { if (PINB0==1) { PORTC|=1<<2; } else { PORTC&= ~(1<<2); } goto ERR_L2; } else { goto ERR_H; } } }
__________________
Надейся на лучшее, расчитывай на худшее Люблю Таврооргию. Такого пох№зма и подъ№балова нигде не встретишь! (c) Lusi |
|
![]() |
![]() |