Подскажите почему не видит в коде глобальную переменную 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++; } } }
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
если не помогло, значит, она и в самом деле лишняя по логике работы. можете, конечно, сделать ее volatile, но это тупиковый путь - подгонять работу компилятора под неверную логику программы
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Ну я хочу создать условие, в котором переменная принимает те или иные значения и в отношении нее сделать действия, как мне это провернуть. Спасибо volatile помогло. Пойду по кривой дорожке.
Последний раз редактировалось strengerst Ср дек 14, 2016 13:52:50, всего редактировалось 1 раз.
В какой-то момент компилятор посчитает нецелесообразным её выбрасывать, и станет всё нормально. Но пока, в таком виде, она не нужна. Ну, или сделайте-таки volatile, на время отладки.
Спасибо volatile помогло. Подскажите сколько должна быть задержка между оправками данных по USART. Без задержки я так понимаю отправлять друг за другом данные нельзя пока буфер не очистится. Если я делаю с задержкой то в терминале протеуса все корректно отображается, а если без нее то только первое условие. А второе нет.
Код:
if ((UCSRA||(1<<UDRE))&&(Danue==0)) { //Отправляем только один раз UDR=0x45; Danue++; } _delay_ms(1000); if ((UCSRA||(1<<UDRE))&&(Danue==1)) { //Отправляем только один раз UDR=0x53; Danue++; }
Спасибо это я понял. но не понятно почему не работает условие без задержки 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);
Самое лучшее объяснение на примере. Как проверить установлен ли бит в переменной? Нужно обнулить все биты, кроме проверочного, а потом сравнить полученное значение с нулем
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
Помогите найти ошибку в приемнике. Почему не выполняется условие 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++; }
Заголовок сообщения: Re: WinAvr в вопросах и ответах
Добавлено: Пт дек 16, 2016 11:37:47
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Уберите условие if (Danue==0), принимайте данные всегда и весь UDR кидайте в PORTB, так будет нагляднее понять что Вы приняли на самом деле.
Самая распространенная ошибка работы с УАРТ, это не правильная настройка скорости. В протеусе то выставили частоту МК? А может Вы не с теми параметрами отправляете данные?
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Доброго времени суток. Столкнулся с проблемой в 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++;
Этот кусок кода не выполняется по заложенному в него алгоритму. Тем более дизассемблер показывает следующее СпойлерПо чему часть кода не обрабатывается? В архиве проект, протеус, и есе файлы.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 45
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения