完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
首先,用pragma指令禁用半主机模式,防止调用printf就出现HardFault。然后在std命名空间中重写fgetc、fputc、fclose、fseek和fflush函数,还要重写__stdin、__stdout和__stderr这三个全局变量。
_sys_exit和_ttywrch也要重写,前者是main函数返回后调用的函数,_ttywrch是出现错误时往串口打印字符的函数。 _sys_exit函数不允许返回,必须以无限循环结尾。 另外,工程属性里面不要勾选Use MicroLIB,这个选项和C++是不兼容的!!即使使用C语言,也能在不勾选Use MicroLIB的情况下printf输出到串口。 【cout.cpp】 #include #include #include "common.hpp" #pragma import(__use_no_semihosting) // 禁用半主机模式 // 请不要勾选Use MicroLib #ifdef __MICROLIB #error "Please do not use MicroLib!" #endif extern "C" { void _sys_exit(int returncode) { printf("Exited! returncode=%dn", returncode); while (1); } void _ttywrch(int ch) { if (ch == 'n') HAL_UART_Transmit(&huart1, (uint8_t *)"rn", 2, HAL_MAX_DELAY); else HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); } } namespace std { struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; FILE __stdin = {0}; FILE __stdout = {1}; FILE __stderr = {2}; int fgetc(FILE *stream) { int c = 0; if (stream->handle == 0) { while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET); HAL_UART_Receive(&huart1, (uint8_t *)&c, 1, HAL_MAX_DELAY); _ttywrch((c == 'r') ? 'n' : c); // 回显 return c; } return EOF; } int fputc(int c, FILE *stream) { if (stream->handle == 1 || stream->handle == 2) { _ttywrch(c); return c; } return EOF; } int fclose(FILE * stream) { return 0; } int fseek(FILE *stream, long int offset, int whence) { return -1; } int fflush(FILE *stream) { if (stream->handle == 1 || stream->handle == 2) while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) == RESET); return 0; } } 另外,启动文件startup_stm32f103xb.s中默认分配的堆空间太小,必须要改大,否则将无法进入main函数。如果程序运行过程中出现HardFault,说明堆空间仍然不够,还需要继续改大。 Heap_Size EQU 0x0001000 以下是测试代码: 【main.cpp】 #include #include #include #include #include #include "common.hpp" using namespace std; // 类 class Test { private: int num; public: Test(int num) : num(num) {} void display(void) { cout << "num=" << num << endl; } }; // 函数模板 template static void further_test(T a) { cout << "[" << typeid(a).name() << "] a=" << a << endl; } // 字符串替换 static void str_replace(string search, string replace, string &subject) { string::size_type pos = 0; for (pos = 0; (pos = subject.find(search, pos)) != string::npos; pos += replace.length()) subject.replace(pos, search.length(), replace); } static void further_test(void) { // string字符串 string str = "this is"; str.append(" a string"); str_replace("is", "[IS]", str); cout << str << " len=" << str.length() << endl; // vector容器 vector vector items.push_back("fooo"); items.push_back("bar"); items.push_back("welcome"); cout << "size=" << items.size() << endl; for (iter = items.begin(); iter != items.end(); ++iter) cout << *iter << " "; cout << endl; // new和delete运算符 int i; int n = items.size(); int *arr = new int[n]; for (i = 0; i < n; i++) arr = items.at(i).length(); for (i = 0; i < n; i++) cout << arr << " "; cout << endl; delete[] arr; // 类 Test t = 50; t.display(); // 引用 Test &u = t; u.display(); // scanf输入 printf("Please input: "); scanf("%d", &n); printf("2n=%dn", 2 * n); // cin输入 cout << "Please input: "; cin >> n; cout << "3n=" << 3 * n << endl; } // s文件中的Heap_Size必须改大,不能采用默认值,否则进不了main函数 // 如果出现Hard Error, 则说明还需要继续改大 int main(void) { HAL_Init(); clock_init(); usart_init(115200); printf("STM32F103C8 printfn"); printf("SystemCoreClock=%un", SystemCoreClock); cout << "STM32F103C8 cout" << endl; cout << "SystemCoreClock=" << SystemCoreClock << endl; // 函数重载 further_test(15); further_test("this"); further_test(); return 0; } 【common.cpp】 #include #include #include "common.hpp" UART_HandleTypeDef huart1; extern "C" { #ifdef USE_FULL_ASSERT // HAL库参数错误警告 void assert_failed(uint8_t *file, uint32_t line) { printf("%s: file %s on line %dn", __FUNCTION__, file, line); while (1); } #endif void HardFault_Handler(void) { printf("Hard Error!n"); while (1); } void SysTick_Handler(void) { HAL_IncTick(); } } // 配置系统和总线时钟 void clock_init(void) { HAL_StatusTypeDef status; RCC_ClkInitTypeDef clk = {0}; RCC_OscInitTypeDef osc = {0}; // 外部晶振为8MHz, 配置PLL倍频器倍频9倍后是72MHz osc.OscillatorType = RCC_OSCILLATORTYPE_HSE; osc.HSEState = RCC_HSE_ON; osc.PLL.PLLMUL = RCC_PLL_MUL9; osc.PLL.PLLSource = RCC_PLLSOURCE_HSE; osc.PLL.PLLState = RCC_PLL_ON; status = HAL_RCC_OscConfig(&osc); // 如果外部晶振启动失败, 则改用内部的8MHz晶振, 经过2分频后倍频16倍, 变成64MHz if (status != HAL_OK) { osc.HSEState = RCC_HSE_OFF; osc.PLL.PLLMUL = RCC_PLL_MUL16; osc.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; HAL_RCC_OscConfig(&osc); } // ADC时钟不能超过14MHz, 所以需要6分频, 72MHz经过分频后是12MHz __HAL_RCC_ADC_CONFIG(RCC_ADCPCLK2_DIV6); // 配置AHB和APB2总线时钟为72MHz, APB1总线时钟为36MHz clk.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clk.AHBCLKDivider = RCC_SYSCLK_DIV1; clk.APB1CLKDivider = RCC_HCLK_DIV2; clk.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_2); } void usart_init(int baud_rate) { GPIO_InitTypeDef gpio = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART1_CLK_ENABLE(); gpio.Mode = GPIO_MODE_AF_PP; gpio.Pin = GPIO_PIN_9; gpio.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &gpio); huart1.Instance = USART1; huart1.Init.BaudRate = baud_rate; huart1.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&huart1); } 【common.hpp】 #ifndef __COMMON_H #define __COMMON_H #ifdef HAL_UART_MODULE_ENABLED extern UART_HandleTypeDef huart1; #endif void clock_init(void); void usart_init(int baud_rate); #endif 程序运行结果: STM32F103C8 printf SystemCoreClock=72000000 STM32F103C8 cout SystemCoreClock=72000000 a=15 [PKc] a=this th[IS] [IS] a string len=20 size=3 fooo bar welcome 4 3 7 num=50 num=50 Please input: 123 2n=246 Please input: -456 3n=-1368 Exited! returncode=0 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1777 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1080 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1678 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
595浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
554浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 04:23 , Processed in 0.716780 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号