QUOTE (Zol'berg @ May 8 2013, 11:42)

Глобальные и локальные переменные мне знакомы, работают по разному, но суть одна-в том, что работать должно и так и так
Уже разобрались - это была внутренняя ошибка компилятора.
QUOTE (Zol'berg @ May 8 2013, 11:42)

А как сделать быстрее, писать конфигурацию прямо в регистры?
Да. Причем сразу, одной командой, а не десятком дерганий каждого битика по отдельности, чем страдает вторая категория примеров из интернета. Вот, сравните, пример по ссылке
из соседней ветки:
CODE
ADC1->CR1 = 0; //предочистка регистра
ADC1->CR2 |= ADC_CR2_CAL; //запуск калибровки
while (!(ADC1->CR2 & ADC_CR2_CAL)){}; //ждем окончания калибровки
ADC1->CR2 = ADC_CR2_JEXTSEL; //выбрать источником запуска разряд JSWSTART
ADC1->CR2 |= ADC_CR2_JEXTTRIG; //разр. внешний запуск инжектированной группы
ADC1->CR2 |= ADC_CR2_CONT; //режим непрерывного преобразования
ADC1->CR1 |= ADC_CR1_SCAN; //режим сканирования (т.е. несколько каналов)
ADC1->CR1 |= ADC_CR1_JAUTO; //автомат. запуск инжектированной группы
ADC1->JSQR = (uint32_t)(4-1)<<20; //задаем количество каналов в инжектированной группе
ADC1->JSQR |= (uint32_t)3<<(5*0); //номер канала для первого преобразования
ADC1->JSQR |= (uint32_t)4<<(5*1); //номер канала для второго преобразования
ADC1->JSQR |= (uint32_t)5<<(5*2); //номер канала для третьего преобразования
ADC1->JSQR |= (uint32_t)6<<(5*3); //номер канала для четвертого преобразования
ADC1->CR2 |= ADC_CR2_ADON; //включить АЦП
ADC1->CR2 |= ADC_CR2_JSWSTART; //запустить процес преобразования
Вам, как недавнему ассемблеристу довольно просто посчитать сколько здесь чтений регистра периферии, сколько наложений масок и записей.
Теперь смотрите сюда:
CODE
// calibrate ADC
ADC1->CR2 = 0
| 1 * ADC_CR2_ADON // A/D Converter ON
| 0 * ADC_CR2_CONT // Continuous Conversion disabled
| 1 * ADC_CR2_CAL // A/D Calibration
| 0 * ADC_CR2_RSTCAL // Reset Calibration
| 0 * ADC_CR2_DMA // Direct Memory access mode
| 0 * ADC_CR2_ALIGN // Data Alignment: right
| 0 * ADC_CR2_JEXTSEL_0 // External event for injected group: none
| 7 * ADC_CR2_JEXTTRIG // External Trigger Conversion mode for injected channels: JSWSTART
| 4 * ADC_CR2_EXTSEL_0 // External Event for regular group: TIM3TRGO
| 0 * ADC_CR2_EXTTRIG // External Trigger Conversion mode for regular channels: enabled
| 0 * ADC_CR2_JSWSTART // Start Conversion of injected channels
| 0 * ADC_CR2_SWSTART // Start Conversion of regular channels
| 0 * ADC_CR2_TSVREFE // Temperature Sensor and VREFINT disabled
;
// wait until calibration is complete
while(ADC1->CR2 & ADC_CR2_CAL)
;
ADC1->SQR1 = 0
| 0 * ADC_SQR1_SQ13_0 // 13th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ14_0 // 14th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ15_0 // 15th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ16_0 // 16th conversion in regular sequence channel: default
| 0 * ADC_SQR1_L_0 // Regular channel sequence length: 1
;
ADC1->SQR3 = 0
| 0 * ADC_SQR3_SQ6_0 // 6th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ5_0 // 5th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ4_0 // 4th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ3_0 // 3rd conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ2_0 // 2nd conversion in regular sequence channel: default
| 8 * ADC_SQR3_SQ1_0 // 1st conversion in regular sequence channel: ADC_IN8 (AUDIO)
ADC1->JSQR = 0
| 0 * ADC_JSQR_JSQ1_0 // 4?th conversion in injected sequence, not used
| 0 * ADC_JSQR_JSQ2_0 // 3?th conversion in injected sequence, not used
| 0 * ADC_JSQR_JSQ3_0 // 2?th conversion in injected sequence, not used
| 7 * ADC_JSQR_JSQ4_0 // 1st conversion in injected sequence, HOOK
| 0 * ADC_JSQR_JL_0 // sequence length
;
ADC1->CR1 = 0
| 7 * ADC_CR1_AWDCH_0 // Analog watchdog channel, HOOK
| 0 * ADC_CR1_EOCIE // EOC interrupt disabled
| 0 * ADC_CR1_AWDIE // Analog Watchdog interrupt disabled
| 0 * ADC_CR1_JEOCIE // Injected channels interrupt disabled
| 1 * ADC_CR1_SCAN // Scan mode, enabled (need for auto injected conversions)
| 1 * ADC_CR1_AWDSGL // watchdog on a single (AWDCH) channel
| 1 * ADC_CR1_JAUTO // injected group conversion after regular channels
| 0 * ADC_CR1_DISCEN // Discontinuous mode on regular channels, disabled.
// One pulse=one conversion
| 0 * ADC_CR1_JDISCEN // Discontinuous mode on injected channels, disabled
| 0 * ADC_CR1_DISCNUM_0 // Discontinuous mode channel count
| 1 * ADC_CR1_JAWDEN // Analog watchdog enabled on injected channels
| 0 * ADC_CR1_AWDEN // Analog watchdog disabled on regular channels
;
// start conversions
ADC1->CR2 = 0
| 1 * ADC_CR2_ADON // A/D Converter ON
| 0 * ADC_CR2_CONT // Continuous Conversion disabled
| 0 * ADC_CR2_CAL // A/D Calibration
| 0 * ADC_CR2_RSTCAL // Reset Calibration
| 1 * ADC_CR2_DMA // Direct Memory access enabled
| 1 * ADC_CR2_ALIGN // Data Alignment: left
| 7 * ADC_CR2_JEXTSEL_0 // External event for injected group: JSWSTART
| 0 * ADC_CR2_JEXTTRIG // External Trigger Conversion mode for injected channels: disabled
| 4 * ADC_CR2_EXTSEL_0 // External Event for regular group: TIM3TRGO
| 1 * ADC_CR2_EXTTRIG // External Trigger Conversion mode for regular channels: enabled
| 0 * ADC_CR2_JSWSTART // Start Conversion of injected channels
| 0 * ADC_CR2_SWSTART // Start Conversion of regular channels
| 0 * ADC_CR2_TSVREFE // Temperature Sensor and VREFINT disabled
;
Конечно, примеры не тождественны, но разницу вы увидеть должны.
QUOTE (Zol'berg @ May 8 2013, 11:42)

Но есть другой вопрос, уже наверное не по теме : как добиться быстрой работы с портами, ассемблерные вставки?
Забудьте о них. Совсем. Прямая запись в регистры, bit-bang и DMA - ваше все. На ассемблере вы не сделаете быстрее.