roboforum.ru

Технический форум по робототехнике.

От WinAVR текут мозги!

От WinAVR текут мозги!

redcat » 27 янв 2009, 23:44

Уже неделю борюсь с WinAVR, много проблем разрешил, но эта -
Не изменяется ГЛОБАЛЬНАЯ ПЕРЕМЕННАЯ в обработчике прерывания!!!!!!
Компилятор WinAVR. МС - Attiny2313

Код: Выделить всёРазвернуть

#define ...................

int a=0;
DDRD = 0b00010000; // PD4 - выход (на этом порту светодиод)
PORTD = 0b00000000;// на всякий случай гасим свет


SIGNAL(USART0_RXC){ // прерывание по приёму символа
// ПРЕРЫВАНИЕ СРАБАТЫВАЕТ !!!

PORTD = 0b00010000;// светодиод зажигается и остаётся гореть
a++; // a=a+1 - увеличивает "а" на один

}


int main(void){

while(1){
; //По идее каждый раз при прерывании USART0_RXC "а" должно увеличиваться!?
; // но "а" остаётся = 0
; //цикл продолжается!

        }

}



я с ума сойду скоро! :P Помогите!

Re: От WinAVR текут мозги!

Сергей » 27 янв 2009, 23:46

Выложи исходник целиком! Кажеца код кривой какойто, помогу

Re: От WinAVR текут мозги!

RoboTok » 28 янв 2009, 00:02

Возможно, переменная a определена не правильно.

Re: От WinAVR текут мозги!

=DeaD= » 28 янв 2009, 00:05

Может просто потом где-то написано "if(a=0)..." ? :) Как узнаёте, что а=0?

Re: От WinAVR текут мозги!

redcat » 28 янв 2009, 00:20

Думаю в комментариях всё понятно обьяснил.

Код: Выделить всёРазвернуть
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h> 
#include <avr/iotn2313.h>


/*********** cpu clock speed if not defined   ****************************************/
#ifndef F_CPU
#define F_CPU 4000000//Hz
#endif

/*********** set desired baud rate *************************************************/
#define BAUDRATE 19200 //bod
//calculate UBRR value
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1) //UBRVAL - Индекс скорости

/*********** СВЕТОДИОДЫ ВКЛ/ВЫКЛ ***************************************************/
#define LED_INIT      DDRD = 0x38; //0b00111000
#define LED_GREEN_ON   PORTD |=_BV(PD4);
#define LED_GREEN_OFF   PORTD &=~_BV(PD4);
#define LED_YELLOW_ON   PORTD |=_BV(PD3);
#define LED_YELLOW_OFF   PORTD &=~_BV(PD3);
#define LED_RED_ON      PORTD |=_BV(PD5);       
#define LED_RED_OFF      PORTD &=~_BV(PD5);
#define LED_ALL_ON      PORTD |=_BV(PD3);PORTD |=_BV(PD4);PORTD |=_BV(PD5);
#define LED_ALL_OFF      PORTD &=~_BV(PD3);PORTD &=~_BV(PD4);PORTD &=~_BV(PD5);

/*********** Глобальные переменные *************************************************/
char usart_enabled; //состояние приёмо-передатчика USART
char received_symbol;
int chr_cntr = 0; //Счётчик кол-ва прерываний


/*********** ФУНКЦИЯ ВКЛЮЧЕНИЯ ПРИЁМНИКА *******************************************/
void USART_Enable(void){
   /* Set baud rate */
   UBRRH = (unsigned char)(UBRRVAL>>8);
   UBRRL = (unsigned char)UBRRVAL;
   /* Enable receiver, transmitter and interrupts on RX*/
   UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
   /* Set frame format: 8data, 2stop bit */
   UCSRC = (1<<USBS)|(3<<UCSZ0);
   //Разрешаем глобальные прерывания
   //sei();
   asm("sei");
   usart_enabled=1;
}



void inc_counter(void){
unsigned char dummy;
dummy=UDR;
//asm("cli");
  cli();
  chr_cntr++;
  sei();
//asm("sei");
}




/*********** Обработка прерывания по приёму символа на USART *******************************************/

ISR(__vector_7){   //interrupt[SIG_USART0_RX]    //SIG_USART0_RX //__vector_7 //_VECTOR(7)
int *p;
unsigned char dummy;
dummy=UDR;

/* ВАРИАНТ 1 */
chr_cntr++; //инкримируем счётчик прерываний  (не работает)

/* ВАРИАНТ 2 */
p = &chr_cntr;      //инкримируем счётчик прерываний через ссылки (не работает)
*p  = ++chr_cntr;

/* ВАРИАНТ 3 */   
inc_counter();    //инкримируем счётчик прерываний вызовом функции (не работает)
   
// ЗАПРЕЩАТЬ ПРЕРЫВАНИЯ ПЕРЕД ВЫПОЛНЕНИЕМ ЛЮБОГО ИЗ ВАРИАНТОВ,
//            А ПОТОМ ВОЗОБНОВЛЯТЬ, НЕ ПОМОГАЕТ!



/***********  мигает зелёный светодиод - индикатор вызова прерывания ************/
      LED_GREEN_ON
      _delay_ms(200);
      LED_GREEN_OFF
      _delay_ms(200);
   
}     



int main(void){     

    LED_INIT   //DDRD = 0x38; //DDRD = 0b00111000
   
   USART_Enable();
   
   
   while(1){     
      
      /*********** Постоянно мигает Желтый светодиод - индикатор цикла **********/
      LED_YELLOW_ON
      _delay_ms(200);
      LED_YELLOW_OFF
      _delay_ms(200);            
      
        /*********** Кол-во миганий светодиода = кол-ву прерываний ****************/
        for(int a=0; a<chr_cntr;a++){   
      LED_RED_ON
      _delay_ms(200);
      LED_RED_OFF
      _delay_ms(200);
      
      }      
   }     
}


Добавлено спустя 2 минуты 24 секунды:
=DeaD= писал(а):Может просто потом где-то написано "if(a=0)..." ? :) Как узнаёте, что а=0?

Считаю при помощи моргания светодиода, или отсылаю в терминал по RS232

Re: От WinAVR текут мозги!

=DeaD= » 28 янв 2009, 00:29

И что наблюдается на светодиодах при отправке чего-то на МК?

Добавлено спустя 1 минуту 44 секунды:
Первое, что напрашивается - поменять в программе местами красный и желтый светодиоды, проверить что оно вообще работает, а то может светодиод криво подключен красный :)

Re: От WinAVR текут мозги!

avr123.nm.ru » 28 янв 2009, 00:31

В "Си для МК" - avr123.nm.ru/05.htm - рекомендую объявлять переменные изменяемые в прерывании с модификатором:

volatile int a=0;

Re: От WinAVR текут мозги!

redcat » 28 янв 2009, 00:46

=DeaD= писал(а):И что наблюдается на светодиодах при отправке чего-то на МК?

Добавлено спустя 1 минуту 44 секунды:
Первое, что напрашивается - поменять в программе местами красный и желтый светодиоды, проверить что оно вообще работает, а то может светодиод криво подключен красный :)



леды подключены верно, при отправке символа на уарт, зелёный мигает один раз(как и задумано) и программа поехала дальше (желтый мигает). Если в прерывании отослать обратно символ, например предварительно его ++, то всё получается...
avr123.nm.ru писал(а):В "Си для МК" - avr123.nm.ru/05.htm - рекомендую объявлять переменные изменяемые в прерывании с модификатором:

volatile int a=0;

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

Добавлено спустя 3 минуты 46 секунд:
По идее моя конструкция не должна работать.... ведь при прерывании записываются все регистры.... а потом восстанавливаются. т.е. если до прерывания А=0; то и после, влюбом случае, 'А' должна быть =0
......

Re: От WinAVR текут мозги!

=DeaD= » 28 янв 2009, 00:49

А если зелёным мигать только если а!=0?

Добавлено спустя 3 минуты 4 секунды:
И в основном цикле тоже мигать красным не столько, сколько в "а" лежит, а просто мигать 1 раз, если а!=0.

(везде читать не "а", а "chr_cntr")

Re: От WinAVR текут мозги!

redcat » 28 янв 2009, 00:57

=DeaD= писал(а):А если зелёным мигать только если а!=0?

Добавлено спустя 3 минуты 4 секунды:
И в основном цикле тоже мигать красным не столько, сколько в "а" лежит, а просто мигать 1 раз, если а!=0.

(везде читать не "а", а "chr_cntr")


если "а" не равно 0 - то фига с маслом.... т.е. а попрежнему ноль.

Мне не понятно, как подобные конструкции работают у других, как например множество примеров по заполнению буфера (buf) символами, когда buf обьявлен глобально как массив... Правда большинство примеров делалось на CVAVR, возможно он "за кадром" чтото делает с переменной buf (например volatile (ещё не пробывал)). Но использования данног компилятора не нахожу выходом из проблемы, люблю когда всё на виду и логично. ...вот тут-то и напрашивается ассемблер, только он мне не нравится.

Re: От WinAVR текут мозги!

=DeaD= » 28 янв 2009, 01:01

А зелёным щас мигает если а!=0?

(я уже спать, у нас 2 ночи :))

Re: От WinAVR текут мозги!

avr123.nm.ru » 28 янв 2009, 01:18

redcat писал(а):quote="avr123.nm.ru"]В "Си для МК" - http://avr123.nm.ru/05.htm - рекомендую объявлять переменные изменяемые в прерывании с модификатором:

volatile int a=0;

хм.. не пробывал, не знаю такого модификатора.
гдето по подробнее про него узнать можно? (не считая поиска)))[/quote]

Да. ЛИНК указан ведь !

Re: От WinAVR текут мозги!

redcat » 28 янв 2009, 01:26

да... я заметил, что после целого дня за компом, я думаю медленнее чем мой контроллер)))) Я этот курс раза три прочитал, ща ещё попробую.

=DeaD= писал(а):А зелёным щас мигает если а!=0?

(я уже спать, у нас 2 ночи :))

чтото я запутался вообще... не мигает. а=0


Нашел -
volatile - ставьте если нужно предотвратить возможность повреждения содержимого переменной в прерывании, и не позволить компилятору попытаться выкинуть её при оптимизации кода.

Попробую на эмуляторе, сам МК на работе, к компу с ЛПТ подключен, до усб программера руки не доходят.

Re: От WinAVR текут мозги!

avr123.nm.ru » 28 янв 2009, 03:25

redcat писал(а):Нашел в курсе AVR -
volatile - ставьте если нужно предотвратить возможность повреждения содержимого переменной в прерывании, и не позволить компилятору попытаться выкинуть её при оптимизации кода.



Руководство по WinAVR есть в папке C:\WinAVR-20081124rc3\doc\avr-libc

avr-libc-user-manual.pdf - там пример как раз про - volatile int

И есть книга по WinAVR - http://stream.ifolder.ru/10240897 пароль 1

Re: От автора текут мозги!

Vooon » 28 янв 2009, 05:27

Уж сколько раз писалось в интернете что такие переменные нужно обьявлять как volatile...
Да и в документации все есть.

PS: читайте документацию к инструменту, которым пользуетесь.
PSS: такие портянки в пост совать не айс, есть же загрузка файлов.


Rambler\'s Top100 Mail.ru counter