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

Billys7
Солнце 01 апреля 2018 12:37
Привет. Я пытаюсь сделать внешнее прерывание со старым путем. Я программирую синюю таблетку от Arduino IDE, используя сериал.
Проект: прерывание, подключенное к PB12, изменит состояние встроенного светодиода.
Я прочитал справочное руководство и другие документы, я также ищу в Google, но я не смог найти подробную документацию. Я также пытался расшифровать библиотеки, но я не мог заставить работать следующий код.
Приглашается любая помощь.

volatile int state = LOW; volatile unsigned long x = 0; void setup() { Serial.begin(57600); RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPBEN); // Enable PB RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPCEN); // Enable PC 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) GPIOB->regs->CRH = 0x44484444; // Set input mode on PB12 P/U or P/D p158, p171 GPIOB->regs->ODR |= 0b0001000000000000; // Pull up on PB12 is enabled RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_AFIOEN); // Enable AFIO RCC_BASE->APB2RSTR |= (1 << RCC_APB2RSTR_AFIORST); asm volatile("cpsie i"); // Enable interrupts EXTI_BASE->FTSR |= (1 << 12); // Falling on 12 EXTI_BASE->RTSR |= (1 << 12); // Rising on 12 EXTI_BASE->IMR |= (1 << 12); // Interrupt mask register AFIO_BASE->EXTICR4 |= (1 << 0); // On PB12 NVIC_BASE->ISER[1] |= (1 << (NVIC_EXTI_15_10 & 0x1F)); // enable interrupt EXTI 10..15 } void loop() { digitalWrite(PC13, state); Serial.println(x); } void EXTI15_10_IRQHandler(void) { x++; state = !state; EXTI_BASE->PR |= (1 << 12); }

Стивестронг
Солнце 01, 2018 13:29
В Ядро Роджера прерывания объявлены в https: // github.com/rogerclarkmelbourne/ ... or_table.С
Таким образом, вы должны использовать одно и то же имя для необходимого ISR, как указано в этом файле.

Billys7
Солнце 01, 2018, 14:22
я сделал это. Я заменяю прерывание на
void __irq_exti2(void) //void blink() { x++; state = !state; EXTI_BASE->PR |= (1 << 12); }

Эдогальдо
Солнце 01, 2018, 15:54
extern "C" () { ... }

Олли
Солнце 01, 2018, 17:11
Нормальная практика для exti15_10_irqhandler состоит в том, чтобы иметь серию операторов IF, чтобы определить, какие из линий Exti (от 10 до 15) изгибаются. Если в «других» линии есть активные прерывания, то «ваша» линия может быть преждевременно очищена. С exti2 оператор if не требуется.

Billys7
Солнце 01, 2018, 21:28
Опять нет результата.
Он сбой, когда он входит в прерывание.

volatile int state = LOW; volatile unsigned long x = 0; void setup() { Serial.begin(57600); Serial.println("Start"); RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPBEN); RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPCEN); 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) GPIOB->regs->CRH = 0x44484444; // Set input mode on PB12 P/U or P/D p158, p171 GPIOB->regs->ODR |= 0b0001000000000000; // Pull up on PB12 is enabled RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_AFIOEN); RCC_BASE->APB2RSTR |= (1 << RCC_APB2RSTR_AFIORST); asm volatile("cpsie i"); EXTI_BASE->FTSR |= (1 << 12); EXTI_BASE->RTSR |= (1 << 12); EXTI_BASE->IMR |= (1 << 12); AFIO_BASE->EXTICR4 |= (1 << 0); NVIC_BASE->ISER[1] |= (1 << (NVIC_EXTI_15_10 & 0x1F));// enable interrupt EXTI 10..15 } void loop() { digitalWrite(PC13, state); Serial.println(x); } void __irq_exti15_10() { x++; state = !state; EXTI_BASE->PR |= (1 << 12); }

Стивестронг
Солнце 01, 2018, 21:51
Почему бы вам не использовать ядро ​​arduino_stm32 с Arduino IDE?
Какова ваша конечная цель, что вы хотите реализовать?

Billys7
Солнце 01, 2018, 21:53
[Эдогальдо - Солнце 01, 2018, 15:54] - extern "C" () { ... }

Billys7
Солнце 01, 2018, 22:04
[Стивестронг - Солнце 01, 2018, 21:51] - Почему бы вам не использовать ядро ​​arduino_stm32 с Arduino IDE?
Какова ваша конечная цель, что вы хотите реализовать?
Прежде всего, я хочу узнать все с самого начала.
Исходя из моего опыта (я не эксперт), используя библиотеки Arduino, делает выполнение медленнее. Использовать библиотеки Arduino очень просто, но иногда, если вы не знаете их ограничения, становится более сложным.

Billys7
Солнце 01, 2018, 22:04
Мне это нужно ?

Rcc_base->Apb2rstr | = (1 << RCC_APB2RSTR_AFIORST);

Стивестронг
Солнце 01, 2018, 22:26
Я не уверен, что скорость - это то, что вы получаете, особенно когда вы иногда добавляете «задержку (...); "
В конечном итоге вы сохраните немного вспышки, однако многое можно получить (128 КБ).
Ядро Libmaple позволяет использовать функции низкого уровня, которые действительно тонкие и оптимизированные скорости.

Но, конечно, наконец -то ваш выбор, как идти.
Для Libmaple Core вы, скорее всего, получите поддержку здесь.
Но не уверен, что вы получите поддержку для своего низкого уровня программирования.

Billys7
Пн, 02 апреля 2018 г., 7:52 утра
[Стивестронг - Солнце 01, 2018, 22:26] - Я не уверен, что скорость - это то, что вы получаете, особенно когда вы иногда добавляете «задержку (...); "
Код, который вы видели, - это просто тест для меня. Цель состоит в том, чтобы узнать, как работает внешнее прерывание.

Billys7
Вторник 03 апреля 2018 г. 14:04
Вот полный рабочий код: //Toggling the onboard led on PC13 after the occurred interrupt. //The interrupt occurred when you connect PB12 to the ground. volatile boolean led ; volatile unsigned long x ; void setup() { Serial.begin(250000); Serial.println("Start"); RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_IOPBEN); // Enable PB. p145 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) GPIOB->regs->CRH = 0x44484444; // Set input mode on PB12 P/U or P/D p158, p171 GPIOB->regs->ODR |= 0b0001000000000000; // Pull up on PB12 is enabled RCC_BASE->APB2ENR |= (1 << RCC_APB2ENR_AFIOEN); // Enable AFIO. p145 RCC_BASE->APB2RSTR |= (1 << RCC_APB2RSTR_AFIORST); // Reset the AFIO registers. p105 asm volatile("cpsie i"); // Enables interrupts and configurable fault handlers. p99 C EXTI_BASE->FTSR |= (1 << 12); // Falling on 12. p211 EXTI_BASE->IMR |= (1 << 12); // Interrupt mask register. p210 AFIO_BASE->EXTICR4 |= (1 << 0); // On PB12. p191 NVIC_BASE->IP[40] = 0 << 4; // Priority to set, 0 being highest priority and 15 being lowest. From the table NVIC_EXTI_15_10 = 40. Move it to the left 4 positions. p125 C EXTI_BASE->PR |= (1 << 12); // Clear pending interrupt on that pin. p212 NVIC_BASE->ISER[1] |= (1 << 8); // Enable interrupt EXTI 10..15. From the table NVIC_EXTI_15_10 = 40. p119 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 } extern "C" void __irq_exti15_10(void) { led = !led; // Reverse state EXTI_BASE->PR |= (1 << 12); // Clear pending interrupt on that pin. p212 x++; // Count the interrupts. Remember, never try and clear the flag that caused the interrupt as the last instruction in the ISR itself. It causes the ISR to reenter immediately. }

Олли
Вторник 03 апреля 2018 г., 17:24
Молодец Билли,

Я думаю, что все, кто приходит в этот бизнес/хобби, должны изучить основы так, как вы продемонстрировали. Большинство пользователей игнорируют руководства и пытаются использовать конструкции высокого уровня, которые скрывают основы. Затем, когда что -то не работает, будет трудно выяснить, что пошло не так. В этом анализе вы должны использовать отладчик низкого уровня и посмотреть биты в регистрах.

С другой стороны, как вы можете видеть, что программирование на уровне регистра очень трудно прочитать. Лично я оставил этот стиль, заменил его Cubemx и не сожалею. Самая большая выгода заключается в том, что теперь есть широкая аудитория, которая может свободно читать мой код - даже без комментариев.

Ура, Олли

Modbus Master and Slave на STM32F103 и Uno

Выполнить из внешнего SRAM