Спасибо иду читать букварьARV писал(а):так вот хренушки! если вы послали "150" из терминальной программы, то у вас будетPILS1396 писал(а):Извиняюсь, ошибся темой пишу в cvavr. Но в прерывании (при переполнении буфера приема) каждый байт записывается в массиве rx_buffer [], а нумерации начинается с нуля.
То есть как я понимаю переданы 150 записываются в массиве как:
rx_buffer [0] = 1
rx_buffer [1] = 5
rx_buffer [2] = 0
rx_buffer [0] = '1'
rx_buffer [1] = '5'
rx_buffer [2] = '0'
а это совершенно не то!
с другой стороны, я не знаю, что у вас за терминалка, но ежели она вдруг посылает именно ЧИСЛО 150, то у вас будет еще лучше:
rx_buffer [0] = 150
rx_buffer [1] = неизвестно что
rx_buffer [2] = неизвестно что
собственно, о чем я и писал: вы не знаете Си и своих собственных инструментов. бегом читать букварь!
WinAvr в вопросах и ответах
Re: WinAvr в вопросах и ответах
- Реклама
Re: WinAvr в вопросах и ответах
Это я учел. Но при передаче сообщения "150" прерывание происходило, а при передаче сообщения "1" не происходит, а происходит при передаче еще двух аналогичных сообщений.AlexFisher писал(а):Ошибок может быть по крайней мере 2:
1. Группа операторов начнет работать, когда передан всего один символ из трех (то есть уже не правильно)
2. Группа операторов не вычищает за собой вышеозначенный буфер, то есть не заносит туда 0х00
Re: WinAvr в вопросах и ответах
Разобрался 
-
alexval2006
- Прорезались зубы
- Сообщения: 225
- Зарегистрирован: Сб мар 10, 2007 20:05:39
- Откуда: валуйки
- Контактная информация:
Re: WinAvr в вопросах и ответах
есть нужда обозвать порт PORTC как нибудь по другому и по #define его чтобы все порты разом пенять по необходимости а то во многих местах менять приходиться как это сделать правильно а то мои эксперименты нечем хорошим не увенчались компилятор либо ругается либо нечего не работает
// Выводим данные на DataPin (PC0)
PORTC &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTC |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт
да еще немного о правилах размещения цикла майн в программе почему он должен быть обязательно в самом низу кода? иначе чущ начинаетса
// Выводим данные на DataPin (PC0)
PORTC &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTC |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт
да еще немного о правилах размещения цикла майн в программе почему он должен быть обязательно в самом низу кода? иначе чущ начинаетса
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
я не понял, что вам надо и что не так - приведенный код нормальный, рабочий, правильный.alexval2006 писал(а):есть нужда обозвать порт PORTC как нибудь по другому и по #define его чтобы все порты разом пенять по необходимости а то во многих местах менять приходиться как это сделать правильно а то мои эксперименты нечем хорошим не увенчались компилятор либо ругается либо нечего не работает
// Выводим данные на DataPin (PC0)
PORTC &=~_BV(DataPin); // установим DataPin в "0"
else // иначе
PORTC |=_BV(DataPin); // установим DataPin в "1"
asm("nop"); // задержка в один такт
и снова не понял: main - это функция, а не цикл. но в ней обычно имеется главный цикл... так снова: что не так? если вы объявили прототипы всех функций, кроме main, то сам main (который не нуждается в объявлении прототипа) может быть в любом месте, не обязательно внизу.alexval2006 писал(а):да еще немного о правилах размещения цикла майн в программе почему он должен быть обязательно в самом низу кода? иначе чущ начинаетса
правило си: каждая функция должна быть объявлена или определена ранее, чем использована.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
-
alexval2006
- Прорезались зубы
- Сообщения: 225
- Зарегистрирован: Сб мар 10, 2007 20:05:39
- Откуда: валуйки
- Контактная информация:
Re: WinAvr в вопросах и ответах
[quote]правило си: каждая функция должна быть объявлена или определена ранее, чем использована.[quote] ЭТО БЫЛА МОЯ ОШИБКА СПАСИБО 
А что касаемо кода то да он правильный дан для примера мне нужно букву порта менять, ну вот нечто такое но почему то не получается
#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"); // задержка в один такт
так отлично работает
А что касаемо кода то да он правильный дан для примера мне нужно букву порта менять, ну вот нечто такое но почему то не получается
#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
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
как обычно, вопросы задаются так, что приходится гадать - что же именно вызывает проблему?
я вот для себя сделал файлик с удобными макросами, назвал его avr-helper.h и подключаю его ко всем своим проектам. файлик прилагаю. думаю, вам стоит обратить внимание на макрос CONCAT, я использую его для таких целей:то есть в программе я уже нигде не указываю настоящие имена регистров портов PORTC или DDRB, а использую их макросы-алиасы. если вдруг приспичит изменить порт кнопок с порта С на порт В, мне придется поменять только ОДНУ-ЕДИНСТВЕННУЮ букву в ОДНОМ-ЕДИНСТВЕННОМ дефайне - остальная часть программы останется нетронутой
я вот для себя сделал файлик с удобными макросами, назвал его 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) // проверка уровня на младшем пине
- Вложения
-
- avr_helper.h
- (7.01 КБ) 593 скачивания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
alexval2006
- Прорезались зубы
- Сообщения: 225
- Зарегистрирован: Сб мар 10, 2007 20:05:39
- Откуда: валуйки
- Контактная информация:
Re: WinAvr в вопросах и ответах
спасибо поюзаем 
обявляютса так?
//Прототипы подпрограмм
void USART_Transmit( unsigned char data );
void USART_Init( unsigned int ubrr);
обявляютса так?
//Прототипы подпрограмм
void USART_Transmit( unsigned char data );
void USART_Init( unsigned int ubrr);
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
на здоровье. там еще кое-что удобственное имеется, особенно если редактор умеет по мере ввода подсказывать "окончания"... например, надо задать предделитель таймера: начинаем вводить TIMER_CLK_ и редактор подсказывает возможные окончания DIV_1 или DIV_8 или DIV_64 и т.д. - остается только выбрать и нажать ENTERalexval2006 писал(а):спасибо поюзаем
надеюсь, вам понравится.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
даalexval2006 писал(а):обявляютса так?
//Прототипы подпрограмм
void USART_Transmit( unsigned char data );
void USART_Init( unsigned int ubrr);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Какой-то бред в Студио 4.18SP3 и GCC
Скачал сабж, решил с асма переползти (не знаю зачем, наверное от того, что чаще стали попадаться для доводки до ума коряво писаные проекты на С).
Ну пробую вообще на предмет, что он работает. Пишу:
В результате компилится вот в этот перл:
Во первых - висит себе на сишной строчке if(PINB!=0xFF), что соответствует бесконечному циклу по адресу 55 , что собственно и должен делать (ну как ему по rjmp пц-0 не повиснуть-то..
Вопрос логичен до нельзя: - что не так? Варнингов при компиляции нет. таргет - mega128...
Во вторых - руководствуясь ЧЕМ оно main вызывает через CALL? Это как-то можно исправить на нормальный rjmp?
В третьих:
Почему 10: if(PINB!=0xFF) - 2 раза встречается?
Ну пробую вообще на предмет, что он работает. Пишу:
Код: Выделить всё
#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
Код: Выделить всё
...
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
...Вопрос логичен до нельзя: - что не так? Варнингов при компиляции нет. таргет - mega128...
Во вторых - руководствуясь ЧЕМ оно main вызывает через CALL? Это как-то можно исправить на нормальный rjmp?
В третьих:
Почему 10: if(PINB!=0xFF) - 2 раза встречается?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
1. не нужно писать #include <avr/iom128.h> - если вы настроили проект правильно, нужный модуль микроконтроллера будет подключен автоматически изнутри #include <avr/iо.h>
2. правильно висит на бесконечном цикле, ничего не делая: вы в своей программе что-то сделали?! ваш цикл while(1){a++;} не делает ничего, что хоть как-то может повлиять на что-то - вот оптимизатор компилятора и выбросил изменение переменной, как явно бесполезное действие, и остался только бесконечный цикл.
3. по стандарту Си функция main() - это именно функция, а функции вызываются при помощи CALL. согласен, это перебор для AVR - но в сущности никакой проблемы не представляет: вам оно не все равно, будет там JMP или CALL? лишних пара байт в коде, но ведь работать будет нормально!
4. в листинге из-за работы оптимизатора порой возникают чУдные вещи, например, повторение кусков исходного текста в разных местах листинга. эта проблема известна, но ее не могут побороть (или не хотят) разработчики avr-gcc. главное, что в коде нет лишних повторов, а листинг, хоть и слегка замусоривается, тем не менее вполне читабельный... смиритесь
2. правильно висит на бесконечном цикле, ничего не делая: вы в своей программе что-то сделали?! ваш цикл while(1){a++;} не делает ничего, что хоть как-то может повлиять на что-то - вот оптимизатор компилятора и выбросил изменение переменной, как явно бесполезное действие, и остался только бесконечный цикл.
3. по стандарту Си функция main() - это именно функция, а функции вызываются при помощи CALL. согласен, это перебор для AVR - но в сущности никакой проблемы не представляет: вам оно не все равно, будет там JMP или CALL? лишних пара байт в коде, но ведь работать будет нормально!
4. в листинге из-за работы оптимизатора порой возникают чУдные вещи, например, повторение кусков исходного текста в разных местах листинга. эта проблема известна, но ее не могут побороть (или не хотят) разработчики avr-gcc. главное, что в коде нет лишних повторов, а листинг, хоть и слегка замусоривается, тем не менее вполне читабельный... смиритесь
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
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. главное, что в коде нет лишних повторов, а листинг, хоть и слегка замусоривается, тем не менее вполне читабельный... смиритесь
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м?
Не совать же все переменные волетайлом, чтобы он не трогал... или совать? Вроде как именно изза приколов RS232 старых машин, где для инициализации порта надо было 2 раза писать в один и тот же адрес одно и то же и оптимизатор тупо резал код, и появился волетайл..
А за "не нужно писать include" - бальшой пасиб.
проверил
volatile int a - полностью решает проблему. Но тогда без оптимизации код 182 байта, а с полной оптимизацией - 214 
- AlexFisher
- Мучитель микросхем
- Сообщения: 493
- Зарегистрирован: Вт апр 21, 2009 13:31:27
- Откуда: Санкт-Петербург
- Контактная информация:
Re: WinAvr в вопросах и ответах
Дело в том, что после инкремента эта переменная нигде не используется (не влияет на другие переменные) - поэтому операция выброшена.Reset писал(а):Всё бы хорошо, но симулятор по этой дряни не ходит нормально.
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м?![]()
Симулятор "ходит" уже по готовому коду - дизассемблируя на ходу и сопоставляя код согласно сишному. Отключите оптимизацию или пишите логичную программу.
[i]Да здравствует всё то, благодаря чему мы не смотря ни на что![/i]
По последней версии AVR
Также замечено, мож людям пригодится - при подключении simulator2 (их 2 в последней студии 4.18SP3) - студия падает при выходе из симулятора если проект в GCC. При работе с симулятором без цифры - всё нормально.
Re: WinAvr в вопросах и ответах
Не всегда так. Если переменная не объявлена как volatile - часто оптимизатор рубит защитные интервалы. В смысле, когда надо включить программный таймер на ожидание какого-то таймаута (на пример ожидания следующего байта по UART), а условие внешнее (ну не понятно же, досчитает он когда-нибудь, или на том конце всё хорошо и инкремент переменной равен декременту) - бывало у моего коллеги вырубало этот кусок оптимизация в IAR.AlexFisher писал(а):Дело в том, что после инкремента эта переменная нигде не используется (не влияет на другие переменные) - поэтому операция выброшена.Reset писал(а):Всё бы хорошо, но симулятор по этой дряни не ходит нормально.
И что значит "ни чего не делает"? А а++ - это он считает "ничего"м?![]()
Симулятор "ходит" уже по готовому коду - дизассемблируя на ходу и сопоставляя код согласно сишному. Отключите оптимизацию или пишите логичную программу.
Не знаю как в GCC, но на всякий случай проверил volatile - отлично посылает подальше оптимизатор.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
вы сами решите для себя: какой смысл изменять ячейку ОЗУ, если результат этого изменения нигде никому не требуется?! история возникновения volatile, как мне кажется, вами несколько искажена, но тем не менее, если вам необходимо, чтобы делалось что-то бессмысленное и бесполезное - вы просто обязаны об этом уведомить оптимизатор - он поймет
более того: volatile просто необходимо указывать для всех глобальных переменных, которые используются и в прерываниях, и в обычных функциях.
что касается не хождения симулятора, то это опять-таки из-за оптимизатора: если коду в строке исходника ничего в реальности не соответствует (выкинуто) - по чем ходить-то прикажете?! отключите оптимизацию -O0 и ходите по каждой строчке, сколько влезет
что касается не хождения симулятора, то это опять-таки из-за оптимизатора: если коду в строке исходника ничего в реальности не соответствует (выкинуто) - по чем ходить-то прикажете?! отключите оптимизацию -O0 и ходите по каждой строчке, сколько влезет
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: WinAvr в вопросах и ответах
ARV писал(а):вы сами решите для себя: какой смысл изменять ячейку ОЗУ, если результат этого изменения нигде никому не требуется?!
Несколько да. На самом деле было примерно как здесь (https://groups.google.com/group/comp.la ... 1922?hl=ru&) пишут, ну и здесь (http://alenacpp.blogspot.com/2006/04/volatile.html) по русски рассуждают (к стати - путная статейка по волетайлу, оченно советую тем, кто хочет "окунуться" в тему и поймать дзен по поводу этой переменной)ARV писал(а):история возникновения volatile, как мне кажется, вами несколько искажена, но тем не менее, если вам необходимо, чтобы делалось что-то бессмысленное и бесполезное - вы просто обязаны об этом уведомить оптимизатор - он пойметболее того: volatile просто необходимо указывать для всех глобальных переменных, которые используются и в прерываниях, и в обычных функциях.
Какбе - пруфлинк.На уровне железа многие процессоры просто резервируют блок адресов памяти для портов ввода-вывода. Большинство процессоров имеют отдельное пространство адресов ввода-вывода, со специальными инструкциями для доступа туда, но это не универсально (на PDP-11 такого не было, например) и даже сейчас, производители железа могут предпочесть использовать для этого адресное пространство памяти, по разным причинам. Я сомневаюсь, что кто-то так делает на архитектуре 8086 - различные адресные ограничения делают это очень сложным. Я видел это на 8080, это очень частое решение на старой TI 9900. И это был единственный способ организовать ввод-вывод на наборе инструкций PDP-11, там просто не было отдельного адресного пространства ввода-вывода (Я думаю, то же самое верно и для VAX. И не забывайте, что большинство работы на С раньше проходило именно на этих двух процессорах).
//-------------------------------
Теперь рассмотрим один из первых последовательных портов, что я использовал: Intel 8051. Нормальным способом его инициализации было записать 0 три раза в порт управления. Если у вас MMIO, то код на С мог бы выглядеть примерно так:
Код: Выделить всё
unsigned char* pControl = 0xff24 ; *pControl = 0 ; *pControl = 0 ; *pControl = 0 ;
Что прекрасно работало на всех компиляторах С. Но вы можете себе представить, что могла бы с этим сделать сама простая оптимизация.
Я поступил по другому - переключился на нормальный старый симулятор с симулятор2 в астудио и поставил волетайл переменную - всё работает как часы, максимальная степень оптимизации послушно слоняется по бесполезному циклу, разница в объеме стала теперь логичной 240Б без и 214 - с оптимизайией.ARV писал(а):что касается не хождения симулятора, то это опять-таки из-за оптимизатора: если коду в строке исходника ничего в реальности не соответствует (выкинуто) - по чем ходить-то прикажете?! отключите оптимизацию -O0 и ходите по каждой строчке, сколько влезет
P.S. Вот что волетайл животворящий делает!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: WinAvr в вопросах и ответах
воистину! аминь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-переменная
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


