2020-08-18 10:24 AM
Hi
So here's the thing: I've been getting familiar with flashing the STM32F407 discovery board using the in-build bootloader via USART3. Boot mode is set to System memory using
Boot0 = 1 (5V)
Boot1 = 0 (GND)
I am using an USB to serial converter. Connection is:
USB_serial_TX (Green wire) <=> MCU_RX (PC11)
USB_serial_RX (White wire) <=> MCU_TX (PC10)
When using the bootloader to upload a program to control an LCD via I2C, I get the expected result. However, when trying to run a simple GP timer to control an LED, the LED does not blink.
The code itself works, because when using the on-board STLink programmer, the LED blinks. Just with the bootloader, it does not. Any ideas? Thank you.
#include "stm32f4xx.h"
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
void funcISRInit();
void funcGPIOInit();
void funcTIM4Init();
int main(void)
{
funcISRInit();
funcGPIOInit();
funcTIM4Init();
for(;;);
}
void funcISRInit()
{
// Enable interrupt for TIM4
__NVIC_EnableIRQ(TIM4_IRQn);
}
void funcGPIOInit()
{
RCC->AHB1ENR |= (1<<RCC_AHB1ENR_GPIODEN_Pos); // Enables AHB1 to communicate with GPIOD
GPIOD->MODER &= ~(2<<GPIO_MODER_MODER15_Pos); // PD15 as output [01]
GPIOD->OTYPER &= ~(1<<GPIO_OTYPER_OT15_Pos); // Push pull
GPIOD->OSPEEDR &= ~(3<<GPIO_OSPEEDR_OSPEED15_Pos); // Sets speed on PD12 to low
}
void funcTIM4Init()
{
// Sets PD12 to TIM4
RCC->AHB1ENR |= (1<<RCC_AHB1ENR_GPIODEN_Pos); // Enables AHB1 to communicate with GPIOD
GPIOD->MODER |= (2<<GPIO_MODER_MODER12_Pos); // Sets PD12 as Alternate function
GPIOD->AFR[1] |= (2<<GPIO_AFRL_AFSEL4_Pos); // Sets PD12 to AF2 [0010]
// Use PD12 to toggle LED in PWM mode. Use alternate function and TIM4
RCC->APB1ENR |= (1<<RCC_APB1ENR_TIM4EN_Pos); // Enables TIM4 on APB1 bus
TIM4->CR1 |= (1<<TIM_CR1_CEN_Pos); // CEN: Counter enabled
TIM4->CR1 &= ~(1<<TIM_CR1_UDIS_Pos); // UDIS: Update event enabled
TIM4->CR1 &= ~(1<<TIM_CR1_URS_Pos); // URS: Update request source enabled
TIM4->CR1 &= ~(1<<TIM_CR1_OPM_Pos); // OPM: One pulse mode disabled
TIM4->CR1 &= ~(1<<TIM_CR1_DIR_Pos); // DIR: Up count
TIM4->CR1 &= ~(3<<TIM_CR1_CMS_Pos); // CMS: Edge aligned mode enabled
TIM4->CR1 &= ~(1<<TIM_CR1_ARPE_Pos); // ARPE: Auto reload register not buffered
TIM4->CR1 &= ~(3<<TIM_CR1_CKD_Pos); // CKD: Clock division and digital filters set to tdts=tck
TIM4->CR2 &= ~(1<<TIM_CR1_CKD_Pos); // TIM4_CH1 is connected to TI1 input
TIM4->DIER |= (1<<TIM_DIER_UIE_Pos); // UIE: Update interrupt enabled
TIM4->EGR |= (1<<TIM_EGR_UG_Pos); // UG: Update generation enabled
TIM4->SMCR |= (1<<6); // TI1F trigger selection
TIM4->CCMR1 &= ~(3<<TIM_CCMR1_CC1S_Pos); // CC1S: CC1 set as output
TIM4->CCMR1 |= (2<<TIM_CCMR1_OC1FE_Pos); // Preload register enabled
TIM4->CCMR1 |= (6<<TIM_CCMR1_OC1M_Pos); // OC1M: PWM1 mode [6:4] 110
TIM4->CCER |= (1<<TIM_CCER_CC1E_Pos); // CC1E: Capture compare 1 output enable
TIM4->CCER &= ~(1<<TIM_CCER_CC1P_Pos); // CC1P: Active high
TIM4->CCER &= ~(1<<TIM_CCER_CC1NP_Pos); // CC1NP: Cleared because CC1 channel is set to output
TIM4->PSC = 0xF9FF; // Sets prescaler to 63999. Timer clock is now 16MHz/(63999+1)=250Hz
TIM4->ARR = 0x00F9; // Counter goes up to 249 to have a 1s timer
TIM4->CCR1 = 0x007D; // Sets compare match to half of ARR: 50% duty cycle
}
void TIM4_IRQHandler()
{
TIM4->SR &= ~(1<<0); // Clears UIF bit
// Handles the IRQ of TIM4
// Toggle LED on PD15
static uint8_t check = 1;
if(check)
{
GPIOD->BSRR |= (1<<15);
check = 0;
}
else
{
GPIOD->BSRR |= (1<<31);
check = 1;
}
}
Solved! Go to Solution.
2020-08-18 12:04 PM
>>Any ideas?
Makes sure the vector table points at yours rather than the ROMs
ie SCB->VTOR = 0x08000000;
2020-08-18 12:04 PM
>>Any ideas?
Makes sure the vector table points at yours rather than the ROMs
ie SCB->VTOR = 0x08000000;
2020-08-18 12:50 PM
Hi clive1
You made my day. Inspecting my two projects (the GP timer where the bootloader did not work and the LCD/I2C where the bootloader works), I noticed that my GP timer project did not have the system_stm32f4xx.c file. Copying this file into my GP timer project, my timer now works like a charm via bootloader flash.
Thanks a lot for your help.
Cheers,