STM32F103C8T6/串口输出/printf函数内调fputc接口改造/硬件分析、CUBEMX初始化、 敲代码、代码分析/建立一套规范化的工程文件架构 | 您所在的位置:网站首页 › printf重定向到不同的串口 › STM32F103C8T6/串口输出/printf函数内调fputc接口改造/硬件分析、CUBEMX初始化、 敲代码、代码分析/建立一套规范化的工程文件架构 |
STM32F103C8T6
今天这一节教程作为stm32入门教程讲解 从硬件分析、CUBEMX初始化、 敲代码、代码分析,来领着大家对STM32的项目过程有个大致的了解以及养成建立一套规范化的工程文件架构的习惯 废话不多说,上干货 一、硬件分析
基本的硬件介绍就在笔记中了,看不懂么得关系,咱们先看更高一层的。 . . . 二、CUBEMX的程序代码初始化![]()
在RCC里面的HSE配置的是晶振时钟,配置完成后我们会看到两个相关管脚变成了绿色,说明已初始化。 复用,即平时的时候是IO口,但是当我们有特殊用途的时候,比如说UART通信(异步全双工串口通信)PA9可以作为TX,PA10可作为RX使用。直接在我们的右面的可视框图里面点击相应的引脚配置就OK。 但是配置完之后还是黄色的,不是绿色的,代表我们还没有完全的配置完毕,不要着急,请看下一步。 然后我们引脚就配置好了 这一块内容就是波特率的设置,一般系统自动按默认值11520bps,不过我们可以修改;默认的码元是8N1型的,8N1是什么,请看我的另一篇文章:有关单片机串口通信的原理性问题讲解 如下图 起个自己想要的名字,配置下路径,配置下想要生成的代码适用的编译器,这里选择MDK-ARM
按图上顺序操作就OK 了 第6步,找到我们刚才在src文件中建立的那个文件夹main_app,因为我们的main_app.h文件在这里面,这样就不会有错误和警告了
那么大家就会有个问题,为什么我要这么做呢,为什么不直接在main.c文件里面去写我们想要的程序呀 这里之后再解释,大家先把这个疑惑保留下。 . . . 五、开始敲写我们今天的代码 #include "main_app.h" #include #define Uart_Timeout 0xFFFF //定义一个超时参数,超时时间设为0XFFFFms void Uart1_Send(uint8_t *buf,uint32_t size);//声明下我们下面定义的一个字符串发送函数 int fputc(int data, FILE *f)//改造下fputc函数,将fputc函数的接口改到我们的这个串口上,因为printf里面调用的有fputc,所以到时候我们就可以直接用printf来发送串口数据 { Uart1_Send((uint8_t *)&data,1);//调用下我们刚才声明的串口发送函数 } //串口输出 void Uart1_Send(uint8_t *buf,uint32_t size)//定义一个串口数据发送函数 { HAL_UART_Transmit(&huart1, buf, size, Uart_Timeout);//将我们的参数传给我们这个hal库中本身存在的一个串口发送函数,从而让这个函数更加简单 } void Uart1_SendTest(void)//串口发送数据的测试 { Uart1_Send("hello,world",11);//发送一个11位的数据 } void Main_App(void)//定义这个函数中的最重要的函数,类似于主程序中的main函数,不过这个只是我们起的名字,main函数一个工程中只能有一个 { Uart1_SendTest(); printf("世界你好\r\n"); while(1) { } }. . . 六、代码疑难杂症分析说起代码的疑难杂症,根源问题是因为我们对hal库不熟而导致的,所以就带大家通过代码的分析来初步认识下几个hal库的函数定义 1、HAL_UART_Transmit(&huart1, buf, size, Uart_Timeout);先看这个函数,这个函数的原型是这个 emmmmm,具体的代码就先不带大家分析了,在这里说下几个参数的作用以及我们应该如何设置就OK HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) UART_HandleTypeDef *huart:一个结构体的句柄,不用理解是什么,我们要用的时候直接对其取地址就ok uint8_t *pData:指针型的数据 uint16_t Size:数据的大小 uint32_t Timeout:超时时间设置 void Uart1_Send(uint8_t *buf,uint32_t size)//定义一个串口数据发送函数 { HAL_UART_Transmit(&huart1, buf, size, Uart_Timeout);//将我们的参数传给我们这个hal库中本身存在的一个串口发送函数,从而让这个函数更加简单 }这就是我们最后改造好的函数,就是根据上面的要求去传入的参数,只不过把参数简化成了两个,把函数名字简化了并且更加具象化了下。 这就实现了我们一个数据的发送 2、对fputc函数的接口改造这就是我们应用到的fputc的地方,我们先找到这个函数的原型 int fputc(int data, FILE *f)//改造下fputc函数,将fputc函数的接口改到我们的这个串口上,因为printf里面调用的有fputc,所以到时候我们就可以直接用printf来发送串口数据 { Uart1_Send((uint8_t *)&data,1);//调用下我们刚才声明的串口发送函数 } printf("世界你好\r\n");fputc函数原型 在标准库stdio.h里面放着 extern _ARMABI int fputc(int /*c*/, FILE * /*stream*/) __attribute__((__nonnull__(2))); /* * writes the character specified by c (converted to an unsigned char) to * the output stream pointed to by stream, at the position indicated by the * asociated file position indicator (if defined), and advances the * indicator appropriately. If the file position indicator is not defined, * the character is appended to the output stream. * Returns: the character written. If a write error occurs, the error * indicator is set and fputc returns EOF. • 将 c 指定的字符(转换为无符号字符)写入 • 按流指向的输出流,位置由 • 已确定的文件位置指示器(如果定义),并推进 • 适当指示器。如果未定义文件位置指示器, • 该字符追加到输出流中。 * 返回:写入的字符。如果发生写入错误,则错误 • 指标设置,fputc 返回 EOF。 */然后我们改造成这样 int fputc(int data, FILE *f)//改造下fputc函数,将fputc函数的接口改到我们的这个串口上,因为printf里面调用的有fputc,所以到时候我们就可以直接用printf来发送串口数据 { Uart1_Send((uint8_t *)&data,1);//调用下我们刚才声明的串口发送函数 }因为我们知道printf函数里面调用的是fputc函数,所以我们这样改造fputc函数的接口后,就直接可以用printf函数向串口发送数据了 七、总结这就是我们本期的教程了,学习32是个循序渐进的过程,没有捷径,多看多写多理解,就OK 如果这篇文章对你有帮助,记得点赞哦,如果文章哪里有错误,请在评论区里及时指出。谢各位大佬~ |
CopyRight 2018-2019 实验室设备网 版权所有 |