mega16 UART + AtmelStusio6.1 + Proteus

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Сообщения: 139
Зарегистрирован: Вс авг 23, 2015 08:14:05

Сообщение Denis82 »

Доброго времени суток коты и кошечки :)

пробую написать обмен по аппаратному UART с использованием прерываний и возникла непонятка, далее код

инициализирую UART так

Код: Выделить всё

//hardware UART
#define baudrate 9600L
#define bauddivider (F_CPU/(16*baudrate)-1)
#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)

void HUART_init( void )
{
	//настройка скорости обмена	
	UBRRL = LO(bauddivider);
	UBRRH = HI(bauddivider);

	//8 бит данных, 1 стоп бит, без контроля четности
	UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );
	//разрешить прием, передачу данных и прерывание по приёму байта
	UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ) | (1 << RXCIE );
}
обработчик прерывания по приему байта

Код: Выделить всё

ISR( USART_RXC_vect )
{//доделать проверку на переполнение буфера

	unsigned char rxbyte = UDR;	
	
	if (m_busy == 0)
	{
		command_buff[byte_count] = rxbyte;
		byte_count++;
		if (rxbyte == CR)
		{	
			m_busy = 1;
		} 

	} 
	else
	{
		//как-то уведомить что занят пока
	}	
}
собственно main

Код: Выделить всё

int main(void)
{
	//обнуляем переменные команд 
	m_busy = 0;
	byte_count = 0;
	//
	dbg = 3;
	
	HUART_init();
	sei();

	dbg = 2;

    while(1)
	{
		dbg = 1;
		if(m_busy == 1)
		{
			dbg = 0;
			//тут то-то делаем с полученными данными
			m_busy = 0;
			byte_count = 0;
		}
		
    }	
}
проблема в чём, в том что после инициализации uart-а не происходит возврат в ф-цию main ...

переменная dbg об этом говорит ясно (в протеусе)
т.е. запускаю моделирование, останавливаю и смотрю значения переменных

по идее с dbg должно происходить следующее
dbg = 3 - начало main
dbg = 2 - инициализировали uart и разрешили прерывания
dbg = 1 - вошли в главный while
dbg = 0 - по uart получили CR

а в протеусе я вижу что dbg = 3, т.е. не произошёл возврат в main после инициализации uart ...
при этом если в терминал протеуса отправить строку и <CR> то переменная busy встаёт в 1, собственно как и должно ...


wtf друзья ?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Denis82 писал(а):останавливаю и смотрю значения переменных
А поглядеть в каком месте кода произошла остановка? Переменная dbg как volatile объявлена? А если не вызывать функцию инициализации UART? А если по шагам выполнить программу и проверять значение регистров?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Встал на лапы
Сообщения: 139
Зарегистрирован: Вс авг 23, 2015 08:14:05

Сообщение Denis82 »

происходит не остановка (обработчик прерывания по приему uart прекрасно работает), нет возврата в main после инициалищации uart т.е. код

Код: Выделить всё

int main(void)
{
	//обнуляем переменные команд
	m_busy = 0;
	byte_count = 0;
	//
	dbg = 3;
	
	HUART_init();
	sei();
вополнился и dbg в протеусе = 3
а код что далее

Код: Выделить всё

	dbg = 1;

    while(1)
	{
		dbg = 2;
не выполняется ...

если убрать

Код: Выделить всё

	HUART_init();
	sei();
то dbg = 0 :shock:


переменные глобальные

Код: Выделить всё

//command variable
#define CR 0x0D		//Enter

unsigned char m_busy;
unsigned char command_buff[128];
unsigned char byte_count;
unsigned char dbg;
//end
Добавлено after 12 minutes 39 seconds:
хм, объявил переменные как volatile и заработало
видимо ССЗБ ...

спасибо Z_h_e :beer:
Ответить

Вернуться в «AVR»