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

Где я накосячил? Atmega328


chert2008

Рекомендуемые сообщения

ISR(USART_TX_vect) // прерывание по завершению отправки
{
	cli();
	
	if (bufferIndexOut <= 13)
	{

		UDR0 = inString[bufferIndexOut];
		bufferIndexOut++; // Увеличиваем индекс
	}
	else if (bufferIndexOut > 13) // Вывели весь буффер?
	{

		PORTD &= ~0b00000100; // Поднимаем ножку направления PD2 по прерыванию начала отправки данных
		bufferIndexOut = 0;
		
		UCSR0B &= ~(1 << TXCIE0);
		
		UCSR0B |= (1 << RXCIE0);
		
	}
	sei();
}


ISR(USART_RX_vect) // прерыванию по окончанию приема модуля USART
{

	cli();
	
	inchar = UDR0;
	if (inchar == 0x2A)
		bufferIndexIn = 0;
	if (bufferIndexIn < 14)
	{
		
		
		inString[bufferIndexIn] = inchar;
		bufferIndexIn++;
	}

	
	if (bufferIndexIn > 13) // весь буффер?
	{
		
		bufferIndexIn = 0;	// Сбрасываем индекс массива
		bufferIndexOut = 0; // Сбрасываем индекс массива
		
		UCSR0B &= ~(1 << RXCIE0);
		UCSR0B |= (1 << TXCIE0);
		PORTD |= 0b00000100; // Поднимаем ножку направления PD2 по прерыванию начала отправки данных
		UDR0 = inString[bufferIndexOut];
		
		bufferIndexOut++;
		
	}
	sei();
}
int main()
{
	while(1)
      {
	    out(outs);
      }
}

void out(uint16_t x)
{
	PORTD |= 0xC0;
												// OE1,2 disable
	DDRB = 0b00001111;										// portB out
	DDRC = 0b00011111;										// portC out
	PORTB = (PORTB & 0xF0) | (uint8_t)(x & 0x000F);			// 1nd 4bit write
	PORTC = (PORTC & 0xF0) | (uint8_t)((x & 0x00F0) >> 4);	// 2nd 4bit write
	PORTD |= 0x10;
											// CLK1 OUT ENABLE
	PORTD &= 0xEF;
											// CLK1 OUT DISABLE
	PORTB = (PORTB & 0xF0) | (uint8_t)((x & 0x0F00) >> 8);	// 3nd 4bit write
	PORTC = (PORTC & 0xF0) | (uint8_t)((x & 0xF000) >> 12); // 4nd 4bit write
	PORTD |= 0x20;	
										// CLK2 OUT ENABLE
	PORTD &= 0xDF;
											// CLK2 OUT DISABLE
	DDRB = 0b00000000;										// portB IN
	DDRC = 0b00010000;										// portC IN
}

Контроллер связан с компьютером через rs485. Со связью вроде разобрались все работает. Но как только  подключаем функцию out(outs); все рушится. Ножка направления передачи PD2 начинает жить своей жизнью. И здесь мне совсем уж непонятно что не так и какой участок кода дергает ножку.

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

Попробуйте при изменении порта D запрещать прерывания

Попробую так сделать.

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

Ошибка как минимум тут

Ошибки нет число уже само по себе инвертировано.

Изменено пользователем Falconist
Оверквотинг
Ссылка на комментарий
Поделиться на другие сайты

В 28.06.2022 в 15:52, snn_krs сказал:

Попробуйте при изменении порта D запрещать прерывания

Сделал так и потестил. Ошибок больше небыло.

Раньше было так.. Когда передача заканчивалась ножка опускалась и сразу же вскакивала обратно (синий канал). Сейчас такого не произошло за час ни разу. Отсюда вопрос как это вообще получается?

 

photo_2022-06-29_20-08-50.jpg

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

Для изменения содержимого порта компилятор может использовать три команды

1. Чтение порта во временный регистр

2. Изменение значения во временном регистре

3. Сохранение временного регистра в порт.

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

Команды cli() и sei() в прерывании не нужны, они прерывание запрещается и разрешается аппаратно. При приеме по 485 используют таймаут. Если нет приема дольше нескольких мСек ( обычо длительность передачи 3.5 символов ), значит прием закончен, или ошибка. Если этого не сделать обмен может зависнуть.

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

2 часа назад, snn_krs сказал:

Если между этими командами произойдет прерывание

Огромнейшее спасибо за советы. Буду тестить дальше. За две недели мучений это большой прорыв для меня.

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...