Если я правильно выявил проблему, то у меня не происходит инициализации глобальной переменной. Сишный код такой:
CODE
#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() уже произвести инициализацию, то все нормально.
На всякий, содержимое стартапа:
CODE
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".
Сообщение отредактировал ohmjke - Apr 2 2012, 14:12