KEIL Configuration
System Reset Implementation
__set_FAULTMASK(1);
NVIC_SystemReset();
Crystal Oscillator Configuration
In the stm32f10x.h file, modify the system clock setup:
static void ConfigureSystemClockTo72MHz(void)
{
__IO uint32_t startupCounter = 0, hseStatus = 0;
/*!< Enable the High Speed External oscillator (HSE) */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/*!< Wait till HSE is ready, timeout if not */
do
{
hseStatus = RCC->CR & RCC_CR_HSERDY;
startupCounter++;
} while((hseStatus == 0) && (startupCounter != HSEStartUp_Timeout));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
hseStatus = (uint32_t)0x01;
}
else
{
hseStatus = (uint32_t)0x00;
}
if (hseStatus == (uint32_t)0x01)
{
/*!< Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/*!< Set 2 wait states for Flash */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/*!< HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/*!< PCLK2 = HCLK (Typically used for APB2 peripherals) */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/*!< PCLK1 = HCLK / 2 (Typically used for APB1 peripherals) */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/*!< PLLCLK = HSE * 6 = 72 MHz (8*9=72 or 6*12=72) */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL6); //12M*6=72M
/*!< Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/*!< Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/*!< Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/*!< Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
else
{ /*!< If HSE fails to start, application will have wrong clock configuration. User can add code here to handle this error */
/*!< Infinite loop */
while (1)
{
}
}
}
STM32CubeIDE Features
Implementing printf Funcsionality
Add the following code to either usart.c or main.c:
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(FILE *f)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
GETCHAR_PROTOTYPE
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1,(uint8_t *)&ch, 1, 0xFFFF);
if (ch == '\r')
{
__io_putchar('\r');
ch = '\n';
}
return __io_putchar(ch);
}
Include the necessary header:
#include <stdio.h>
Configure the IDE to use scanf library files.
Generating Hex and Bin Files
Navigate to toolbar: Project → Properties
Follow these steps to configure the output format:
- Select the appropriate options for generating both Hex and Bin files
- Apply and Close
- After compilation, check the Debug folder for the generated files
Code Highlighting Feature
Enable this feature to highlight identical code sections throughout your project. When activated, matching code blocks will be highlighted; when disabled, only the currently selected portion will be shown.
String Prefix Detection Function
/* String processing function for char or uint8_t arrays */
uint8_t has_prefix(const char *source, const char *prefix)
{
while (*prefix)
if (*prefix++ != *source++)
return 0;
return 1;
}
Usage example:
if(has_prefix((char *)uart_rx_buffer, "CMD,")) // Check prefix
Data Parsing and Conversion Functions
Example input format: CMD,12,23,45,87,88,\r\n
if(has_prefix((char *)uart5_rx_buffer, "CMD,")) // Check prefix
{
char *token;
token = strtok((char *)uart5_rx_buffer, ","); // First part before comma -- CMD
char *roll_value = strtok(NULL, ","); // 12
char *pitch_value = strtok(NULL, ","); // 23
double roll_data = strtod(roll_value, NULL); // Convert string to double
double pitch_data = strtod(pitch_value, NULL); // Convert string to double
/* Optional: Print received values */
printf("%.1f,%.1f\r\n", roll_data, pitch_data);
/* Clear buffer if needed */
}
Modifying Code Start Address in Flash
For a 128KB Flash with a 32KB bootloader at address 0x08000000:
The main code should include a function to handle the Flash offset.
Suporting Chinese Character Output
While IDE defaults to UTF-8 encoding, you can add GBK support for Chinese characters:
In the miscellaneous compiler options, add:
-fexec-charset=GBK
Modifying Font and Size
- Go to Window → Preferences
- Navigate to General → Appearance → Color and Fonts → C/C++ → Editor → Text Font
- Select your preferred font, style, and size
- Click Apply and Close
Troubleshooting Project Creation
If STMcube appears grayed out during new project creation and only "Empty" is available:
- Check available disk space
- Verify if an IDE udpate is needed
Additional Programming Tips
C Language Bit Manipulation
Example of flipping a specific bit in an 8-bit value:
0xAA = 1010 1010 To flip the 3rd bit:
uint8_t data = 0xAA;
data ^= 0x08; // XOR operation to flip bit 3
// Result: 0xA2 = 1010 0010
Using ST-Link to View MCU Memory Contents
To view memory contents with ST-Link:
- Use STM32 ST-LINK Utility or ST Visual Programmer software
- Before connecting, ensure the MCU is reset
- Connect the ST-Link and view the memory contents