Timer 2 прерывание с использованием программирования низкого уровня

Billys7
Чт, 05 апреля 2018 г., 22:28
Я что -то скучаю? //Toggling the onboard led on PC13 every 1 sec. volatile boolean led ; volatile unsigned long x ; void setup() { Serial.begin(250000); Serial.println("Start"); RCC_BASE->APB1ENR |= (1 << RCC_APB1ENR_TIM2EN); // Enable Timer2. p147 RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPCEN); // Enable PC. p145 GPIOC->regs->CRH = GPIOC->regs->CRH | 0x00300000; // Set output mode on PC13 @ max freq 50MHz (MODE13[1:0] = 11) p158, p171 GPIOC->regs->CRH = GPIOC->regs->CRH & 0xFF3FFFFF; // Set output mode on PC13 as general push-pull output (cnf8[1:0] = 00) asm volatile("cpsie i"); // Enables interrupts and configurable fault handlers. p99 C TIMER2_BASE->CR1 = 0; TIMER2_BASE->CR2 = 0; TIMER2_BASE->SMCR = 0; TIMER2_BASE->DIER = 0; TIMER2_BASE->SR= 0; TIMER2_BASE->EGR= 0; TIMER2_BASE->CCMR1= 0; TIMER2_BASE->CCMR2= 0; TIMER2_BASE->CCER= 0; TIMER2_BASE->CNT= 0; TIMER2_BASE->PSC= 0; TIMER2_BASE->ARR = 65535; TIMER2_BASE->CCR1= 0; TIMER2_BASE->CCR2= 0; TIMER2_BASE->CCR3= 0; TIMER2_BASE->CCR4= 0; TIMER2_BASE->DCR= 0; TIMER2_BASE->DMAR= 0; TIMER2_BASE->PSC = 23999; // Set prescaler to 24.000 (PSC + 1) Means 72.000.000 / 24.000 = 3.000 per second. p417 TIMER2_BASE->ARR = 3000; // Auto reload value 3000. The update event is sent when the counter reaches the overflow. p418 TIMER2_BASE->DIER |= (1 << 0); // Enable update interrupt TIM_DIER_UIE = 1 . p408 TIMER2_BASE->CR1 |= (1 << 0); // Enable timer TIM_CR1_CEN = 1 . p403 NVIC_BASE->IP[28] = 15<< 4; // Set Priority, 0 = highest, 15 = lowest. From the table on page 197 TIM2 = 28. Move it to the left 4 positions. p125 C TIMER2_BASE->SR &= ~(1 << 0); // clear pending interrupt UIF flag TIM_SR_UIF=0. p409 NVIC_BASE->ISER[0]|= (1 << 28); // Enable interrupt TIM2. From page 197 on the table TIM2 = 28. ISER = 0. p119 C & p120 C. } void loop() { GPIOC->regs->BSRR |= (1 << (13 + (led * 16))); // Lower 16 bits setting while higher bits clearing. p172 Serial.println(x); // Show me how many interrupts has occurred }

Эдогальдо
Пт 06 апреля 2018 г. 5:09
Короткий ответ заключается в том, что вы не можете переопределить IRQ, уже определенные в ядре.
В этих случаях вы должны использовать крючки Attachinterrup.

В прошлом было несколько тем, вы можете искать «слабые» и «прерывание» для получения дополнительной информации.

Ура, e.

Billys7
Пт 06 апреля 2018 г. 11:06 утра
Честно говоря, я читаю их, перед публикацией, но я действительно не мог их понять.
Я знаю о несовместимости прерываний C и C ++, но я не мог понять, почему мне нужно использовать только команду AttactInterrup.

Эдогальдо
Пт 06 апреля 2018 г. 11:58 утра
Когда вы используете ядро, вы полагаетесь на рамки, которая предлагает вам некоторые преимущества, но также вызывает некоторые ограничения.
Ядро Libmaple уже реализует несколько обработчиков прерываний и предлагает вам основу для привязки вашего кода, который основан на крючках "AttactIntert".
Рассмотрим это: у вас уже есть __irq_tim2 () здесь; Если вы переопределяете __irq_tim2 () в своем эскизе, то вы получите 2 определения для него, а затем линкер жалуется, потому что он не знает, какой из них использовать..
Чтобы иметь возможность использовать свое определение, вы должны удалить основное.
В любом случае, учитывайте, что подход AttachInterrup также выполняет некоторые другие задачи (например, включение прерывания), необходимых для правильной настройки управления прерыванием; Если вы решите обойти его, вы должны позаботиться также о других вещах.

Надеюсь, это немного лучше..

Ура, e.

Billys7
Пт 06 апреля 2018 г., 15:00
Спасибо, Эдогальдо.
Это работает нормально.

Кибермир
Пн, 09 апреля 2018 г. 8:47
Привет, Биллис7

Вы можете опубликовать свой рабочий код. Меня интересует этот тип вещей.

Спасибо.

Дэнниф
Пн, 09 апреля 2018 г., 10:15
не Billys7, но вы можете найти здесь различные кодовые детали:

F0: https: // github.com/dannyf00/my-mcu-libr ... ER/STM32F0
F1: https: // github.com/dannyf00/my-mcu-libr ... /Stm32f1xx
F4: https: // github.com/dannyf00/my-mcu-libr ... ER/STM32F4

Billys7
Пн, 09 апреля 2018 г., 14:55
Вот рабочий код.
// Toggling the onboard led on PC13 every 1 sec. // I must exempt - delete the corresponding timer from STM32F1/cores/maple/libmaple/timer.c // For this example the corresponding timer is described on lines 506 to 508 of timer.c. volatile boolean led =0; volatile unsigned long x ; void setup() { Serial.begin(57600); Serial.println("Start"); RCC_BASE->APB1ENR |= (1 << RCC_APB1ENR_TIM2EN); // Enable Timer2. p147 RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPCEN); // Enable PC. p145 GPIOC->regs->CRH = GPIOC->regs->CRH | 0x00300000; // Set output mode on PC13 @ max freq 50MHz (MODE13[1:0] = 11) p158, p171 GPIOC->regs->CRH = GPIOC->regs->CRH & 0xFF3FFFFF; // Set output mode on PC13 as general push-pull output (cnf8[1:0] = 00) asm volatile("cpsie i"); // Enables interrupts and configurable fault handlers. p99 C /* Reset all the registers */ TIMER2_BASE->CR1 = 0; TIMER2_BASE->CR2 = 0; TIMER2_BASE->SMCR = 0; TIMER2_BASE->DIER = 0; TIMER2_BASE->SR= 0; TIMER2_BASE->EGR= 0; TIMER2_BASE->CCMR1= 0; TIMER2_BASE->CCMR2= 0; TIMER2_BASE->CCER= 0; TIMER2_BASE->CNT= 0; TIMER2_BASE->PSC= 0; TIMER2_BASE->ARR = 65535; TIMER2_BASE->CCR1= 0; TIMER2_BASE->CCR2= 0; TIMER2_BASE->CCR3= 0; TIMER2_BASE->CCR4= 0; TIMER2_BASE->DCR= 0; TIMER2_BASE->DMAR= 0; TIMER2_BASE->PSC = 23999; // Set prescaler to 24.000 (PSC + 1) Means 72.000.000 / 24.000 = 3.000 counts per second. p417 TIMER2_BASE->ARR = 3000; // Auto reload value 3000. The update event is sent when the counter reaches the overflow. p418 TIMER2_BASE->DIER |= (1 << 0); // Enable update interrupt TIM_DIER_UIE = 1 (timer level). p408 TIMER2_BASE->CR1 |= (1 << 0); // TIM_CR1_CEN = 1 Enable timer. p403 NVIC_BASE->IP[28] = 15<< 4; // Set Priority, 0 = highest, 15 = lowest. From the table on page 197 TIM2 = 28. Move it to the left 4 positions. p125 C TIMER2_BASE->SR &= ~(1 << 0); // clear pending interrupt UIF flag TIM_SR_UIF=0. p409 NVIC_BASE->ISER[0]|= (1 << 28); // Enable interrupt TIM2. From page 197 on the table TIM2 = 28. ISER = 0. p119 C & p120 C. } void loop() { GPIOC->regs->BSRR |= (1 << (13 + (led * 16))); // Lower 16 bits setting while higher bits clearing. p172 Serial.println(x); Serial.println(led); // Show me how many interrupts has occurred } extern "C" void __irq_tim2(void) // https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F1/cores/maple/libmaple/stm32f1/performance/vector_table.S { /* Remember, never try to clear the pending interrupt flag as the last instruction in the ISR itself. It causes the ISR to reenter immediately.*/ led = !led; // Reverse state TIMER2_BASE->SR &= ~(1 << 0); // clear pending interrupt UIF flag TIM_SR_UIF=0. p409 x++; // Count the interrupts }

Кибермир
Ср 11 апреля 2018 г., 6:25
Спасибо Billys7.

Эдогальдо
Ср 11 апреля 2018 г., 7:33 утра
[Billys7 - Пт. 06 апреля 2018 г., 15:00] - Спасибо, Эдогальдо.
Это работает нормально.
@Billys7: Может быть эта ветка: Здесь я предложил возможное изменение ядра, чтобы разрешить переопределение любого IRQ без необходимости удалять те, которые определены в ядре; Я проверил изменение и внедрил его для всех основных IRQ в моем личном варианте, без проблем (до сих пор) в любом случае, основные сопровождающие не считали, что это стоит возможных рисков.

Надеюсь, это поможет.

Лучший, e.

Billys7
Пн, 16 апреля 2018 г. 8:44
Привет, Эдогальдо,

Я не знаком с «слабым» определением.
Вы можете мне объяснить, что вы сделали?

Эдогальдо
Пн, 16 апреля 2018 г., 9:11 утра
https: // en.Википедия.org/wiki/sleed_symbol

То, что я предложил, - это метод помечения основного IRQ как «слабых», чтобы они могли быть переопределены с «сильным» определением, указанным в эскизе (если Desided).
Таким образом, можно либо определить его собственную реализацию IRQ, либо использовать ядро ​​по умолчанию как предпочтительный без конфликтов (это позволило бы избежать необходимости удалить основной IRQ, как вы это сделали).

В потоке я предложил решение для irq "__irq_usart1 ()", но это может применить к любому IRQ..


Ура, e.

Rogerclark
Пн, 16 апреля 2018 г., 21:18
Есть ли пиар для этого, так как он вызывающе имеет заслуги

Эдогальдо
Вт 17 апреля 2018 г. 7:41
Привет, Роджер, рад прочитать, что это может быть интересно.
В этот пост Я объясняю подход.
Поскольку вы предпочитаете, я могу предоставить либо PR «Большой взрыв» (для всех IRQ), либо пробный, с некоторыми IRQ, чтобы вы могли проверить и подтвердить, что все в порядке, все в порядке.
дайте мне знать.

Лучший, e.

Rogerclark
Вт 17 апреля 2018 г. 8:07
Может сделать их все за один раз

Эдогальдо
Вт 17 апреля 2018 г. 11:52 утра
[Rogerclark - Пн, 16 апреля 2018 г., 21:18] - Есть ли пиар для этого, как это вызывающе имеет заслуги
Кстати, надеюсь, это было "определенно".. :)

Rogerclark
Вт 17 апреля 2018 г., 21:29
Aargghhh

Я ненавижу авторитетно на телефонах и планшетах.