»
(008)CubeIDE实现USB外设*
(018)C99 的指针*
(019)C99 只有值赋值,没有move*
(022)POSIX线程库pthread的同步锁*
(023)POSIX线程库pthread的多线程*
(027)C99标准库中的计时与等待 *
(028)C语言中的高精度计算库GMP *
(029)C语言中的Web服务*
(030)C语言中的字符转码ICU*
(031)从几个方面显然C语言比C++效率高*
(036)STM32重定向printf输出到USART的方法
STM32重定向printf输出到USART1的方法
1、重写_write函数放到syscall.c文件里面
int outputc(int ch){
while((USART1->SR & USART_SR_TXE) == 0);// 等待 USART1 的发送数据寄存器准备好
USART1->DR = (uint8_t)ch; //填充需要发送的字节到USART1的数据寄存器(DR)
while((USART1->SR & USART_SR_TC) == 0); //USART的状态寄存器(SR),等待直到发送完成
return ch;
}
int _write(int file, char *ptr, int len) {
// 判断是否由标准输出调用
//if (file == STDOUT_FILENO || file == STDERR_FILENO) {//嵌入式不适用
// 如果是标准输出,则通过串口发送
for (int i = 0; i < len; i++) {
//HAL_UART_Transmit(&huart1, (uint8_t *)&ptr[i], 1, HAL_MAX_DELAY);
outputc(*ptr++);
}
return len; // 返回写入的字节数
//}
// 如果不是标准输出,返回错误 -1
return -1;
}
注意:通过改写weak int _write(int file, char *ptr, int len)函数实现的printf没有缓冲区,printf输出的每个字符都会依次直接输出到UART,所以,顺序可能会乱。
调试过程:
如果printf函数TTL没有输出,先判断UART1与TTL是否有问题:
//直接在初始化完成后调用以下函数测试UART1是否正常:
HAL_UART_Transmit(&huart1, (uint8_t *)"Test UART1\n", 11, HAL_MAX_DELAY);
2、功能开发过程注意事项:
1)网口只有在带电烧录后才能使用的问题:
在硬件的开发过程中,需要考虑外设的加电过程、网卡的加电过程以及外设的加电完成时间、网卡的加电完成时间,特别是有振荡电路的外设。必要时使用Delay等待外设加电过程的完成。
技术以外的话:
与我共事:完整交付代码,不留bug,不保留代码,写经得起几年考验的代码。
与我共事,能提升:正确的FreeRTOS的内存配置方法;能提升:裸机while循环外的技巧(说明:裸机开发都只有一个主while循环,来自ChatGPT和DeepSeek)。能提升为什么嵌入式中的printf会导致死机:在FreeRTOS系统任意地方使用带%f号的printf(自我研究过程中总结的使用Queue实现的不阻塞高效printf)
人生格言:招之即来,辞之即去,挥挥衣袖,留下一片云彩。