Страница 1 из 2
KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 13:34:14
Николай Relsart
Доброго времени суток!
Может быть кто знает, в чем может быть затыка.
Камешек STM32F103C8T6. Собираю проект с нуля в Keil5. Структуры проекта собрана. Подключены файлы CMSIS библиотеки. Добавлен Startup для данной модели.
Пути к инклудам прописаны. Настройки компилятора, линкера в "Options for Target..." и прочего- аналогичны тем, что в проектах, созданных Кубом. Оптимизация отключена.
Тактирование, проты ввода-вывода, прерывания-все как положено...
Все собирается без ошибок и заливается в МК. Код, написанный в Main-е работает (светодиодом управляю, кнопки читаю и т.п.). Во только не работают обработчики прерываний! Пробовал писать их и в main.c, и в отдельном файле.
Если запускаю кубовский проект в отладку, точка выполнения встает в начало функции Main(), что логично.
А вот в новом- точка выполнения застревает где-то в ассемблеровском startup-е, на строке "LDR R0, =SystemInit".
Затем наблюдаются необъяснимые чудеса. Если в запущенном режиме Debug запустить выполнение кода (F5)- обработчики начинают жить (я для простоты сделал моргание светодиодом на борту платы по прерыванию таймера1).
Отключаю режим отладки, жму Reset- все затыкается и не работает.
Платы пробовал разные- bluepill, STM323 Smart.
Причем есть пара проектов собранных ранее с нуля- там прерывания чудесным образом работают (хотя раньше не работали и не понятно, по какому тычку они завелись).
Все библиотеки в них- одни и те же, стартап тот же.
Очень хотелось бы найти эту загадочную настройку, из за которой то работает то нет, ведь с Кубовскими проектами таких чудес не возникает.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 13:40:56
КРАМ
Вопросов к вам собственно два:
1. Что является ИСТОЧНИКОМ прерываний?
2. Вы ничего не сказали о РАЗРЕШЕНИЯХ конкретных векторов в NVIC.
Приведите код который формирует условия генерации прерываний и собственно сами обработчики. Весь код приводить не надо.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 13:56:49
Николай Relsart
Источник прерываний: таймер1 (прерывание TIM1_UP_IRQn):
Код: Выделить всё
void TimerConfig (void)
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Тактиррование таймера от APB2
TIM1->SMCR &=~TIM_SMCR_SMS; // Внутреннее тактирование таймера 1
TIM1->CR1=TIM_CR1_CEN; // Режим работы таймера
TIM1->PSC=500; // Прескалер. Частота импульсов 0,1мс (10 кГц)
TIM1->ARR=9999; // Регистр перезагрузки. Будет раз в секунду.
TIM1->DIER |= TIM_DIER_UIE; // Разрешили прерывания по перезагрузке
}
Разрешение в main():
Код: Выделить всё
NVIC_EnableIRQ(TIM1_UP_IRQn); // Разрешили прерывания в контроллере
Обработчик в Interrupt_handler.c:
Код: Выделить всё
void TIM1_UP_IRQHandler ()
{
TIM1->SR &= ~TIM_SR_UIF; // Сняли флаг сработки
if ((GPIOC->IDR & GPIO_IDR_IDR13)==0) // Моргаем светодиодом
GPIOC->ODR |=1<<13;
else
GPIOC->ODR &=~(1<<13);
}
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 14:04:26
Reflector
[uquote="Николай Relsart",url="/forum/viewtopic.php?p=4110466#p4110466"]Причем есть пара проектов собранных ранее с нуля- там прерывания чудесным образом работают (хотя раньше не работали и не понятно, по какому тычку они завелись).
Все библиотеки в них- одни и те же, стартап тот же.

[/uquote]
Берешь и сравниваешь текстовые файлы с конфигами из рабочего и нерабочего проекта, сам так пару раз делал...
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 14:08:09
КРАМ
Неплохо привести код мэйна связанный с вызовом инициализации таймера.
Ну и в инициализации куртуазно запускать таймер ПОСЛЕ того, как он инициализирован.
Это я к тому, что
TIM1->CR1=TIM_CR1_CEN; // Режим работы таймера
никакой не режим, а тупо его запуск.
ЗЫ. Ну и отладчик на этот случай есть. Останавливаете его и смотрите что с таймером и флагами.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 14:16:54
Николай Relsart
Собственно Main.c:
Спойлер
Код: Выделить всё
#include "main.h"
void GPIO_Config(void);
void SystemClockConfig (void);
void TimerConfig (void);
int main(void)
{
SystemClockConfig();
GPIO_Config();
TimerConfig();
while(1)
{ }
}
void GPIO_Config()
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // включили тактирование портов A-D
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13); // CNF 0b00 MODE 0b10
GPIOC->CRH |= (0b10 << GPIO_CRH_MODE13_Pos); // PC13- активный выход
}
void SystemClockConfig (void)
{
RCC->CR |= (1<<RCC_CR_HSEON_Pos); // Запуск внешнего генератора
while (!(RCC->CR & (1<<RCC_CR_HSERDY_Pos))){} // Ждем запуска генератора...
RCC->CFGR |= (0x07<<RCC_CFGR_PLLMULL_Pos)|(0x01<<RCC_CFGR_PLLSRC_Pos); // Тактирование PLL от HSE, множитель =9
RCC->CR |= (1<<RCC_CR_PLLON_Pos); // Запуск PLL
while (!(RCC->CR & (1<<RCC_CR_PLLRDY_Pos))){} // Ждем запуска PLL...
FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos); // 2 цкла ожидания для FLASH
//Делители:
RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos)|(0x04<<RCC_CFGR_PPRE1_Pos)|(0x00<<RCC_CFGR_HPRE_Pos);
RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos); // Переключаемся на работу от PLL
// Ждем окончания переключения:
while ((RCC->CFGR & RCC_CFGR_SWS_Msk)!=(0x02<<RCC_CFGR_SWS_Pos)){}
RCC->CR &= ~(1<<RCC_CR_HSION_Pos); // Отключаем HSI
}
void TimerConfig (void)
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Тактиррование таймера от APB2
TIM1->SMCR &=~TIM_SMCR_SMS; // Внутреннее тактирование таймера 1
TIM1->PSC=500; // Прескалер. Частота импульсов 0,1мс (10 кГц)
TIM1->ARR=9999; // Регистр перезагрузки. Будет раз в секунду.
TIM1->DIER |= TIM_DIER_UIE; // Разрешили прерывания по перезагрузке
NVIC_EnableIRQ(TIM1_UP_IRQn); // Разрешили прерывания в контроллере
TIM1->CR1=TIM_CR1_CEN; // Режим работы таймера
}
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 14:25:59
КРАМ
А с отладчиком чего видно?
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 14:37:10
Николай Relsart
При переходе в отладчик:
И вот если в отладке жамкнуть F5- прерывания работать будут (светодиод замигает).
Отключить отладчика и нажать Reset- не будут

Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 15:52:41
КРАМ
Шозабред?
В брейкпойнт в прерывании заходит?
И почему main файл именован для плюсов? У вас проект на Си или на плюсах?
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 15:59:00
Reflector
Кстати, да. На словах в проекте Main.c, а на картинке main.cpp, для плюсов нужно обработчикам прерываний extern "C" добавлять, за исключением случаев когда стартап тоже на плюсах.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 16:04:19
Николай Relsart
Я имею ввиду что если запустить программу кнопкой Run, находясь в отладчике, то в прерывания заходить будет.
Этот проект с плюсами (экспериментировал), но пробовал и с простым Си, то же самое.
В плане Си или плюсов- я экспериментировал с Кубовскими проектами- менял main.c на main.cpp, stm32f1xx_it.c на stm32f1xx_it.cpp, и все работало как часы. Прямо из обработчика прерывания по таймеру вызывался метод класса без проблем.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 17:52:28
КРАМ
[uquote="Николай Relsart",url="/forum/viewtopic.php?p=4110573#p4110573"]если запустить программу кнопкой Run[/uquote]
А переставьте мигания в основной цикл. Есть смутные подозрения...
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 18:27:17
Николай Relsart
Вот ведь! Та же история!
Выключил прерывания, убрал обработчик и сделал такую до безобразия простую вещь:
Код: Выделить всё
int main(void)
{
SystemClockConfig();
GPIO_Config();
int Delay_Counter=500000;
while(1)
{
Delay_Counter-=1;
if (Delay_Counter==0)
{
if ((GPIOC->IDR & GPIO_IDR_IDR13)==0) // Моргаем светодиодом
GPIOC->ODR |=1<<13;
else
GPIOC->ODR &=~(1<<13);
Delay_Counter=500000;
}
}
}
И запускается только в отладке в Run-е. Поделитесь подозрениями, в какую сторону копать

Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 18:32:17
КРАМ
Ну наверное МК не стартует...
Схемку предъявите пожалуйста...
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 18:47:57
AndTer
А МК есть другой?
Китайцы шлют нередко перемарк и отбраковку.
Бывали уже случаи с непонятными глюками которые пропадали со сменой самого МК.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Вс окт 24, 2021 19:43:16
Николай Relsart
Тоже было подозрение, но пробовал на двух платах: самая обычная BluePill китайская за 200р и чуть подороже STM32 Smart. У обеих STM32F103С8T6 на борту. Схема.. так кроме питания 5В и собственно программатора ничего и не подключаю. У таблетки копеечный программатор-свисток, у Smart- ST-Link/V2. И там и там картина одна. И вопрос то остаётся- почему Кубовские проекты встают без всяких косяков, и работают без сбоев. Есть подозрения на сам Кейл, что он в памяти саму программу как-то криво размещает. Вот я и подумал, что может какую-то конфигу не делаю, адресацию где-нибудь не задаю и т.п. Но окно "Options for Target..." излажено вдоль и поперек, и каких-либо отличий не нашел

Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Ср янв 12, 2022 09:26:28
Николай Relsart
Нашел странную закономерность- все вышеуказанные косяки проявляются при отключенной оптимизации (О0). Если включить любой уровень О1, О3 и т.п. - все работает и в отладке и непосредственно на МК. Проверил на разных компах и разных кристаллах
Глюк Кейла?

Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Ср янв 12, 2022 18:07:36
a797945
Дайте периферии хоть пару тактов после включения, перед тем как заполнять ее регистры.
Например, вынестите включение всей периферии вперед, а регистры начните заполнять с той, какую включили первой.
... не внимательно посмотрел, кажется дело не в этом.
... где-то в ассемблеровском startup-е, на строке "LDR R0, =SystemInit"..."
это обращение в system_stm32f10x.c - делает примерно тоже ч то вы в СистемКлок
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Ср янв 12, 2022 20:44:07
Professor Chaos
Николай Relsart писал(а):А вот в новом- точка выполнения застревает где-то в ассемблеровском startup-е, на строке "LDR R0, =SystemInit".
Наверное, затык возникает позже, уже после входа в SystemInit. Поставьте точку останова внутри функции SystemInit и пройдите её по-шагам, чтобы понять, где именно в ней происходит затык (скорее всего это событие HardFault). Кстати, поставьте точку останова внутри HardFaultHandler, чтобы убедиться (или наоборот), что в момент зависания вашей программы МК заходит туда. А там можно и по регистру отказов посмотреть причину.
Re: KEIL. Нулевой проект- на работают прерывания.
Добавлено: Ср янв 12, 2022 21:25:08
a797945
у меня отладчик проваливается на СистемИнит в файл system_stm32f10x.c и ждет пинка на первой его процедуре.
А унего в стартапе останавливается. Startupповский файл у меня на _md_vl.s заканчивается