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

Обсуждаем контроллеры компании Atmel.
PILS1396
Родился
Сообщения: 5
Зарегистрирован: Вт ноя 16, 2010 13:37:28
Контактная информация:

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

Сообщение PILS1396 »

ARV писал(а):
PILS1396 писал(а):Извиняюсь, ошибся темой пишу в cvavr. Но в прерывании (при переполнении буфера приема) каждый байт записывается в массиве rx_buffer [], а нумерации начинается с нуля.
То есть как я понимаю переданы 150 записываются в массиве как:
rx_buffer [0] = 1
rx_buffer [1] = 5
rx_buffer [2] = 0
так вот хренушки! если вы послали "150" из терминальной программы, то у вас будет
rx_buffer [0] = '1'
rx_buffer [1] = '5'
rx_buffer [2] = '0'

а это совершенно не то!
с другой стороны, я не знаю, что у вас за терминалка, но ежели она вдруг посылает именно ЧИСЛО 150, то у вас будет еще лучше:
rx_buffer [0] = 150
rx_buffer [1] = неизвестно что
rx_buffer [2] = неизвестно что


собственно, о чем я и писал: вы не знаете Си и своих собственных инструментов. бегом читать букварь! :)))

Спасибо иду читать букварь
PILS1396
Родился
Сообщения: 5
Зарегистрирован: Вт ноя 16, 2010 13:37:28
Контактная информация:

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

Сообщение PILS1396 »

AlexFisher писал(а):Ошибок может быть по крайней мере 2:
1. Группа операторов начнет работать, когда передан всего один символ из трех (то есть уже не правильно)
2. Группа операторов не вычищает за собой вышеозначенный буфер, то есть не заносит туда 0х00

Это я учел. Но при передаче сообщения "150" прерывание происходило, а при передаче сообщения "1" не происходит, а происходит при передаче еще двух аналогичных сообщений.
PILS1396
Родился
Сообщения: 5
Зарегистрирован: Вт ноя 16, 2010 13:37:28
Контактная информация:

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

Сообщение PILS1396 »

Разобрался :))
alexval2006
Прорезались зубы
Сообщения: 225
Зарегистрирован: Сб мар 10, 2007 20:05:39
Откуда: валуйки
Контактная информация:

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

Сообщение alexval2006 »

есть нужда обозвать порт PORTC как нибудь по другому и по #define его чтобы все порты разом пенять по необходимости а то во многих местах менять приходиться как это сделать правильно а то мои эксперименты нечем хорошим не увенчались компилятор либо ругается либо нечего не работает

// Выводим данные на DataPin (PC0)
PORTC &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTC |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт

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

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

Сообщение ARV »

alexval2006 писал(а):есть нужда обозвать порт PORTC как нибудь по другому и по #define его чтобы все порты разом пенять по необходимости а то во многих местах менять приходиться как это сделать правильно а то мои эксперименты нечем хорошим не увенчались компилятор либо ругается либо нечего не работает

// Выводим данные на DataPin (PC0)
PORTC &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTC |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт

я не понял, что вам надо и что не так - приведенный код нормальный, рабочий, правильный.
alexval2006 писал(а):да еще немного о правилах размещения цикла майн в программе почему он должен быть обязательно в самом низу кода? иначе чущ начинаетса

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

Мой уютный бложик... заходите!
alexval2006
Прорезались зубы
Сообщения: 225
Зарегистрирован: Сб мар 10, 2007 20:05:39
Откуда: валуйки
Контактная информация:

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

Сообщение alexval2006 »

[quote]правило си: каждая функция должна быть объявлена или определена ранее, чем использована.[quote] ЭТО БЫЛА МОЯ ОШИБКА СПАСИБО :oops:


А что касаемо кода то да он правильный дан для примера мне нужно букву порта менять, ну вот нечто такое но почему то не получается
#define PORT@ PORTC //выбран порт PORTC

PORT@ &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORT@ |=_BV(DataPin); // установим DataPin в "1"


ДОБАВЛЕНО ПОЗЖЕ

вопрос решен эти две ошибки наслаивались друг на друга и создавали полную кашу
#define PORTX1 PORTD //выбран порт PORTC
// Выводим данные на DataPin (PC0)
PORTX1 &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTX1 |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт

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

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

Сообщение ARV »

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

я вот для себя сделал файлик с удобными макросами, назвал его avr-helper.h и подключаю его ко всем своим проектам. файлик прилагаю. думаю, вам стоит обратить внимание на макрос CONCAT, я использую его для таких целей:

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

#define OUT_    D /* обратите внимание - только БУКВА порта*/
#define OUT_PORT CONCAT(PORT, OUT_)
#define OUT_DDR CONCAT(DDR, OUT_)
#define OUT_PIN CONCAT(PIN, OUT_)
// и далее я использую уже не конкретный PORTD, а эти макросы:

OUT_DDR = 254; // все на вывод, кроме младешего бита
OUT_PORT = 1; // подтяжка на младший бит
if(OUT_PIN & 1) // проверка уровня на младшем пине
то есть в программе я уже нигде не указываю настоящие имена регистров портов PORTC или DDRB, а использую их макросы-алиасы. если вдруг приспичит изменить порт кнопок с порта С на порт В, мне придется поменять только ОДНУ-ЕДИНСТВЕННУЮ букву в ОДНОМ-ЕДИНСТВЕННОМ дефайне - остальная часть программы останется нетронутой
Вложения
avr_helper.h
(7.01 КБ) 593 скачивания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
alexval2006
Прорезались зубы
Сообщения: 225
Зарегистрирован: Сб мар 10, 2007 20:05:39
Откуда: валуйки
Контактная информация:

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

Сообщение alexval2006 »

спасибо поюзаем :)

обявляютса так?
//Прототипы подпрограмм
void USART_Transmit( unsigned char data );
void USART_Init( unsigned int ubrr);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

alexval2006 писал(а):спасибо поюзаем :)

на здоровье. там еще кое-что удобственное имеется, особенно если редактор умеет по мере ввода подсказывать "окончания"... например, надо задать предделитель таймера: начинаем вводить TIMER_CLK_ и редактор подсказывает возможные окончания DIV_1 или DIV_8 или DIV_64 и т.д. - остается только выбрать и нажать ENTER :) в принципе, если хорошенько прочесть файлик и уловить логику составления имен макросов, несложно и на память все помнить...
надеюсь, вам понравится.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Сообщение ARV »

alexval2006 писал(а):обявляютса так?
//Прототипы подпрограмм
void USART_Transmit( unsigned char data );
void USART_Init( unsigned int ubrr);
да
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

Какой-то бред в Студио 4.18SP3 и GCC

Сообщение Reset »

Скачал сабж, решил с асма переползти (не знаю зачем, наверное от того, что чаще стали попадаться для доводки до ума коряво писаные проекты на С).
Ну пробую вообще на предмет, что он работает. Пишу:

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

#include <avr/io.h>
#include <avr/iom128.h>
#include <avr/interrupt.h>
//******************************************************//
int main (void)
{
int a=4;
PORTB=a;
if(PINB!=0xFF)
{
a=3;
}
while(1)
{
a++;
}

}


В результате компилится вот в этот перл:

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

0: File not found
+00000000:   940C0046    JMP       0x00000046     Jump
+00000002:   940C0050    JMP       0x00000050     Jump
+00000004:   940C0050    JMP       0x00000050     Jump
+00000006:   940C0050    JMP       0x00000050     Jump
+00000008:   940C0050    JMP       0x00000050     Jump
+0000000A:   940C0050    JMP       0x00000050     Jump
+0000000C:   940C0050    JMP       0x00000050     Jump
+0000000E:   940C0050    JMP       0x00000050     Jump
+00000010:   940C0050    JMP       0x00000050     Jump
+00000012:   940C0050    JMP       0x00000050     Jump
+00000014:   940C0000    JMP       0x00000000     Jump
+00000016:   940C0050    JMP       0x00000050     Jump
+00000018:   940C0050    JMP       0x00000050     Jump
+0000001A:   940C0050    JMP       0x00000050     Jump
+0000001C:   940C0050    JMP       0x00000050     Jump
+0000001E:   940C0050    JMP       0x00000050     Jump
+00000020:   940C0050    JMP       0x00000050     Jump
+00000022:   940C0050    JMP       0x00000050     Jump
+00000024:   940C0050    JMP       0x00000050     Jump
+00000026:   940C0050    JMP       0x00000050     Jump
+00000028:   940C0050    JMP       0x00000050     Jump
+0000002A:   940C0050    JMP       0x00000050     Jump
+0000002C:   940C0050    JMP       0x00000050     Jump
+0000002E:   940C0050    JMP       0x00000050     Jump
+00000030:   940C0050    JMP       0x00000050     Jump
+00000032:   940C0050    JMP       0x00000050     Jump
+00000034:   940C0050    JMP       0x00000050     Jump
+00000036:   940C0050    JMP       0x00000050     Jump
+00000038:   940C0050    JMP       0x00000050     Jump
+0000003A:   940C0050    JMP       0x00000050     Jump
+0000003C:   940C0050    JMP       0x00000050     Jump
+0000003E:   940C0050    JMP       0x00000050     Jump
+00000040:   940C0050    JMP       0x00000050     Jump
+00000042:   940C0050    JMP       0x00000050     Jump
+00000044:   940C0050    JMP       0x00000050     Jump
+00000046:   2411        CLR       R1             Clear Register
+00000047:   BE1F        OUT       0x3F,R1        Out to I/O location
+00000048:   EFCF        SER       R28            Set Register
+00000049:   E1D0        LDI       R29,0x10       Load immediate
+0000004A:   BFDE        OUT       0x3E,R29       Out to I/O location
+0000004B:   BFCD        OUT       0x3D,R28       Out to I/O location
+0000004C:   940E0052    CALL      0x00000052     Call subroutine
+0000004E:   940C0056    JMP       0x00000056     Jump
+00000050:   940C0000    JMP       0x00000000     Jump
@00000052: main
---- GCC_tst.c ----------
7:        {
+00000052:   E084        LDI       R24,0x04       Load immediate
+00000053:   BB88        OUT       0x18,R24       Out to I/O location
10:       if(PINB!=0xFF)
+00000054:   B386        IN        R24,0x16       In from I/O location
+00000055:   CFFF        RJMP      PC-0x0000      Relative jump
10:       if(PINB!=0xFF)
+00000056:   94F8        CLI                      Global Interrupt Disable
+00000057:   CFFF        RJMP      PC-0x0000      Relative jump
+00000058:   00FF        ???                      Data or unknown opcode
+00000059:   FFFF        ???                      Data or unknown opcode
+0000005A:   FFFF        ???                      Data or unknown opcode


Во первых - висит себе на сишной строчке if(PINB!=0xFF), что соответствует бесконечному циклу по адресу 55

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

...
10:       if(PINB!=0xFF)
+00000054:   B386        IN        R24,0x16       In from I/O location
+00000055:   CFFF        RJMP      PC-0x0000      Relative jump
10:       if(PINB!=0xFF)
+00000056:   94F8        CLI                      Global Interrupt Disable
+00000057:   CFFF        RJMP      PC-0x0000      Relative jump
+00000058:   00FF        ???                      Data or unknown opcode
...
, что собственно и должен делать (ну как ему по rjmp пц-0 не повиснуть-то..

Вопрос логичен до нельзя: - что не так? Варнингов при компиляции нет. таргет - mega128...

Во вторых - руководствуясь ЧЕМ оно main вызывает через CALL? Это как-то можно исправить на нормальный rjmp?

В третьих:
Почему 10: if(PINB!=0xFF) - 2 раза встречается?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

1. не нужно писать #include <avr/iom128.h> - если вы настроили проект правильно, нужный модуль микроконтроллера будет подключен автоматически изнутри #include <avr/iо.h>
2. правильно висит на бесконечном цикле, ничего не делая: вы в своей программе что-то сделали?! ваш цикл while(1){a++;} не делает ничего, что хоть как-то может повлиять на что-то - вот оптимизатор компилятора и выбросил изменение переменной, как явно бесполезное действие, и остался только бесконечный цикл.
3. по стандарту Си функция main() - это именно функция, а функции вызываются при помощи CALL. согласен, это перебор для AVR - но в сущности никакой проблемы не представляет: вам оно не все равно, будет там JMP или CALL? лишних пара байт в коде, но ведь работать будет нормально! :)
4. в листинге из-за работы оптимизатора порой возникают чУдные вещи, например, повторение кусков исходного текста в разных местах листинга. эта проблема известна, но ее не могут побороть (или не хотят) разработчики avr-gcc. главное, что в коде нет лишних повторов, а листинг, хоть и слегка замусоривается, тем не менее вполне читабельный... смиритесь :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

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

Сообщение Reset »

ARV писал(а):1. не нужно писать #include <avr/iom128.h> - если вы настроили проект правильно, нужный модуль микроконтроллера будет подключен автоматически изнутри #include <avr/iо.h>
2. правильно висит на бесконечном цикле, ничего не делая: вы в своей программе что-то сделали?! ваш цикл while(1){a++;} не делает ничего, что хоть как-то может повлиять на что-то - вот оптимизатор компилятора и выбросил изменение переменной, как явно бесполезное действие, и остался только бесконечный цикл.
3. по стандарту Си функция main() - это именно функция, а функции вызываются при помощи CALL. согласен, это перебор для AVR - но в сущности никакой проблемы не представляет: вам оно не все равно, будет там JMP или CALL? лишних пара байт в коде, но ведь работать будет нормально! :)
4. в листинге из-за работы оптимизатора порой возникают чУдные вещи, например, повторение кусков исходного текста в разных местах листинга. эта проблема известна, но ее не могут побороть (или не хотят) разработчики avr-gcc. главное, что в коде нет лишних повторов, а листинг, хоть и слегка замусоривается, тем не менее вполне читабельный... смиритесь :)

Всё бы хорошо, но симулятор по этой дряни не ходит нормально.
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м? :)

Не совать же все переменные волетайлом, чтобы он не трогал... или совать? Вроде как именно изза приколов RS232 старых машин, где для инициализации порта надо было 2 раза писать в один и тот же адрес одно и то же и оптимизатор тупо резал код, и появился волетайл..

А за "не нужно писать include" - бальшой пасиб.
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

проверил

Сообщение Reset »

volatile int a - полностью решает проблему. Но тогда без оптимизации код 182 байта, а с полной оптимизацией - 214 :)
Аватара пользователя
AlexFisher
Мучитель микросхем
Сообщения: 493
Зарегистрирован: Вт апр 21, 2009 13:31:27
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение AlexFisher »

Reset писал(а):Всё бы хорошо, но симулятор по этой дряни не ходит нормально.
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м? :)


Дело в том, что после инкремента эта переменная нигде не используется (не влияет на другие переменные) - поэтому операция выброшена.
Симулятор "ходит" уже по готовому коду - дизассемблируя на ходу и сопоставляя код согласно сишному. Отключите оптимизацию или пишите логичную программу.
[i]Да здравствует всё то, благодаря чему мы не смотря ни на что![/i]
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

По последней версии AVR

Сообщение Reset »

Также замечено, мож людям пригодится - при подключении simulator2 (их 2 в последней студии 4.18SP3) - студия падает при выходе из симулятора если проект в GCC. При работе с симулятором без цифры - всё нормально.
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

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

Сообщение Reset »

AlexFisher писал(а):
Reset писал(а):Всё бы хорошо, но симулятор по этой дряни не ходит нормально.
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м? :)


Дело в том, что после инкремента эта переменная нигде не используется (не влияет на другие переменные) - поэтому операция выброшена.
Симулятор "ходит" уже по готовому коду - дизассемблируя на ходу и сопоставляя код согласно сишному. Отключите оптимизацию или пишите логичную программу.

Не всегда так. Если переменная не объявлена как volatile - часто оптимизатор рубит защитные интервалы. В смысле, когда надо включить программный таймер на ожидание какого-то таймаута (на пример ожидания следующего байта по UART), а условие внешнее (ну не понятно же, досчитает он когда-нибудь, или на том конце всё хорошо и инкремент переменной равен декременту) - бывало у моего коллеги вырубало этот кусок оптимизация в IAR.
Не знаю как в GCC, но на всякий случай проверил volatile - отлично посылает подальше оптимизатор.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

вы сами решите для себя: какой смысл изменять ячейку ОЗУ, если результат этого изменения нигде никому не требуется?! история возникновения volatile, как мне кажется, вами несколько искажена, но тем не менее, если вам необходимо, чтобы делалось что-то бессмысленное и бесполезное - вы просто обязаны об этом уведомить оптимизатор - он поймет :) более того: volatile просто необходимо указывать для всех глобальных переменных, которые используются и в прерываниях, и в обычных функциях.

что касается не хождения симулятора, то это опять-таки из-за оптимизатора: если коду в строке исходника ничего в реальности не соответствует (выкинуто) - по чем ходить-то прикажете?! отключите оптимизацию -O0 и ходите по каждой строчке, сколько влезет :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Reset
Родился
Сообщения: 6
Зарегистрирован: Пт авг 04, 2006 16:58:35
Откуда: Харьков

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

Сообщение Reset »

ARV писал(а):вы сами решите для себя: какой смысл изменять ячейку ОЗУ, если результат этого изменения нигде никому не требуется?!


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

Несколько да. На самом деле было примерно как здесь (https://groups.google.com/group/comp.la ... 922?hl=ru&) пишут, ну и здесь (http://alenacpp.blogspot.com/2006/04/volatile.html) по русски рассуждают (к стати - путная статейка по волетайлу, оченно советую тем, кто хочет "окунуться" в тему и поймать дзен по поводу этой переменной)
На уровне железа многие процессоры просто резервируют блок адресов памяти для портов ввода-вывода. Большинство процессоров имеют отдельное пространство адресов ввода-вывода, со специальными инструкциями для доступа туда, но это не универсально (на PDP-11 такого не было, например) и даже сейчас, производители железа могут предпочесть использовать для этого адресное пространство памяти, по разным причинам. Я сомневаюсь, что кто-то так делает на архитектуре 8086 - различные адресные ограничения делают это очень сложным. Я видел это на 8080, это очень частое решение на старой TI 9900. И это был единственный способ организовать ввод-вывод на наборе инструкций PDP-11, там просто не было отдельного адресного пространства ввода-вывода (Я думаю, то же самое верно и для VAX. И не забывайте, что большинство работы на С раньше проходило именно на этих двух процессорах).
//----------
Теперь рассмотрим один из первых последовательных портов, что я использовал: Intel 8051. Нормальным способом его инициализации было записать 0 три раза в порт управления. Если у вас MMIO, то код на С мог бы выглядеть примерно так:


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

unsigned char* pControl = 0xff24 ;
*pControl = 0 ;
*pControl = 0 ;
*pControl = 0 ;



Что прекрасно работало на всех компиляторах С. Но вы можете себе представить, что могла бы с этим сделать сама простая оптимизация.

Какбе - пруфлинк.


ARV писал(а):что касается не хождения симулятора, то это опять-таки из-за оптимизатора: если коду в строке исходника ничего в реальности не соответствует (выкинуто) - по чем ходить-то прикажете?! отключите оптимизацию -O0 и ходите по каждой строчке, сколько влезет :)

Я поступил по другому - переключился на нормальный старый симулятор с симулятор2 в астудио и поставил волетайл переменную - всё работает как часы, максимальная степень оптимизации послушно слоняется по бесполезному циклу, разница в объеме стала теперь логичной 240Б без и 214 - с оптимизайией.

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

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

Сообщение ARV »

Reset писал(а):Вот что волетайл животворящий делает!
воистину! аминь :)

P.S. природа зарождения volatile не интересна, т.к. четко понятен его смысл - уведомить компилятор, что обращение к переменной должно быть каждый раз, когда переменная упомянута в тексте. про порты - это все интересно, но есть и такие финты: a = (b+3)*b; - если b не-volatile, то она будет считана в регистр один раз и затем этот регистр будет использован в вычислениях. если к моменту этого оператора значение b уже лежало в каком-то регистре, то этот регистр и будет использован без лишних загрузок. однако, если переменная b объявлена volatile, то в процессе вычислений она будет ДВАЖДЫ считана из ОЗУ. если эта перменная отображена на область адресов внешних устройств - может быть считано два РАЗНЫХ значения перменной со всеми вытекающими. :)
или вот еще, сравните: if(a & a & a) c if(PINB & PINB & PINB). в первом случае компилятор сделает по сути if(a), а вот во-втором - нет: произойдет "определение дребезга единицы", т.к. PINB - это volatile-переменная :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

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