Нужна помощь с STM32F429

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 4
Зарегистрирован: Пт мар 28, 2014 06:51:19

Сообщение wypuk »

Начал осваивать камни CM4, работаю с платой STM32F429I-DISCO. Возникла одна проблема, непонятная для меня.
Решил настроить МК на частоту 180 МГц, сделал все по алгоритму из даташита с включением Over-drive режима и т.п.
Чтобы проверить правильно ли все настроилось и работает решил по прерыванию таймера моргать СД с определенной частотой.
Но не нут то было. Настроил таймер TIM4, включил прерывание по переполнению UIE, разрешил его в NVIC, разрешил прерывания глобально.
Тут и возникла проблема. При переполнении таймера возникает запрос на прерывание, но в NVIC почему-то ставится флаг отложенного прерывания "Pending" и обработчик не вызывается.
Изображение
На что думать, куда смотреть и как исправить?
Работаю в Keil u4 v4.72. Вот код, правда на asm.
Спойлер

Код: Выделить всё

                AREA        |PROGRAMMA|, CODE, READONLY

                INCLUDE Sourse.s 
                INCLUDE Flash.s 
                INCLUDE Power.s 
                INCLUDE RCC.s 

                ; Interrupt

TIM4_IRQHandler PROC                          ; Прерывание TIM4
                EXPORT    TIM4_IRQHandler

                MOV32 R0, #TIM4
                MOV   R1, #0
                STR   R1, [R0, #0x10]

                MOV32 R0, #GPIOG
                LDR   R1, [R0, #0x14]
                EOR   R1, #0x6000
                STR   R1, [R0, #0x14]
                
                BX    LR

                ENDP

                ; Inicialisation Code

System_Init     PROC
                EXPORT    System_Init

                MOV32 R0, #HSEON              ; В R0 помещам адрес бита HSEON в bit band alias
                MOV   R1, #1
                STR   R1, [R0]                ; Запускаем внешний кварц, устанавливая бит HSEON

                MOV32 R0, #HSERDY
                MOV   R2, #0xFFFF
M1              LDR   R1, [R0]                ; Читаем бит HSERDY по адресу в bit band region
                CMP   R1, #0                  ; Проверяем флаг готовности
                BNE   M2                      ; Если бит установился, то HSE запущен, и идем дальше
                SUBS  R2, #1
                BNE   M1                      ; Пробуем еще раз
                B     System_fault            ; Если не запустился, то ошибка! Fuck!

M2              MOV32 R0, #RCC                ; PLLQ = 9, PLLSRC = от HSE, PLLP = 2 ('00'), PLLN = 360 ('5A'), PLLM = 16 ('10')
                MOV32 R1, 0x09405A10
                STR   R1, [R0, #RCC_PLLCFGR]

                MOV32 R1, 0x10000000
				STR   R1, [R0, #RCC_APB1ENR]
				
                MOV32 R0, #PLLON              ; Запускаю PLL
                MOV   R1, #1
                STR   R1, [R0]

                MOV32 R0, #ODEN               ; Разрешаю Over-drive режим
                MOV   R1, #1
                STR   R1, [R0]
				
;                MOV32 R0, #PWR                ; Разрешаю Over-drive режим
;                MOV32 R1, #0x00010000
;                STR   R1, [R0]				

                MOV32 R0, #ODRDY
M3              LDR   R1, [R0]
                CMP   R1, #0
                BEQ   M3

                MOV32 R0, #ODSWEN             ; Включаю Over-drive режим
                MOV   R1, #1
                STR   R1, [R0]

                MOV32 R0, #ODSWRDY
M4              LDR   R1, [R0]
                CMP   R1, #0
                BEQ   M4

                MOV32 R3, #0xFFFF
M5              MOV32 R0, #FLASH              ; Теперь настраиваем предвыборку Flash, т.к. планируем работать на 180 МГц
                MOV   R1, #0x0105
                STR   R1, [R0, #FLASH_ACR]    ; Включили буфер предвыборки и настроили на 5 циклов ожидания

M6              LDR   R2, [R0, #FLASH_ACR]    ; Проверяем записалось ли?
                CMP   R2, R1
                BEQ   M7
                SUBS  R3, #1
                BNE   M6
                B     M5

M7              MOV32 R0, #RCC
                MOV32 R1, #0xFF409400         ; SysClk = 180 МГц, AHBpre = 1, APB1pre = 4, APB2pre = 2, SYSCLCK от PLL
                STR   R1, [R0, #RCC_CFGR]     ; Сохраняем настройки в RCC_CFGR

                MOV32 R0, #PLLRDY
M8              LDR   R1, [R0]                ; читаем флаг готовности PLL
                CMP   R1, #0                  ; Проверяем флаг готовности
                BEQ   M8                      ; пока не установится в 1

                MOV32 R0, #SW1
                MOV   R1, #1
                STR   R1, [R0]                ; Выбираем тактовый сигнал Sysclk от PLL

                MOV32 R0, #SWS1               ; ожидаем пока Sysclck не переключится на PLL
M9              LDR   R1, [R0]                ; читаем флаг готовности SWS1
                CMP   R1, #0                  ; Проверяем флаг готовности
                BEQ   M9                      ; ждем пока не установится в 1

                MOV32 R0, #RCC
                MOV   R1, #0x40
                STR   R1, [R0, #RCC_AHB1ENR]

                MOV32 R0, #GPIOG
                MOV32 R1, #0x14000000           ; General purpose output mode
                STR   R1, [R0, #0]              ; GPIOx_MODER
                MOV32 R1, #0x00000000           ; Low speed
                STR   R1, [R0, #0x08]           ; GPIOx_OSPEEDR
                MOV32 R1, #0x14000000           ; Pull-up
                STR   R1, [R0, #0x0C]           ; GPIOx_PUPDR
                MOV32 R1, #0x00006000
                STR   R1, [R0, #0x18]           ; GPIOx_BSRR Установить биты 13-14 в порту G

                MOV32 R0, #RCC
				LDR   R1, [R0, #RCC_APB1ENR]
				ORR   R1, #0x04
                STR   R1, [R0, #RCC_APB1ENR]

                MOV32 R0, #TIM4
                MOV   R1, #0xAFC8
                STR   R1, [R0, #0x28]         ; TIMx_PSC
                MOV   R1, #0x07D0
                STR   R1, [R0, #0x2C]         ; TIMx_ARR
                MOV   R1, #0x0000
                STR   R1, [R0, #0x24]         ; TIMx_CNT
                MOV   R1, #0x0001
                STR   R1, [R0, #0x0C]         ; TIMx_DIER
                MOV   R1, #0x0085
                STR   R1, [R0]                ; TIMx_CR1

                MOV32 R0, #NVIC_Base
                MOV32 R1, #0x40000000
                STR   R1, [R0]
                
                CPSIE I

                MOV32 R3, #GPIOG



                BX    LR

System_fault    ; где-то здесь нужно что-то сделать
                ; дабы обработать отказ HSE

                B     .

                ENDP

                ; My Appication

Main            PROC
                EXPORT      Main

                LDR   R1, [R3, #0x14]
                EOR   R1, #0x6000
                STR   R1, [R3, #0x14]

B1              SUBS  R2, #1
				BNE   B1
				
				MOV32 R2, #0x0ABA9500

                B           Main
                ENDP



                END
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 274
Зарегистрирован: Пт мар 12, 2010 12:09:26
Откуда: Кемерово

Сообщение Andrew_KMR »

Вы что весь код на ассемблере пишите?
Реклама
Родился
Сообщения: 4
Зарегистрирован: Пт мар 28, 2014 06:51:19

Сообщение wypuk »

Andrew_KMR писал(а):Вы что весь код на ассемблере пишите?
Пока да, Си не знаю, а с ассемблером все просто.
Насчет моей проблемы, один человек сказал, что у него мой проект запускается и в обработчик прерывания вызывается нормально.
Может в настройках Keil выставил что не так?
Грызет канифоль
Аватара пользователя
Сообщения: 274
Зарегистрирован: Пт мар 12, 2010 12:09:26
Откуда: Кемерово

Сообщение Andrew_KMR »

По Keil честно не знаю, но в настройках Iar сложно сделать не рабочими прерывания, при условии успешной компиляции проекта и наличия подключаемых модулей.
Я бы посоветовал для инициализации перифирии и прерываний использовать библиотечные функции, а уже в критичных по времени участках кода писать на ассемблере.Так будет легче работать с перифирией, тот же USB, FSMC, DCMI…
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 4
Зарегистрирован: Пт мар 28, 2014 06:51:19

Сообщение wypuk »

В общем я выяснил, что программа все-таки попадает в обработчик. Поставил breakpoint в обработчике, запустил выполнение программы и оказался в обработчике.
Когда я работал на Pinboard II с stm32f103 и отлаживал через JTAG картина была другая: после переполнения сразу вылетало прерывание, и если в обработчике опять возникало переполнение
(т.к. таймер/периферия при отладке не останавливается и работает независимо от ядра), то после выхода из него обработчик вызывался повторно.
Как я понял с SWD как-то по другому... но как? Сейчас получается, что когда я пошагово отлаживаю программу обработчик не вызывается (а таймер как видно по регистру счета CNT так же не останавливается), и только если нажму "RUN" в него можно попасть.
Самое интересное, что прерывание вызывается не через строго одинаковые интервалы времени, а всегда по разному. Допустим задал я период счета 2 секунды, но судя по счетчику (на картинке) каждый раз прерывание может вызываться через разные интервалы времени.
С чем это может быть связано?
Изображение
Проект полностью: http://yadi.sk/d/t8Tt48ruLUCL2
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

wypuk,попробуй наконец-то выставить приоритет прерыванию...
Реклама
Родился
Сообщения: 4
Зарегистрирован: Пт мар 28, 2014 06:51:19

Сообщение wypuk »

dosikus писал(а):wypuk,попробуй наконец-то выставить приоритет прерыванию...
Какой в этом смысл? И если на то уж пошло, то у TIM4 уже по-умолчанию установлен насколько это возможно наивысший приоритет = 0!
Выше только у NMI, HardFault и т.п. И что с того? Может тогда уже всем остальным прерываниям понизить приоритет?
Тут по моему в другом дело, и связано это с отладчиком. Ядро тормозится отладчиком, а счетчик продолжает работать. Обработчик в останове не отрабатывает.
Возможно обработчик вызывается по фронту импульса, который генерируется событием переполнения. Но при установленном "pending" флаге он тоже по идее должен вызываться.
Жаль нет знатока, который бы это мог все объяснить.
Настроил в регистрах отладки, чтобы таймер останавливался вместе с ядром - тоже ставится этот "pending". И только нажав кнопку Run программа останавливается на брекпоинте в обработчике.
Ответить

Вернуться в «ARM»