STM32F072RB Nucleo板SD卡RTC日期戳文件名生成问题求助
Hey Joana, let's fix that filename formatting problem you're facing with your STM32F072 Nucleo data logger! The core issue here is that when you assign a uint8_t numeric value (like 9 for the date) directly to a char variable, you're storing the ASCII control character corresponding to that number (ASCII 9 is a tab \t) instead of the digit character '9'. Let's break down the solutions step by step:
First, Understand the Character Conversion Trick
To convert a single-digit number to its corresponding ASCII character, simply add the ASCII value of '0' (which is 48) to the numeric value. For example:
uint8_t day = 9; char day_char = '0' + day; // This gives '9' (ASCII 57) instead of '\t'
For two-digit numbers (like 15), split the tens and units digits first:
uint8_t day = 15; char tens = '0' + (day / 10); // '1' char units = '0' + (day % 10); // '5'
Simplify Your Filename Construction
Your current approach with if-else for months is functional, but we can clean it up and fix the date conversion at the same time. Here are two robust methods:
Method 1: Manual String Construction (No Standard Library Dependencies)
This is great if you want to avoid relying on standard library functions:
char filename[12] = {'\0'}; // Initialize to empty const char* month_names[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; // Get RTC time/date HAL_RTC_GetTime(&hrtc, &time3, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); // Copy 3-letter month to filename filename[0] = month_names[date.Month - 1][0]; filename[1] = month_names[date.Month - 1][1]; filename[2] = month_names[date.Month - 1][2]; // Handle 2-digit date if (date.Date < 10) { filename[3] = '0'; filename[4] = '0' + date.Date; } else { filename[3] = '0' + (date.Date / 10); filename[4] = '0' + (date.Date % 10); } // Add the rest of the filename suffix filename[5] = '_'; filename[6] = '0'; filename[7] = '0'; filename[8] = '.'; filename[9] = 'T'; filename[10] = 'X'; filename[11] = 'T';
Method 2: Use Standard Library sprintf (Cleaner Code)
If your STM32 project is configured to use the standard C library (most are by default, or you can enable it in your IDE settings—e.g., check "Use MicroLIB" in Keil), sprintf makes this trivial:
char filename[12]; const char* month_names[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; HAL_RTC_GetTime(&hrtc, &time3, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); // Format the filename in one line sprintf(filename, "%s%02d_00.TXT", month_names[date.Month - 1], date.Date);
The %02d format specifier ensures the date is always two digits (e.g., 9 becomes "09").
Do ST Libraries Provide Conversion Tools?
To answer your question directly: ST's HAL library doesn't include dedicated string conversion functions like itoa as part of its core utilities. However, standard C library functions like sprintf, itoa, and utoa are fully supported in STM32 development environments (GCC, ARMCC) as long as you have the standard library enabled in your project configuration.
This should resolve your issue and generate filenames exactly in the format you want (e.g., "MAY09_00.TXT").
内容的提问来源于stack exchange,提问作者Joana Rigbi

