WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Подскажите почему не видит в коде глобальную переменную Danue в среде WinAVR. Что не так делаю. Вот снимок. вот сам код.
Спойлер/*
* USARTATMEGA8.c
*

*/


#include <avr/io.h>
#define F_CPU 4000000
#define BAUD 9600L // Скорость обмена данными
#define UBRRL_value (F_CPU/(BAUD*16))-1
unsigned char Danue=0;

int main(void)

{
/*Настраиваем соответствующий порт передачи на выход*/
PORTD|=(1<<PD1);
/*Устанавливаем бит разрешение передачи*/
UCSRB|=(1<<TXEN);
//Переходим в регистр UCSRC
UCSRC|=(1<<URSEL);
//Размер передоваемого слова выставляем на 8 бит.*/
UCSRC|=(1<<UCSZ1)|(1<<UCSZ0);
//Выбираем режим работы ассинхронный
UCSRC&=~(1<<UMSEL);
//Проверка на четность выставляем в ноль
UCSRC&=~(1<<UPM1)&(1<<UPM0);
//Количество стоп битов также ставим 1
UCSRC&=~(1<<USBS);
//Устанавливают скорость передачи в бодах
UCSRC&=~(1<<URSEL);//Переходим в регистр UBRR;
UBRRL=UBRRL_value;//Младший бит
UBRRH=0x00;//Старший бит

/*Передаем наши данные через UDR всего один раз. */
//UDR=0x45;
while(1)
{

//Проверяем флаг UDRE — флаг опустошения регистра передатчика,
//устанавливается в 1 при пустом буфере передатчика — UDR значит можно передовать;
if ((Danue==0)&&(UCSRA|(1<<UDRE)))
{ //Отправляем только один раз
Danue++;

UDR=0x45;

}
if ((Danue==1)&&(UCSRA|(1<<UDRE)))
{ //Отправляем только один раз
UDR=0x53;
Danue++;
}
}
}
Вложения
8888.png
(126.03 КБ) 469 скачиваний
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

Компилятор при оптимизации увидел, что она фактически не используется, поэтому её выбросил и сгенерировал код наподобие:

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

if (UCSRA | (1<<UDRE))
    UDR=0x45;
if (UCSRA | (1<<UDRE))
    UDR=0x53;
while(1) {}
Думаю, дело именно в этом.
Реклама
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Подскажите а как мне ее задействовать Danue в условии, так как в отношении этой переменной должно срабатывать условие.

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

 if ((Danue==0)&&(UCSRA|(1<<UDRE)))
        { //Отправляем только один раз
	  
	   Danue=1; 
	  
			UDR=0x45;
			
        }
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

WiseLord писал(а):Думаю, дело именно в этом
либо сделал ее регистровой (я не вникал в логику использования переменной).

Добавлено after 1 minute 38 seconds:
strengerst писал(а):а как мне ее задействовать Danue в условии
а это на самом деле надо? судя по комментарию вам нужно выдать данные в USART один раз - ну так и выдавайте ВНЕ цикла. будет один раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Мне для понимания для себя что бы знать. На коменты не смотрите. Как сделать ее не регистровой.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

strengerst писал(а):Как сделать ее не регистровой
сделайте ее static
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Не помогло. Делал так

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

static unsigned char  Danue=0;
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Ну я хочу создать условие, в котором переменная принимает те или иные значения и в отношении нее сделать действия, как мне это провернуть.
Спасибо volatile помогло. Пойду по кривой дорожке.
Последний раз редактировалось strengerst Ср дек 14, 2016 13:52:50, всего редактировалось 1 раз.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

В какой-то момент компилятор посчитает нецелесообразным её выбрасывать, и станет всё нормально. Но пока, в таком виде, она не нужна. Ну, или сделайте-таки volatile, на время отладки.
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Спасибо volatile помогло.
Подскажите сколько должна быть задержка между оправками данных по USART.
Без задержки я так понимаю отправлять друг за другом данные нельзя пока буфер не очистится.
Если я делаю с задержкой то в терминале протеуса все корректно отображается, а если без нее то только первое условие.
А второе нет.

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

if ((UCSRA||(1<<UDRE))&&(Danue==0))
{ //Отправляем только один раз
UDR=0x45;
Danue++; 
}
_delay_ms(1000);
if ((UCSRA||(1<<UDRE))&&(Danue==1))
{ //Отправляем только один раз
UDR=0x53;
Danue++;
}
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: WinAvr в вопросах и ответах

Сообщение COKPOWEHEU »

В даташите приведены функции передачи байта на UART, перед отправкой ожидающие опустошения буфера. Проще говоря, ждут, пока не поднимется флаг UDRE
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Спасибо это я понял. но не понятно почему не работает условие без задержки delay. Ну вот код ниже в нем в условии указано что только при опустошении буфера UDRE (то есть когда он в 1 то буфер пуст и данные можно передавать), передать данные UDR=0x45;
и прибавить 1 к переменной Danue. Условие выполняется а вот второе точно такое же условие уже не выполняется. Почему? А вот если поставить между условиями задержку в 1 секунду. Все работает.
Рабочий код
Спойлер

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

if ((UCSRA||(1<<UDRE))&&(Danue==0))
{ //Отправляем только один раз
UDR=0x45;
Danue++; 
}
_delay_ms(1000);
if ((UCSRA||(1<<UDRE))&&(Danue==1))
{ //Отправляем только один раз
UDR=0x53;
Danue++;
}

Не рабочий код (Второе условие не передается)
Спойлер

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

if ((UCSRA||(1<<UDRE))&&(Danue==0))
{ //Отправляем только один раз
UDR=0x45;
Danue++; 
}
if ((UCSRA||(1<<UDRE))&&(Danue==1))
{ //Отправляем только один раз
UDR=0x53;
Danue++;
}
Весь этот код находиться в цикле while(1) функции int main(void);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

strengerst писал(а):но не понятно почему не работает условие без задержки delay
потому что вы ошибаетесь в записи логических выражений.
strengerst писал(а):UCSRA||(1<<UDRE)
вот это выражение истинно ВСЕГДА. изучите битовые манипуляции над переменными, например, вот по этой моей заметке: http://arv.radioliga.com/content/view/191/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Самое лучшее объяснение на примере.
Как проверить установлен ли бит в переменной? Нужно обнулить все биты, кроме проверочного, а потом сравнить полученное значение с нулем

if ((tmp & (1<<2)) != 0 ){
// блок будет выполняться, только если установлен
// второй бит переменной tmp
}

if ((tmp & (1<<2)) == 0 ){
// блок будет выполняться, только если не установлен
// второй бит переменной tmp
}


if ((UCSRA & (1<<UDRE)) != 0 ){
// блок будет выполняться, только если установлен
// UDRE бит переменной tmp
}

if ((UCSRA & (1<<UDRE)) == 0 ){
// блок будет выполняться, только если не установлен
// UDRE бит переменной UDRE=1
}

Или так:

if (~(UCSRA | ~(1<<UDRE))== 0 ){
// блок будет выполняться, только если установлен
// UDRE бит переменной UDRE=1

}
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Помогите найти ошибку в приемнике. Почему не выполняется условие if(Zeto==0x56) {PORTD|=(1<<PD5);Zeto++;}
Я понимаю что из-за того что Zeto не равно 0x56. Но почему? Мы ведь считываем данные после отправки с UDR а там точно 0x56?
Спойлер

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

/*
* USARTATMEGA8.c
*

*/ 


#include <avr/io.h>
#define F_CPU 4000000
#define BAUD 9600L // Скорость обмена данными
#define UBRRL_value (F_CPU/(BAUD*16))-1 //volatile unsigned char Danue=0;
 unsigned char Danue=0;
 unsigned char Zeto=0;
int main(void)

{
PORTD|=(1<<PD4);
/*Настраиваем соответствующий порт передачи на вход*/
PORTD&=~(1<<PD0);
/*Устанавливаем бит разрешение приема*/
UCSRB|=(1<<RXEN);
//Переходим в регистр UCSRC
UCSRC|=(1<<URSEL);
//Размер принимаемого слова выставляем на 8 бит.*/
UCSRC|=(1<<UCSZ1)|(1<<UCSZ0);
//Выбираем режим работы ассинхронный
UCSRC&=~(1<<UMSEL);
//Проверка на четность выставляем в ноль
UCSRC&=~(1<<UPM1)&(1<<UPM0);
//Количество стоп битов также ставим 1
UCSRC&=~(1<<USBS);
//Устанавливают скорость передачи в бодах
UCSRC&=~(1<<URSEL);//Переходим в регистр UBRR;
UBRRL=UBRRL_value;//Младший бит
UBRRH=0x00;//Старший бит

/*Принимаем наши данные через RXD всего один раз. */	
while(1)
{

//Проверяем флаг RXC флаг завершения приема, устанавливается в 1 при наличие непрочитанных данных в буфере приемник — UDR; — флаг опустошения регистра передатчика, 

   //(UCSRA & (1<<UDRE)) - производит чтение бита.
   //UCSRA ^(1<<UDRE) - инверсия.
if ((UCSRA & (1<<RXC))!= 0 ){ 
if (Danue==0)
{ //Отправляем только один раз
 Zeto=UDR;
Danue++;
}}
   if(Zeto==0x56)
   {PORTD|=(1<<PD5);
      Zeto++;
      }
   
   
}
}
Вложения
яяяя.png
(65.45 КБ) 302 скачивания
яяя.png
(30.8 КБ) 449 скачиваний
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: WinAvr в вопросах и ответах

Сообщение Z_h_e »

Уберите условие if (Danue==0), принимайте данные всегда и весь UDR кидайте в PORTB, так будет нагляднее понять что Вы приняли на самом деле.

Самая распространенная ошибка работы с УАРТ, это не правильная настройка скорости. В протеусе то выставили частоту МК? А может Вы не с теми параметрами отправляете данные?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

Re: WinAvr в вопросах и ответах

Сообщение strengerst »

Да в роде в настройках все правильно поставил. Вот снимок. Подправил код
Спойлер

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

if ((UCSRA & (1<<RXC))!= 0 ){ 

 Zeto=UDR;

}
   if(Zeto==0x56)
   {PORTD|=(1<<PD5);
      Zeto++;
      }
   
Вложения
pppp.png
(104.25 КБ) 471 скачивание
cccc.png
(134.55 КБ) 450 скачиваний
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: WinAvr в вопросах и ответах

Сообщение Dimon456 »

Доброго времени суток.
Столкнулся с проблемой в winavr.
Вот, к примеру, простенькая программа:
Спойлер

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

#include <avr/io.h>
#include <avr/interrupt.h>  /* для sei() */
#include <util/delay.h>     /* для _delay_ms() */


#define KN_PORT 	PORTD 	// порт
#define KN_DDR 	DDRD
#define KN_PIN 	PIND	
#define KN	 	0		// пин кнопка 


unsigned int last_millis=0; 
char   i=0;


// Timer 0 overflow interrupt service routine
ISR( TIMER0_OVF_vect )
{
// Reinitialize Timer 0 value
TCNT0=0xB2;
// Place your code here
last_millis++;

}



char skan_klav (char Pin_Set, volatile char *PORT_set) {

	last_millis = 0; // 10 милли секунд
	
   if ((*PORT_set & (1<<Pin_Set)) == 0) {
    _delay_ms (50);
	 
     do { } while ((*PORT_set & (1<<Pin_Set)) == 0); // проверить отжата ли кнопка
	_delay_ms(30);
	
	
	  if (last_millis > 25) {
		return 1;
		}
	  
	  if (last_millis > 200) {
		return 2;
		}
	return 100;
	}

   return 0;	
};

int main(void)
{

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0 |= (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0xB2;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK |= (1<<TOIE0);


	KN_DDR |= (0<<KN);  
	KN_PORT |= (1<<KN);
	
	sei();

for(;;){  	

	i = skan_klav (KN, &KN_PIN);
	
	_delay_ms(500);
	
	i = 0;
	
	}

};
Интересует вот этот кусок кода:
Спойлер

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

char skan_klav (char Pin_Set, volatile char *PORT_set) {

	last_millis = 0; // 10 милли секунд
	
   if ((*PORT_set & (1<<Pin_Set)) == 0) {
    _delay_ms (50);
	 
     do { } while ((*PORT_set & (1<<Pin_Set)) == 0); // проверить отжата ли кнопка
	_delay_ms(30);
	
	
	  if (last_millis > 25) {
		return 1;
		}
	  
	  if (last_millis > 200) {
		return 2;
		}
	return 100;
	}

   return 0;	
};
Этот кусок кода не выполняется по заложенному в него алгоритму.
Тем более дизассемблер показывает следующее
СпойлерИзображение
По чему часть кода не обрабатывается?
В архиве проект, протеус, и есе файлы.
Вложения
Primer.rar
(23.57 КБ) 262 скачивания
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение WiseLord »

Не сильно вникая в суть проблемы, спрошу: почему глобальная переменная, last_millis, которая изменяется в прерывании, не объявлена как volatile?
Ответить

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