Перейти к содержанию
    

Инициализация глобальных переменных, Keil

Если я правильно выявил проблему, то у меня не происходит инициализации глобальной переменной. Сишный код такой:

#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".

Изменено пользователем ohmjke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы подменили библиотечную __main, которая, в частности, инициализирует глобальные переменные, на свою функцию. Назовете ее main, а не __main.

 

В настройках линкера стоит галочка "Dont search standard libraries".

Тогда инициализации ждать и не стоит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно ли как-то это исправить? Просто, если поставить эту галку, то происходит то, что описано здесь: http://electronix.ru/forum/index.php?showtopic=101188

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Хорошо, спасибо, все понятно. А можно ли как-то подправить её?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...