Перейти к содержанию
    

Микроконтроллеры для начинающих

Функция eeprom_update_word() сама этого не делает?

Если не делает, то её фактически нет, разве что какому-то программисту от микроконтроллера понадобится только его EEPROM и ничего более.

 

На время подачи сигнала разблокирования записи в EEPROM прерывания требуется запретить, чтобы выполнить требования по разблокирующей последовательности (у микроконтроллеров PIC, например, это последовательная запись 55 и AA в регистр разблокировки), но далее, на саму запущенную процедуру записи, любая работа программы никакого влияния не оказывает, в т.ч. и её работа в прерываниях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Снова здравствуйте.

 

AVR.

 

Есть 2 самописных функции.

Эти функции используют разные глобальные переменные, вообще никак не пересекаются между собой. Вызываются в оновном цикле, никак не завязаны на прерывания. В одной из них работа с SPI, в другой с АЦП.

Но при этом функция с АЦП влияет на работу функции с SPI. Нашёл 2 строчки из-за которых это происходит, но там просто математические вычисления, никакого отношения не имеющие к другой функции.

 

При включении любого уровня оптимизации это проявляется. На уровне -О0 всё работает нормально.

 

Подскажите в чём может быть дело?

Изменено пользователем lyric

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

код нужен

 

#define F_CPU 8000000
#include <avr/io.h>
#include <stdlib.h>
#include <math.h>
#include <avr/interrupt.h>



//--------------------------------------------------------------------------------------------------------------глобальные переменные-----------------------------------------------------------------
volatile uint8_t R1=0, R2=0, R3=0, R4=0, R5=0, R6=0, R7=0, R8=0; //Переменные значений разрядов индикатора
volatile int16_t ADC_AI_1, ADC_AI_2; //Текущие значения АЦП без фильтрации
volatile float ADC_AI_1_ff, ADC_AI_2_ff, AI_1, AI_2, AI_1_fv, AI_2_fv;//Текущие значения АЦП после фильтрации, аппроксимированных значений аналоговых входов до коррекции и после
volatile int32_t accu1=0, accu2=0; //переменные для оверсемплинга АЦП
volatile uint8_t accu_count1=0, accu_count2=0; //переменные для оверсемплинга АЦП
volatile int16_t koeff_AI1=1;
volatile int16_t koeff_AI2=1;
volatile uint8_t DI_portD_Mask; 
volatile uint8_t DI_portA_Mask_no_opros; 
volatile uint8_t DI_portA_Mask; 

uint8_t tip_AI1=1;
uint16_t calibr_ADC_min_AI1; //  Калибровочное минимальное значение АЦП аналогового входа AI1
uint16_t calibr_ADC_max_AI1; // Калибровочное максимальное значение АЦП аналогового входа AI1
int16_t NPI_AI1; // Нижний предел измерения параметра с аналогового входа AI1
int16_t VPI_AI1; // Верхний предел измерения параметра с аналогового входа AI1
uint16_t koef_A_AI1; // Коэффициент коррекции А для параметра с аналогового входа AI1
int16_t koef_B_AI1; // Коэффициент коррекции B для параметра с аналогового входа AI1
uint8_t koef_filtra_AI1; // Коэффициент фильтрации параметра с AI1

uint8_t tip_AI2=2;
uint16_t calibr_ADC_min_AI2; //  Калибровочное минимальное значение АЦП аналогового входа AI2
uint16_t calibr_ADC_max_AI2; // Калибровочное максимальное значение АЦП аналогового входа AI2
int16_t NPI_AI2; //  Нижний предел измерения параметра с аналогового входа AI2
int16_t VPI_AI2; //  Верхний предел измерения параметра с аналогового входа AI2
uint16_t koef_A_AI2; //  Коэффициент коррекции А для параметра с аналогового входа AI2
int16_t koef_B_AI2; //  Коэффициент коррекции B для параметра с аналогового входа AI2
uint8_t koef_filtra_AI2; //  Коэффициент фильтрации параметра с AI2

//------------------------------------------------------------------------------------------------

void preset()//функция установки портов
{


//инициализация порта В
DDRB = 0b10110000;  //конфигурация: 0 - вход. 1 - выход
PORTB = 0b01001111; //1 - включение подтягивающих резисторов для входов. 0 - задание выходам порта начальных значений ("отключено" - высокий уровень, "включено" - низкий уровень).
//инициализация порта C
DDRC = 0b11111111;  //конфигурация: 0 - вход. 1 - выход
PORTC = 0b01111111; //1 - включение подтягивающих резисторов для входов. 0 - задание выходам порта начальных значений ("отключено" - высокий уровень, "включено" - низкий уровень).
//инициализация порта D
//конфигурация: 0 - вход:
DDRD &=~(1<<PD7); //Настраиваем ножку PD7 в режим входа
DDRD &=~(1<<PD6); //Настраиваем ножку PD6 в режим входа
DDRD &=~(1<<PD5); //Настраиваем ножку PD5 в режим входа
DDRD &=~(1<<PD4); //Настраиваем ножку PD4 в режим входа
DDRD &=~(1<<PD3); //Настраиваем ножку PD3 в режим входа
DDRD |=(1<<PD2); //Настраиваем ножку PD3 в режим вЫхода
//1 - включение подтягивающих резисторов для входов порта D:
PORTD |= (1<<PD7); 
PORTD |= (1<<PD6); 
PORTD |= (1<<PD5); 
PORTD |= (1<<PD4); 
PORTD |= (1<<PD3); 
//1 - задание выходу №2 порта D начального значения "отключено" - высокий уровень:
PORTD |= (1<<PD2);
}

void symboll(uint8_t symm) //функция отображения символов на индикаторах
{
switch(symm)
{
	case 1: SPDR = 0b10111011; break;	//цифра 1
	case 2: SPDR = 0b10001100; break;	//цифра 2
	case 3: SPDR = 0b10101000; break;	//цифра 3
	case 4: SPDR = 0b00111001; break;	//цифра 4
	case 5: SPDR = 0b01101000; break;	//цифра 5
	case 6: SPDR = 0b01001000; break;	//цифра 6
	case 7: SPDR = 0b10111010; break;	//цифра 7
	case 8: SPDR = 0b00001000; break;	//цифра 8
	case 9: SPDR = 0b00101000; break;	//цифра 9
	case 0: SPDR = 0b00001010; break;	//цифра 0

	case 11: SPDR = 0b10110011; break;  //цифра 1 с точкой
	case 12: SPDR = 0b10000100; break;  //цифра 2 с точкой
	case 13: SPDR = 0b10100000; break;	//цифра 3 с точкой
	case 14: SPDR = 0b00110001; break;	//цифра 4 с точкой
	case 15: SPDR = 0b01100000; break;	//цифра 5 с точкой
	case 16: SPDR = 0b01000000; break;	//цифра 6 с точкой
	case 17: SPDR = 0b10110010; break;	//цифра 7 с точкой
	case 18: SPDR = 0b00000000; break;	//цифра 8 с точкой
	case 19: SPDR = 0b00100000; break;	//цифра 9 с точкой
	case 10: SPDR = 0b00000010; break;	//цифра 0 с точкой		

	case 20: SPDR = 0b00011000; break;	//буква А
	case 21: SPDR = 0b01001001; break;	//буква B 
	case 22: SPDR = 0b01001110; break;	//буква C
	case 23: SPDR = 0b10001001; break;	//буква D
	case 24: SPDR = 0b01001100; break;	//буква E
	case 25: SPDR = 0b01001010; break;	//буква G
	case 26: SPDR = 0b11001110; break;	//буква I
	case 27: SPDR = 0b00010001; break;	//буква K
	case 28: SPDR = 0b01001111; break;	//буква L
	case 29: SPDR = 0b11011001; break;	//буква N
	case 30: SPDR = 0b11001001; break;	//буква O
	case 31: SPDR = 0b11000001; break;	//буква O с точкой
	case 32: SPDR = 0b00011100; break;	//буква P
	case 33: SPDR = 0b11101111; break;	//нижнее подчёркивание
	case 34: SPDR = 0b11111101; break;	//минус
	case 35: SPDR = 0b11111111; break;	//ничего
	case 36: SPDR = 0b10111110; break;	//стрелка вверх
	case 37: SPDR = 0b11001111; break;	//стрелка вниз
	case 38: SPDR = 0b11011101; break;	//буква R
	case 39: SPDR = 0b11010101; break;	//буква R с точкой
	case 40: SPDR = 0b01101000; break;	//буква S 
	case 41: SPDR = 0b01100000; break;	//буква S с точкой 
	case 42: SPDR = 0b01001101; break;	//буква T
	case 43: SPDR = 0b11001011; break;	//буква U
	case 44: SPDR = 0b00001011; break;	//буква V
	case 45: SPDR = 0b11110001; break;	//буква Z
	default: SPDR = 0b11111111;      	//ничего
}
}

void SPI_init()
{
SPCR = ((1<<SPE)|(1<<MSTR));
}

void ADC_init()
{
ADCSRA |= ((1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)); //Разрешение использования АЦП и делитель 64 (частота опроса 125кГц)
ADMUX=0; 
}

void ADC_convert(void) //функция чтения каналов АЦП. Первые 2 канала - это аналогоые входы. Остальные 6 каналов - используются как дискретные входы. 
{	
uint16_t kod_acp=0;
uint8_t lock_0=0; //чтобы за один вызов функции выполнялось только одно преобразование АЦП, а не 0 и 7 в один раз
static float prom_out1=0, prom_out2=0;
unsigned char savee = SREG;


if (ADMUX==7)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00100000;}	else	{DI_portA_Mask_no_opros &= 0b11011111;}
	lock_0=1; 
	SREG= savee;
	ADMUX=0;
}

if (ADMUX==6)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00010000;}	else	{DI_portA_Mask_no_opros &= 0b11101111;}
	SREG= savee;
	ADMUX=7;
}

if (ADMUX==5)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00001000;}	else	{DI_portA_Mask_no_opros &= 0b11110111;}
	SREG= savee;
	ADMUX=6;
}

if (ADMUX==4)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00000100;}	else	{DI_portA_Mask_no_opros &= 0b11111011;}
	SREG= savee;
	ADMUX=5;
}

if (ADMUX==3)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00000010;}	else	{DI_portA_Mask_no_opros &= 0b11111101;}
	SREG= savee;
	ADMUX=4;
}

if (ADMUX==2)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();
	kod_acp = (unsigned int) ADC;
	if (kod_acp<300)	{DI_portA_Mask_no_opros |= 0b00000001;}	else	{DI_portA_Mask_no_opros &= 0b11111110;}
	SREG= savee;
	ADMUX=3;
}

if (ADMUX==1)
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();	
	accu2 += (int32_t) ADC;//Оверсемплинг AI2. Было 10 бит, стало 13
	accu_count2++;
	if (accu_count2>=64)
	{
		ADC_AI_2=(int16_t)(accu2/8); accu_count2=0; accu2=0;//фильтрация AI2
		ADC_AI_2_ff=prom_out2+(ADC_AI_2-prom_out2)/(float)koef_filtra_AI2; //экспоненциальный фильтр
		prom_out2=ADC_AI_2_ff;

		if (tip_AI2==1)
		{
			AI_2= ((float)((ADC_AI_2_ff-calibr_ADC_min_AI2)/(calibr_ADC_max_AI2-calibr_ADC_min_AI2)) * (((float)(VPI_AI2-NPI_AI2))/koeff_AI2)+ ((float)(NPI_AI2/koeff_AI2)));//Аппроксимация AI2
			AI_2_fv=AI_2*(((float)koef_A_AI2)/1000)+(float)koef_B_AI2/koeff_AI2; //Коррекция AI2
		} 
		else {AI_2=0;AI_2_fv=0;}
	}

	SREG= savee;
	ADMUX=2;
}

if ((ADMUX==0) && (lock_0==0))
{
	ADCSRA |= (1<<ADSC); //Начинаем преобразование
	while((ADCSRA & (1<<ADSC))) {}; //проверка закончилось ли аналого-цифровое преобразование
		savee =SREG;
		cli ();		
	accu1 += (int32_t) ADC; //Оверсемплинг AI1. Было 10 бит, стало 13
	accu_count1++;
	if (accu_count1>=64)		
	{
	ADC_AI_1=(int16_t)(accu1/8); accu_count1=0; accu1=0;//фильтрация AI1
	ADC_AI_1_ff=prom_out1+(ADC_AI_1-prom_out1)/(float)koef_filtra_AI1; //экспоненциальный фильтр
	prom_out1=ADC_AI_1_ff;

	if ((tip_AI1>0) && (tip_AI1<4))
		{		
AI_1= ((float)((ADC_AI_1_ff-calibr_ADC_min_AI1)/(calibr_ADC_max_AI1-calibr_ADC_min_AI1)) * (((float)(VPI_AI1-NPI_AI1))/koeff_AI1)+ ((float)(NPI_AI1/koeff_AI1)));//Аппроксимация AI1
	AI_1_fv=AI_1*(((float)koef_A_AI1)/1000)+(float)koef_B_AI1/koeff_AI1;//Коррекция AI1
		} 
		else 
		{AI_1=0;AI_1_fv=0;}
	}

	SREG= savee;
	ADMUX=1;
}
lock_0=0;

}	

void indi()
{
static char n_count=1; //Переменная для перебора посылаемых байтов-символов на разряды индикатора

if (n_count==8)
{symboll(R8);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b01111111;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==7)
{ symboll(R7);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b10111111;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==6)
{symboll(R6);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11011111;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==5)
{symboll(R5);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11101111;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==4)
{symboll(R4);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11110111;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==3)
{symboll(R3);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11111011;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==2)
{symboll(R2);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11111101;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

if (n_count==1)
{symboll(R1);
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	SPDR =0b11111110;//выбор индикатора
	while (!(SPSR & (1<<SPIF))) {}; //ожидание, пока данные передадутся
	//отрицательный фронт для записи в STORAGE REGISTER
	PORTB |=  (1<<4); // высокий уровень
	PORTB &=  ~(1<<4); // низкий уровень
}

++n_count;
if (n_count>8) {n_count=1;}

}

int main(void)
{
preset();
SPI_init();
ADC_init();
sei();
while (1)
{

ADC_convert();	
R1=7;
R2=7;		
R3=7;
R4=7;
R5=7;
R6=7;
R7=7;
R8=7;
indi();
}//КОНЕЦ ОСНОВНОГО ЦИКЛА while
}//КОНЕЦ ОСНОВНОЙ ФУНКЦИИ main

 

Функция ADC_convert() влияет на работу функции indi(). ADC_convert() - опрос 8 каналов АЦП, indi() - индикация на 8-разрядный семисегментный экран по SPI. Проблема - последний разряд (R8) мерцает, в то время как остальные разряды горят нормально.

Это не вся программа, только те её части, с которыми проблема. Код компилится (Atmel Studio 7) и проблема в нём проявляется. 2 строчки, выделенные жирным цветом - если их закомментировать, то мерцание пропадает. Какое отношение они имеют к индикации - непонятно, но влияют. Такие же две строчки есть и чуть выше в этой же функции,

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

Изменено пользователем lyric

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

calibr_ADC_max_AI2 - calibr_ADC_min_AI2 у вас неинициализированы, а в этих строках вы делите на их разность, оная будет равна 0, так они в стартапе обе обнуляются.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

calibr_ADC_max_AI2 - calibr_ADC_min_AI2 у вас неинициализированы, а в этих строках вы делите на их разность, оная будет равна 0, так они в стартапе обе обнуляются.

 

Все переменные инициализировал, ничего не изменилось.

Ну и прошу прощения, - ошибся:

Присмотрелся лучше к экрану - мерцания прекращаются только если ADC_convert вообще не вызывать.

Что-то не так с этой функцией (подскажите что?). И почему она портит только один разряд а не все 8 - не пойму.

 

Когда ADMUX=0 и ADMUX=1 функция ADC_convert выполняется дольше, потому что больше расчётов в ней происходит.

Поэтому функция indi() в эти моменты дольше НЕ выполняется.

И, видимо, эти моменты совпадают с моментами, когда должен включаться индикатор (R8).

 

Но между ADMUX=0 и ADMUX=1 функция indi() всё равно должна успеть выполниться 1 раз, и получается что мерцать должны 2 индикатора, а не один.

Так и есть? или это бред?

 

:help: :help: :help:

Изменено пользователем lyric

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день. Коллеги, просветите меня пожалуйста, в каком порядке правильно разрешать внешние прерывания в С на Atmel Studio 7, микроконтроллер ATMega2560, хотя эта проблема и на других микроконтроллерах AVR. Я поступаю следующим образом. Предположим что программа работает в цикле измерений. Запуск измерения производится по внешнему прерыванию по входу INT4. Я разрешаю прерывание на INT4, затем sei(). По окончании измерения даю cli() и запрещаю прерывание по INT4. В результате первое прерывание происходит произвольно, без каких либо событий на входе INT4, т.е. одно прерывание лишнее. В чём может быть проблема? Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, Smoky said:

В результате первое прерывание происходит произвольно, без каких либо событий на входе INT4,

Перед разрешением прерываний прочтите состояние INT4 (или что там у ATmega), что бы сбросить pending прерывание.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, xvr сказал:

Перед разрешением прерываний прочтите состояние INT4 (или что там у ATmega), что бы сбросить pending прерывание.

 

Спасибо, вы правы. Весьма удивлён тем что флаги прерываний устанавливаются даже при запрете прерываний...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, Smoky said:

Спасибо, вы правы. Весьма удивлён тем что флаги прерываний устанавливаются даже при запрете прерываний...

а как же иначе? запретил прерывание для каких-то нужд и потерял его, если флаг не будет выставляться...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запрет прерываний - это запрет обработки. Флаг прерывания - результат события. Так что все совершенно логично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

34 minutes ago, rx3apf said:

Запрет прерываний - это запрет обработки. Флаг прерывания - результат события. Так что все совершенно логично.

События и прерывания однако разные вещи в общем случае.
В некоторых архитектурах они эквивалентны, в других обрабатываются разными движками.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, rx3apf сказал:

Запрет прерываний - это запрет обработки. Флаг прерывания - результат события. Так что все совершенно логично.

Занимаюсь этим уже не первый год а столкнулся с этим впервые. Обычно использовал прерывания для одного события и всё "сходило с рук", а тут пришлось фиксировать несколько разделённых по времени событий по одному входу и тут же "влип". Спасибо всем за разъяснения, очень помогли.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно ли я понимаю из дискуссии, что если у меня настроено прерывание по фронту входного сигнала, и этот фронт случился во время запрета прерывания, то сразу по разрешению этого прерывания сразу произойдет прерывание? Т.е. событие я не потеряю, просто реакция на него будет позже.,?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...