реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> WinAVR траблы, WinAVR не включает в код операторы, почему?
tazik
сообщение Dec 3 2009, 04:23
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Есть такой код:
CODE
/*
* main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
//#include <util/delay.h>
#include "sine_table.h"

#define BTN_UP PD0
#define BTN_DOWN PD1

static int16_t step_counter;
uint8_t step;
uint8_t kvadrant;
uint8_t time_delay;

void IOInit(void){
DDRB=(1<<PB3);
PORTD=(1<<BTN_DOWN)|(1<<BTN_UP);
DDRD=(1<<PD4)|(1<<PD3);
}

void Timer1Init(void){
ICR1=0x01FF;
TCCR1A=(1<<COM1A1);
TCCR1B=(1<<WGM13)|(1<<CS11);
TIMSK=(1<<TOV1);
}

ISR(TIMER1_OVF_vect){
switch(kvadrant){
case 1:{
OCR1A=pgm_read_word(pSine+step_counter);
step_counter+=step;
if (step_counter>511) {step_counter-=step; kvadrant=2;}
break;
};
case 2:{
OCR1A=pgm_read_word(pSine+step_counter);
step_counter-=step;
if (step_counter<0) {step_counter+=step; kvadrant=3;}
break;
};
case 3:{
OCR1A=0x1FF-pgm_read_word(pSine+step_counter);
step_counter+=step;
if (step_counter>511) {step_counter-=step; kvadrant=4;}
break;
};
case 4:{
OCR1A=0x1FF-pgm_read_word(pSine+step_counter);
step_counter-=step;
if (step_counter<0) {step_counter+=step; kvadrant=1;}
break;
};
};
};

int main(void){

OCR1A=0x10;
IOInit();
Timer1Init();
sei();
step=20;
step_counter=511;
kvadrant=4;
PORTD=0xFF;

while(1){
cli();
step=10; // в итоговом коде этого нет! (((
sei();
};
return 0;
}


И почему-то, в итоговом коде отсутствует операция step=10 основного цикла. получается так:
CODE

652: 82 bb out 0x12, r24 ; 18
654: f8 94 cli
656: 78 94 sei
658: fd cf rjmp .-6 ; 0x654 <main+0x44>


Отчего такое может быть? В каком месте у меня кривые руки?
Go to the top of the page
 
+Quote Post
Methane
сообщение Dec 3 2009, 04:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



Цитата(tazik @ Dec 3 2009, 06:23) *
Отчего такое может быть? В каком месте у меня кривые руки?

Скорее всего компилер просто за пределы цикла вынес.
Go to the top of the page
 
+Quote Post
tazik
сообщение Dec 3 2009, 05:07
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



вот так более подробно. К сожалению, не вынес (
CODE
while(1){
cli();
654: f8 94 cli
step=10;
sei();
656: 78 94 sei
658: fd cf rjmp .-6 ; 0x654 <main+0x44>
Go to the top of the page
 
+Quote Post
tazik
сообщение Dec 3 2009, 06:07
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



надо было добавить volatile в объявлении переменной step. Оказывается, старые чужие грабли
Go to the top of the page
 
+Quote Post
Methane
сообщение Dec 3 2009, 06:13
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 615
Регистрация: 12-01-09
Из: США, Главное разведовательное управление
Пользователь №: 43 230



Цитата(tazik @ Dec 3 2009, 08:07) *
отключил оптимизацию. Теперь выражение step=10 появилось в выходном коде. Почему WinAVR так оптимизирует? И как избавиться от такой оптимизации?
CODE
while(1){
cli();
7d4: f8 94 cli
step=10;
7d6: 8a e0 ldi r24, 0x0A ; 10
7d8: 80 93 66 00 sts 0x0066, r24
sei();
7dc: 78 94 sei
7de: fa cf rjmp .-12 ; 0x7d4 <main+0x3a>

Посмотрите, все же, чему равно step, в отладчике.
Go to the top of the page
 
+Quote Post
tazik
сообщение Dec 3 2009, 06:22
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Цитата(Methane @ Dec 3 2009, 13:13) *
Посмотрите, все же, чему равно step, в отладчике.


Спасибо за содействие) В основном цикле пытался обратиться к переменной, обрабатываемой в прерывании. Оказывается, в таких случаях надо писать модификатор volatile перед переменной.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Dec 3 2009, 11:17
Сообщение #7


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(tazik @ Dec 3 2009, 09:22) *
Спасибо за содействие) В основном цикле пытался обратиться к переменной, обрабатываемой в прерывании. Оказывается, в таких случаях надо писать модификатор volatile перед переменной.

Почитайте FAQ к Winavr, avr-libc и многие вопросы исчезнут. Этот момент там тоже описан. Чтение документации много времени не отнимет, сэкономит больше.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
tazik
сообщение Dec 3 2009, 16:42
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 195
Регистрация: 13-05-07
Из: Норильск
Пользователь №: 27 691



Цитата(mdmitry @ Dec 3 2009, 18:17) *
Почитайте FAQ к Winavr, avr-libc и многие вопросы исчезнут. Этот момент там тоже описан. Чтение документации много времени не отнимет, сэкономит больше.


Да, Вы правы! Очень полезный документ. Наткнулся почти случайно, попался бы он раньше...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 19:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01408 секунд с 7
ELECTRONIX ©2004-2016