ohmjke 0 2 апреля, 2012 Опубликовано 2 апреля, 2012 (изменено) · Жалоба Если я правильно выявил проблему, то у меня не происходит инициализации глобальной переменной. Сишный код такой: #define STM32F10X_MD_VL #include "stm32f10x.h" volatile static uint8_t change = 10; void EXTI0_IRQHandler (void) { EXTI->PR = EXTI_PR_PR0; //NVIC_ClearPendingIRQ (EXTI0_IRQn); change = (change == 2 ? 10 : 2); }; static __INLINE void system_init (void) { RCC->CR |= RCC_CR_HSEON; while (!(RCC->CR & RCC_CR_HSERDY)) {}; RCC->CFGR |= RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLSRC; RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)) {}; RCC->CFGR |= RCC_CFGR_SW_1; while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)) {}; RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN); }; static void delay (uint8_t mul) { uint32_t counter; for (counter = 0; counter < mul * 100000; counter++) {}; }; int __main (void) { system_init (); GPIOC->CRH &= ~GPIO_CRH_CNF8 & ~GPIO_CRH_CNF9 & ~GPIO_CRH_MODE8 & ~GPIO_CRH_MODE9; GPIOC->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1; AFIO->EXTICR [0] |= AFIO_EXTICR1_EXTI0_PA; EXTI->RTSR |= EXTI_RTSR_TR0; EXTI->IMR |= EXTI_IMR_MR0; NVIC_SetPriority (EXTI0_IRQn, 15); NVIC_EnableIRQ (EXTI0_IRQn); __enable_irq (); while (1) { GPIOC->BSRR = GPIO_BSRR_BS8 | GPIO_BSRR_BR9; delay (change); GPIOC->BSRR = GPIO_BSRR_BR8 | GPIO_BSRR_BS9; delay (change); }; }; Программа представляет собой "мигалку". По очереди включаются и выключаются синий и зеленый светодиоды на плате stm32vldiscovery. При включении значение переменной change должно быть равно десяти, при этом светодиоды моргают с определенной скоростью. При нажатии на кнопку возникает прерывание и change должна меняться с десяти на два. При этом скорость мигания увеличивается. Но дело вот в чем - если залить прошивку в МК и выдернуть/вставить usb провод, тем самым отключив на время питание, то светодиоды начнут мигать со скоростью меньшей, чем там, с которой они мигают, когда значение change равно десяти. Т.е., по идее, не происходит инициализации этой переменной. Если после этого нажать на кнопку, то вызовется прерывание, произойдет проверка условия в обработчике, и переменной присвоится значение 2. Дальше, если нажимать на кнопку, то все работает как положено - change меняется с двух на десять, с десяти на два и т.д. Но, если же нажать на кнопку RESET на плате, то после сброса сохраняется скорость мигания, т.е. получается что после такого сброса(в смысле, сброс подачей нужного уровня на ножку RESET, а не отключение питания) содержимое SRAM не сбрасывается, я прав? В любому случае, это еще раз подтверждает тот факт, что change не инициализируется. Из-за чего такое может быть? Если просто объявить эту переменную, без присваивания ей значения, а в функции main() уже произвести инициализацию, то все нормально. На всякий, содержимое стартапа: sram_base EQU 0x20000000 sram_size EQU 0x2000 stack_top EQU (sram_base + sram_size) ;------------------------------------------------ ;PRESERVE8 ;THUMB AREA reset, DATA, READONLY DCD stack_top DCD RESET_Handler DCD 0;NMI_Handler ; NMI Handler DCD 0;HardFault_Handler ; Hard Fault Handler DCD 0;MemManage_Handler ; MPU Fault Handler DCD 0;BusFault_Handler ; Bus Fault Handler DCD 0;UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0;SVC_Handler ; SVCall Handler DCD 0;DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD 0;PendSV_Handler ; PendSV Handler DCD 0;SysTick_Handler ; SysTick Handler ; External Interrupts DCD 0;WWDG_IRQHandler ; Window Watchdog DCD 0;PVD_IRQHandler ; PVD through EXTI Line detect DCD 0;TAMPER_IRQHandler ; Tamper DCD 0;RTC_IRQHandler ; RTC DCD 0;FLASH_IRQHandler ; Flash DCD 0;RCC_IRQHandler ; RCC DCD EXTI0_IRQHandler ; EXTI Line 0 DCD 0;EXTI1_IRQHandler ; EXTI Line 1 DCD 0;EXTI2_IRQHandler ; EXTI Line 2 DCD 0;EXTI3_IRQHandler ; EXTI Line 3 DCD 0;EXTI4_IRQHandler ; EXTI Line 4 DCD 0;DMA1_Channel1_IRQHandler ; DMA1 Channel 1 DCD 0;DMA1_Channel2_IRQHandler ; DMA1 Channel 2 DCD 0;DMA1_Channel3_IRQHandler ; DMA1 Channel 3 DCD 0;DMA1_Channel4_IRQHandler ; DMA1 Channel 4 DCD 0;DMA1_Channel5_IRQHandler ; DMA1 Channel 5 DCD 0;DMA1_Channel6_IRQHandler ; DMA1 Channel 6 DCD 0;DMA1_Channel7_IRQHandler ; DMA1 Channel 7 DCD 0;ADC1_IRQHandler ; ADC1 DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0;EXTI9_5_IRQHandler ; EXTI Line 9..5 DCD 0;TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15 DCD 0;TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 DCD 0;TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17 DCD 0;TIM1_CC_IRQHandler ; TIM1 Capture Compare DCD 0;TIM2_IRQHandler ; TIM2 DCD 0;TIM3_IRQHandler ; TIM3 DCD 0 ; Reserved DCD 0;I2C1_EV_IRQHandler ; I2C1 Event DCD 0;I2C1_ER_IRQHandler ; I2C1 Error DCD 0;0 ; Reserved DCD 0 ; Reserved DCD 0;SPI1_IRQHandler ; SPI1 DCD 0 ; Reserved DCD 0;USART1_IRQHandler ; USART1 DCD 0;USART2_IRQHandler ; USART2 DCD 0 ; Reserved DCD 0;EXTI15_10_IRQHandler ; EXTI Line 15..10 DCD 0;RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line DCD 0;CEC_IRQHandler ; HDMI-CEC DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0;TIM6_DAC_IRQHandler ; TIM6 and DAC underrun DCD 0;TIM7_IRQHandler ; TIM7 ;------------------------------------------------ AREA main_code, CODE, READONLY RESET_Handler PROC ENTRY IMPORT __main LDR R0, =__main BX R0 ENDP EXTI0_IRQHandler\ PROC EXPORT EXTI0_IRQHandler [WEAK] ENDP ;------------------------------------------------ ;AREA stack, DATA, READWRITE ;SPACE 0x1000 ;------------------------------------------------ END и scatter-файл: LR_IROM1 0x08000000 0x00020000 { ; load region size_region ER_IROM1 0x08000000 0x00020000 {; load address = execution address *.o (reset, +First) .ANY (+RO) } RW_IRAM1 0x20000000 0x00002000 { .ANY (+RW) } } В настройках линкера стоит галочка "Dont search standard libraries". Изменено 2 апреля, 2012 пользователем ohmjke Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 апреля, 2012 Опубликовано 2 апреля, 2012 · Жалоба Вы подменили библиотечную __main, которая, в частности, инициализирует глобальные переменные, на свою функцию. Назовете ее main, а не __main. В настройках линкера стоит галочка "Dont search standard libraries". Тогда инициализации ждать и не стоит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ohmjke 0 2 апреля, 2012 Опубликовано 2 апреля, 2012 · Жалоба А можно ли как-то это исправить? Просто, если поставить эту галку, то происходит то, что описано здесь: http://electronix.ru/forum/index.php?showtopic=101188 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 апреля, 2012 Опубликовано 2 апреля, 2012 · Жалоба Ничего "левого" там не происходит. Если вы сознательно отказываетесь от родных библиотек (а это необходимо бывает в очень редких случаях), то будьте готовы заменить их своим кодом, вплоть до процедур деления и т.п. Стандартная библиотека есть неотъемлемая часть языка, поэтому совет отключить ее на пустом месте выглядит более чем странно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ohmjke 0 2 апреля, 2012 Опубликовано 2 апреля, 2012 · Жалоба Ничего "левого" там не происходит. Если вы сознательно отказываетесь от родных библиотек (а это необходимо бывает в очень редких случаях), то будьте готовы заменить их своим кодом, вплоть до процедур деления и т.п. Стандартная библиотека есть неотъемлемая часть языка, поэтому совет отключить ее на пустом месте выглядит более чем странно. Хорошо, спасибо, все понятно. А можно ли как-то подправить её? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 2 апреля, 2012 Опубликовано 2 апреля, 2012 · Жалоба А можно ли как-то подправить её? Подправить - нет, только заменить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться