Я новичок в создании проектов с нуля с помощью mcu. Я взял старый файл проекта, который успешно работает в среде сборки eclipse/gdb, где IDE делает всю сборку за меня, и попытался реализовать свою собственную сборку с помощью open-ocd и цепочки инструментов: arm-none-eabi. Мне удалось прошить устройство, однако плата не запускает код. Я надеялся, что у меня может отсутствовать какой-то очевидный важный файл, но я не пришел к такому выводу.
Меня больше всего беспокоит то, что у меня нет надлежащих настроек для моего файла start_up.c или файла linker.ld, хотя я не нашел причин так полагать. Я использую плату обнаружения stm32L476. Вот ссылка на техпаспорт, если кому интересно: https://www.st.com/resource/en/reference_manual/dm00083560-stm32l47xxx-stm32l48xxx-stm32l49xxx-and-stm32l4axxx-advanced-armbased-32bit-mcus -stmicroelectronics.pdf
Исходники моей проблемы здесь, на github: https://github.com/landonbr/stm32-fun
Я настоятельно рекомендую вам не использовать C для начальной загрузки C. И настоятельно рекомендую не использовать структуры между доменами компиляции.
• 96 Кбайт отображаются по адресу 0x2000 0000 (SRAM1) • 32 Кбайта по адресу 0x1000 0000 с аппаратной проверкой четности (SRAM2).
На устройствах STM32L49x/L4Ax SRAM2 имеет псевдоним по адресу 0x2004 0000, предлагая непрерывное адресное пространство с SRAM1.
Это STM32L47 да? Так что это не относится.
08000000 <vector>:
8000000: 20020000 andcs r0, r2, r0
8000004: 0800043b stmdaeq r0, {r0, r1, r3, r4, r5, r10}
8000008: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
800000c: 08000435 stmdaeq r0, {r0, r2, r4, r5, r10}
0x200000 = 128 Кбайт. Попробуйте что-нибудь маленькое, просто для начала 0x20001000. Или перейти на 96K. 0x20018000
Он не сломан (ну, это может зависеть от регистра и поля), но чище делать чтение-изменение-запись отдельно от регистра, чтобы регистр переходил только из одного режима в другой, а не дважды переключал режимы.
GPIOB->MODER &= ~(3UL<<4); // Clear mode bits
GPIOB->MODER |= 1UL<<4; // Set mode to output
tmp = GPIOB->MODER
tmp &= ~(3UL<<4); // Clear mode bits
tmp |= 1UL<<4; // Set mode to output
GPIOB->MODER = tmp
Может быть хорошей идеей делать что-то одно за раз. Либо просто включите светодиод, либо мигните светодиодом, используя задержку на основе счетчика (это не мертвый код). Затем позже возитесь с кнопками или таймерами или чем-то еще.
Взгляните на регистр gpio BSRR вместо ODR. Облегчает жизнь.
Это мертвый код,
if (Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
for(int i=125000; i!=0; i--){}
GPIOE->ODR |= (1UL << 8);
for (int i=125000; i!=0; i--){}
}
Он компилируется в это в основном
if (Upush%2!=0){
GPIOE->ODR &= ~(1UL << 8);
GPIOE->ODR |= (1UL << 8);
}
Что слишком быстро, чтобы увидеть без прицела. И вы не можете точно определить время в цикле, поэтому оно не равно 2 Гц.
В вашем случае вы не оптимизировали, чтобы цикл был там, по крайней мере, с gnu, который я использую.
Конечно, вы должны начать с этого:
while(1){
GPIOE->BSRR = 1<<(8+16);
for(volatile int i=125000; i!=0; i--){}
GPIOE->BSRR = 1<<(8+ 0);
for (volatile int i=125000; i!=0; i--){}
}
как ваша основная программа после инициализации этого контакта gpio. Без каких-либо кнопок джойстика. Заставьте это работать и убедитесь, что ваш основной скелет хорош, а затем добавляйте к нему что-то. (кнопки заметок сложны / болезненны, так как вы часто хотите их устранить. Скорее всего, не в этом случае, а в целом)
Никто не хочет лезть в ваш гитхаб, чтобы ответить на вопрос. Разместите соответствующий код прямо здесь.