Довольно бесполезно, что ссылка для скачивания руководства пользователя Nucleo F429ZI UM1974 по адресу https://www.st.com/en/evaluation-tools/nucleo-f429zi.html#resource, похоже, не работает (на момент написания), но я нашел копию в другом месте и назначение выводов:три пользовательских светодиода описаны следующим образом:
Схема предполагает, что заводское состояние паяных мостов SB120 и SB119 установлено для LD1 на PB0, а не назатем PA5.Проблема с вашей попыткой установить LD2 (синий) заключается в том, что вы не включили GPIOB в RCC - он включает GPIOA, как при попытке LD1 (зеленый).
Другая проблема заключается в том, что при настройке GPIO MODER предполагается, что состояние сброса для порта равно нулю.Это не так (хотя это касается конкретных пинов, о которых идет речь - поэтому вы «сойдете с рук» * в этом случае ):
Хорошая идея определить все константы портов / выводов в одном месте, чтобы вы могли легко переключать или добавлять выходы и с меньшей вероятностью ошибки:
#define LED_PORT GPIOB
#define LED_PORT_RCC_EN 0x2u
#define GPIO_MODE_MASK ~0x3u
#define GPIO_MODE_OUTPUT 0x1u
#define GREEN_LED_PIN 0u
#define BLUE_LED_PIN 7u
#define RED_LED_PIN 14u
#define FLASH_LED GREEN_LED_PIN
int main(void)
{
RCC->AHB1ENR |= LED_PORT_RCC_EN ;
LED_PORT->MODER &= GPIO_MODE_MASK << (FLASH_LED << 1) ;
LED_PORT->MODER |= GPIO_MODE_OUTPUT << (FLASH_LED << 1) ;
for(;;)
{
LED_PORT->ODR |= 0x1 << FLASH_LED ;
delayMs( 100 ) ;
LED_PORT->ODR &= ~(0x1 << FLASH_LED) ;
delayMs( 100 ) ;
}
return 0 ;
}
Ваша функция задержкисерьезно испорчен, и, вероятно, будет оптимизирован, чтобы "ничего не делать".Ваш счетчик цикла должен быть объявлен энергозависимым, чтобы избежать его оптимизации.Если это произойдет, индикатор не будет заметно мигать, но будет пульсировать с очень высокой частотой и включаться, но не на полной яркости.
Следующее действие не позволит оптимизировать петли.
void delayMs( unsigned delay )
{
for( volatile unsigned d = delay; d > 0; d--)
{
for( volatile int i = 0; i < 3195; i++ )
{
}
}
}
Однако это часть с частотой 180 МГц;если вы используете его на полной скорости 3195 итераций, это, вероятно, не займет 1 мс.Больше похоже на несколько десятков микросекунд.Даже если он работает на частоте запуска HSI 16 МГц, он может составлять порядка нескольких сотен микросекунд и в любом случае будет зависеть от настроек оптимизации и времени, затрачиваемого на работу любых обработчиков прерываний.Гораздо лучше использовать счетчик Cortex-M SYSTICK следующим образом:
static volatile uint32_t ms_tick = 0 ;
void SysTick_Init(void)
{
SysTick_Config( SystemCoreClock / 1000 ) ;
}
void SysTick_Handler(void)
{
ms_tick++;
}
void delayMs( uint32_t delay)
{
uint32_t start_tick = ms_tick ;
while( (ms_tick - start_tick) < delay );
}
Тогда задержка будет точной независимо от тактовой частоты, на которой вы запускаете процессор, или от прерывания нагрузки.