STM32串口通讯printf函数实现

合集下载

通过串口利用printf函数输出数据

通过串口利用printf函数输出数据

通过串口利用printf函数输出数据一。

printf函数格式printf函数具有强大的输出功能%表示格式化字符串输出目前printf支持以下格式的输出,例如:printf("%c",a);输出单个字符。

printf("%d",a);输出十进制整数。

printf("%f",a);输出十进制浮点数.printf("%o",a);输出八进制数。

printf("%s",a);输出字符串。

printf("%u",a);输出无符号十进制数。

printf("%x",a);输出十六进制数。

例如:n = 15printf("The result is %d", n); //通过屏幕输出十进制数15n = 15.2printf("The result is %f", n); //通过屏幕输出十进制浮点数15 二。

实现方法在uart.c文件中加入#include "stdio.h"////////////////////////////////////////////////////////////////// //加入以下代码,支持printf函数,而不需要选择use MicroLIB #if 1#pragma import(__use_no_semihosting)//标准库需要的支持函数struct __FILE{int handle;};FILE __stdout;//定义_sys_exit()以避免使用半主机模式_sys_exit(int x){x = x;}//重定义fputc函数int fputc(int ch, FILE *f){while((USART1->SR&0X40)==0);//把数据通过串口1循环发送,直到发送完毕 ,如果使用串口2,则改成 USART2USART1->DR = (u8) ch;return ch;}#endif三。

在STM32中使用printf发送字符串到串口

在STM32中使用printf发送字符串到串口

在STM32中使用printf发送字符串到串口
问题:在使用STM32 调试时,经常使用串口发送信息,为了方便调试与
串口发送信息,用printf()函数实现通过串口打印信息。

方法一:
1.添加包含printf()函数的头文件:#include “stdio.h”
2.重写stdio.h 头文件中的int fputc(int ch, FILE *f) 函数
int fputc(int ch, FILE *f)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
//等待先前的字符发送完成
USART_SendData(USART1, (uint8_t) ch);
//发送字符
return ch;
}
//示例函数中使用了USART1 来发送消息
//实际情况可以根据硬件板来决定使用哪个串口
注意:使用while 循环先等待先前的字符发送完成,避免造成字符串首字符发
送丢失的问题。

3.将该函数” int fputc(int ch, FILE *f) “放在main()函数能够调用到的文件中,KEIL->Options for Target’xxx’->Target->Code Generation,勾选Use MicroLIB
方法二:
//加入以下代码,支持printf 函数,而不需要选择use MicroLIB
#if USART_DEBUG。

STM32之串口通信_you are great

STM32之串口通信_you are great

STM32之串口通信标签: stm32串口通信usartit分类:STM32实验目的:实现利用串口1 不停的打印一个信息到电脑上,同时接收从串口发过来的数据,把发送过来的数据直接送回给电脑。

实验平台:基于STM32F103C8T6的彩屏开发板硬件接口:注意:因为我的开发板上的串口和LED 共用了PA9和PA10,所以在使用USART1时务必屏蔽LED ,不然两者会互相影响而导致实现现象无法呈现。

相关寄存器:1,串口时钟使能。

串口作为STM32 的一个外设,其时钟由外设时钟使能寄存器控制,这 里我们使用的串口1 是在APB2ENR 寄存器的第14 位。

2,串口复位。

串口1 的复位是通过配置APB2RSTR 寄存器的第14 位来实现的。

通过向该位写1来复位串口1,写0 结束复位。

3,串口波特率设置。

每个串口都有一个自己独立的波特率寄存器USART_BRR波特率的计算,STM32 的串口波特率计算公式如下:上式中,是给串口的时钟(PCLK1 用于USART2、3、4、5,PCLK2 用于USART1);USARTDIV是一个无符号定点数。

我们只要得到USARTDIV 的值,就可以得到串口波特率寄存器USART1->BRR 的值。

4,串口控制。

STM32 的每个串口都有3 个控制寄存器USART_CR1~3,串口的很多配置都是通过这3 个寄存器来设置的5,数据发送与接收。

STM32 的发送与接收是通过数据寄存器USART_DR 来实现的,这是一个双寄存器,包含了TDR 和RDR。

6,串口状态。

串口的状态可以通过状态寄存器USART_SR 读取。

(注:详细的介绍使用请参考ST公司的数据手册)程序设计:(注:本人的usart.cusart.hdelay.cdelay.hsys.csys.h是引用网上一位网友整理的)usart.h#ifndef __USART_H#define __USART_H#include <stm32f10x_lib.h>#include "stdio.h"extern u8 USART_RX_BUF[64]; //接收缓冲,最大63个字节.末字节为换行符extern u8 USART_RX_STA; //接收状态标记//如果想串口中断接收,请不要注释以下宏定义#define EN_USART1_RX //使能串口1接收voiduart_init(u32 pclk2,u32 bound);#endifusart.c#include "sys.h"#include "usart.h"//加入以下代码,支持printf函数,而不需要选择use MicroLIB#if 1#pragma import(__use_no_semihosting)//标准库需要的支持函数struct __FILE{int handle;};FILE __stdout;//定义_sys_exit()以避免使用半主机模式_sys_exit(int x){x = x;}//重定义fputc函数intfputc(intch, FILE *f){while((USART1->SR&0X40)==0);//循环发送,直到发送完毕USART1->DR = (u8) ch;returnch;}#endif//end//////////////////////////////////////////////////////////////////#ifdef EN_USART1_RX //如果使能了接收//串口1中断服务程序//注意,读取USARTx->SR能避免莫名其妙的错误u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节.//接收状态//bit7,接收完成标志//bit6,接收到0x0d//bit5~0,接收到的有效字节数目u8 USART_RX_STA=0; //接收状态标记void USART1_IRQHandler(void){u8 res;if(USART1->SR&(1<<5))//接收到数据{res=USART1->DR;if((USART_RX_STA&0x80)==0)//接收未完成{if(USART_RX_STA&0x40)//接收到了0x0d{if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始elseUSART_RX_STA|=0x80; //接收完成了}else //还没收到0X0D{if(res==0x0d)USART_RX_STA|=0x40;else{USART_RX_BUF[USART_RX_STA&0X3F]=res;USART_RX_STA++;if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收}}}}}#endif//该函数的重点就是判断接收是否完成,通过检测是否收到0X0D、0X0A 的连续2 个字节//(0X0D 后跟0X0A 表示回车键)来检测是否结束。

stm32多串口公用printf的问题

stm32多串口公用printf的问题

[1楼] 正点原子等级:站长注册时间:2010/12/02 10:41 回复数: 43927 这等于你自己重构了一个printf接用写不够用过我的淘宝小店:主题数: 356酷贴数:25论坛积分:47495 来自: 湖南离线 回复[2楼] licgang等级:注册时间:2012/06/19 11:08 回复数: 20主题数: 5论坛积分:35离线现在是要用printf较麻烦,输出的格式有点多回复[3楼] 正点原子等级:站长注册时间:2010/12/02 10:41 回复数: 43927主题数: 356酷贴数:25论坛积分:47495来自: 湖南离线哦的实现方法我的淘宝小店: 回复[4楼] licgang等级:注册时间:2012/06/19 11:08 回复数: 20主题数: 5论坛积分:35离线这两天有空研究了下数,参照网上资料自己写了个模拟现多串口其实变参数的获取了,这里要用到stdarg.h问题了。

void myitoa(int data,char *buf ){int temp,j=0,i=0;while(data) //反序生成数字,可自己取个数字测试,如123,反序字符数组中的值为321{buf[i++] = data%10+'0';//将转换后的数字字符存放在字符数组中data = data/10; //删除已经转换的数字,为取下一个数字做好准备}buf[i--]='\0'; //转换完后还需要在字符数组后面加一个字符串结束标志'/0',代表是一个字符串while( j < i ) //刚刚转换好的字符串是逆序的必须把它反转过来{temp = buf[j];buf[j] = buf[i];buf[i] = temp;i--,j++;}}//------------------------COM3 printf------------------------------//void DBGprintf(const char*format, ...){va_list ap;char c,nc;va_start(ap, format);//从右到左将参数入栈,ap指向formatwhile (c = *format++){if(c == '%'&&(nc = *format++) != '\0'){switch(nc){case 'c': //输出1个字符{char ch = va_arg(ap, int); //调用后栈回复[5楼] 正点原子可以写成形如myprintf(u8 uartx,const char *format, ...)其中等级:站长注册时间:2010/12/02 10:41 回复数: 43927主题数: 356酷贴数:25论坛积分:47495来自: 湖南离线如1,2,3,4,5对应串口1~5.后见面的两个参数就是标准的printf参数了.这样使用起来更方便.我的淘宝小店: 回复2012/08/05 11:54[6楼] licgang等级:注册时间:2012/06/19 11:08 回复数: 20主题数: 5论坛积分:35离线后面是要这样写方便些,贴出代码来主要是让大家看下,顺便测试看有没有什么问题,目前测试都还正常刚才测试打印INT整数,发现STM32int是32位的,上面程序默认的INT类型是有符号的,超出0x7fffffff,输出不正常。

STM32KEIL下的printf函数

STM32KEIL下的printf函数
1加入以下代码支持printf函数而不需要选择usemicrolib2if13pragmaimportusenosemihosting4标准库需要的支持函数5structfile67inthandle
L下的 printf函数
1 //加入以下代码,支持printf函数,而不需要选择use MicroLIB 2 #if 1 3 #pragma import(__use_no_semihosting) 4 //标准库需要的支持函数 5 struct __FILE 6{ 7 int handle; 8 9 }; 10 11 FILE __stdout; 12 //定义_sys_exit()以避免使用半主机模式 13 _sys_exit(int x) 14 { 15 x = x; 16 } 17 //重定义fputc函数 18 int fputc(int ch, FILE *f) 19 { 20 //return ITM_SendChar(ch); 21 22 while((USART2->SR&0X40)==0);//循环发送,直到发送完毕 23 USART2->DR = (u8) ch; 24 return ch; 25 } 26 #endif
如上图: 保留这一部分时:
其中 可以更换任意的串口 printf输出用串口发送出去 当 下图圈圈中的部分编译
则 通过JTAG (6线) 打印到SEGGER软件上
但是当串口初始化函数运行了的时候 上面就失效了 原因是?

STM32串口接收、发送数据实验-程序代码分析

STM32串口接收、发送数据实验-程序代码分析

STM32串⼝接收、发送数据实验-程序代码分析串⼝通信实验Printf⽀持printf向串⼝发送⼀些字符串数据。

如果使⽤串⼝2,可以修改while((USART1->SR&0X40)==0);和USART1->DR = (u8) ch; 中的USART1为USART2.//加⼊以下代码,⽀持printf函数,⽽不需要选择use MicroLIB#if 1#pragma import(__use_no_semihosting)//解决HAL库使⽤时,某些情况可能报错的bugint _ttywrch(int ch){ch=ch;return ch;}//标准库需要的⽀持函数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 is typedef’ d in stdio.h. */FILE __stdout;//定义_sys_exit()以避免使⽤半主机模式void _sys_exit(int x){x = x;}//重定义fputc函数int fputc(int ch, FILE *f){while((USART1->SR&0X40)==0);//循环发送,直到发送完毕USART1->DR = (u8) ch;return ch;}#endif实验现象从电脑串⼝助⼿发送长度为200以内任意长度的字符串给STM32串⼝1(字符串以回车换⾏标识结束),STM32接收到字符串之后,⼀次性通过串⼝1把所有数据返回给电脑。

实现过程把每个接收到的数据保存在⼀个程序定义的Buffer数组中(数组长度为200),同时把接收到的数据个数保存在定义的变量中。

单片机程序巧用printf

单片机程序巧用printf
由于不同的编译器 studio 函数不一样,所以使用的 方法也不一样,这需要大家去看编译器的 help 帮助选项, 这里我们以 STM32、51 和 AVR 整理了几个串口打印程序, 供需要的朋友参考。
1、在 KEIL 下使用 printf 函数,以 STM32 为例 在 uart.c 中添加如下代码 View Code /************************************************ ******************************* 函数名:fputc 输 入: 输 出:
return (int)USART_ReceiveData(USART1); }
这样,只要在需要用 printf 的文件里#include ;就 可以了,printf 会自已的调用 fputc 函数来实现串口数 据的输出。 2、添加 Retarget.c,实现在 KEIL 下使用 printf 函数, 以 LPC2478 为例
int sendchar (int ch) { // Write character to Serial Port while (!(U0LSR & 0x20)); return (U0THR = ch); } int getkey (void) { // Read character from Serial Port while (!(U0LSR & 0x01)); return (U0RBR); } 这样,只要在需要用 printf 的文件里#include ;就 可以了,printf 会通过 Retarget 中的 fputc 函数调用 sendchar 来实现串口数据的输出。 事实上,和第一种的方式是一样的。 3、自定义 printf 函数,以 AVR 为例 前面介绍的是在 KEIL 编译器上使用 printf 函数,但 不是所有的编译器平台都能适用,因此有时候我们需要

记录stm32f407使用hal库,串口2重定向到printf的一些问题(已解决)

记录stm32f407使用hal库,串口2重定向到printf的一些问题(已解决)

记录stm32f407使⽤hal库,串⼝2重定向到printf的⼀些问题(已解决)⼤致介绍在使⽤usart2时,使⽤中断传输进⾏printf会出现异常。

使⽤阻塞传输⽆问题。

在usart1中⽆问题。

在GD32F407中⽆问题。

直接使⽤中断传输⽆问题。

使⽤代码正常配置串⼝,勾选microlib库,重写fputcint fputc(int ch, FILE *f){while(HAL_UART_Transmit_IT(&huart2, (unsigned char *)&ch, 1)!=HAL_OK){};return ch;}结果只配置usart2时,使⽤printf打印,只能接收到0x0C;同时配置了usart1时,使⽤printf打印,只能接收到0x14;同时配置usart3时,使⽤printf打印,只能接收到0x16;同时配置usart6时,使⽤printf打印,只能接收到0x1e;原因所在在查询串⼝相关的讯息时,考虑到不使⽤microlib库打印会如何。

加⼊标准库⽀持后,打印正常。

#pragma import(__use_no_semihosting)//标准库需要的⽀持函数struct __FILE{int handle;};FILE __stdout;/*** @brief 定义_sys_exit()以避免使⽤半主机模式* @param void* @return void*/void _sys_exit(int x){x = x;}同时发现,使⽤微库时,优化等级也会造成影响。

在-o3,-o2,-o1时时,除了usart1以外,其他的均会出现以上情况。

-o0时,⼀切正常。

(以上均是仅测试usart1,usart2,usart3)。

考虑到有在⽹上见到过:选上Use MicroLIB,例如你⽤printf()函数的时候,就会从串⼝1输出字符串,直接默认定向到串⼝1。

法1可实现串⼝1数据输出,但要定向到串⼝2,串⼝3,microLIB就不合⽤了;这样的⾔论,也许有⼀定关系吧。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档