在单片机中使用最多的通信接口基本就是串口了,说起串口就不得不提串口中最常用的一个函数就是打印函数printf()函数,在上位机上中这个函数直接从库函数中调用就可以了,那么在单片机中这个函数要怎么使用呢?能不能将这个函数和串口1对应起来,当然是有方法的。

  下面就通过代码来演示一下如何在串口1上使用printf()函数的功能。

void uart_init(u32 bound)
{//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);  //使能USART1,GPIOA时钟//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX     GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE);                    //使能串口1
}

  首先初始化串口1所使用到的端口,将发送引脚设置为推挽输出模式,将接收引脚设置为浮空输入模式。这里串口使用中断来接收数据,所以还需要设置中断优先级,通过NVIC(嵌套向量中断控制器)来设置串口中断的优先级,接下来设置串口的波特率,字长为8位,1位停止位,无奇偶校验位,无硬件数据流控制端口,串口模式设置为收发模式。最后使能串口,并开启中断功能。

  下面编写串口中断函数,用来接收数据

u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0,   接收到的有效字节数目
u16 USART_RX_STA = 0;     //接收状态标记void USART1_IRQHandler(void)                 //串口1中断服务程序
{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res = USART_ReceiveData(USART1);  //读取接收到的数据if((USART_RX_STA & 0x8000) == 0) //接收未完成{if(USART_RX_STA & 0x4000) //接收到了0x0d{if(Res != 0x0a)USART_RX_STA = 0; //接收错误,重新开始else USART_RX_STA |= 0x8000;   //接收完成了}else //还没收到0X0D{if(Res == 0x0d)USART_RX_STA |= 0x4000;else{USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res ;USART_RX_STA++;if(USART_RX_STA > (USART_REC_LEN - 1))USART_RX_STA = 0; //接收数据错误,重新开始接收}}}}
}

  接收数据时通过USART_RX_STA变量的最高两位表示接收数据的状态,接收数据以回车换行作为结束位,回车换行对应的数据为0x0D、0x0A,只有这两个数据挨着接收到之后才表示一组数据成功的接收到了,这里使用USART_RX_STA最高两位表示是否接收到了这两个结束标志。

  串口设置好之后,接下来给串口1添加支持printf()函数的代码。

#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); //循环发送,直到发送完毕USART1->DR = (u8) ch;return ch;
}
#endif

  上面的两个函数是固定模式不需要修改,自己需要修改的是fputc()函数,在这个函数中将寄存器设置为串口1的寄存器,这样printf()函数在打印数据的时候,就会通过串口1将数据发送出去,如何这里的寄存器设置为了其他串口的寄存器,那么使用printf()函数打印的时候就会通过其他串口打印出去。重定义函数fputc()设置好之后,就可在程序中直接使用printf()函数打印了。

int main(void)
{u8 t;u8 len;u16 times=0;delay_init();       //延时函数初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);LED_Init();while(1){if(USART_RX_STA&0x8000){LED1=!LED1;len=USART_RX_STA&0x3fff;       //获取本次接收数据长度printf("\r\n您发送的消息为:\r\n");for(t=0;t<len;t++){USART_SendData(USART1,USART_RX_BUF[t]);//向串口1发送数据while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送完成 }printf("\r\n");USART_RX_STA=0;}else{times++;if(times%5000==0){printf("串口实验\r\n");}if(times%300==0)printf("请输入数据,以回车键结束\r\n");if(times%30==0)LED0=!LED0;delay_ms(10);}}
}

  在主函数中通过printf()打印提示语句,提示用户输入数据。当用户输入数据并以回车换行结束后,串口接收到数据就会将接收到的数据直接打印出来。

  这样在单片机中,通过串口1就可以输出printf()函数打印的数据了。

STM32F103串口1 printf函数的实现相关推荐

  1. STM32F103自定义的printf函数的实现

      在单片机中使用最多的通信接口基本就是串口了,说起串口就不得不提串口中最常用的一个函数就是打印函数printf()函数,通常使用这个函数都是直接调用库函数来实现的,在单片机中如何要使用printf( ...

  2. linux arm printf 函数与串口,11、串口实现printf()函数--s3c440

    一.概要 由于以往的单片机实现printf函数成本太高,基本上不会其上实现printf功能,随着ARM芯片的发展,printf调试受到了极大的欢迎.对于嵌入式软件的开发人员而言,"print ...

  3. 用串口模拟printf函数输出

    #include <iostream> #include <stdio.h> #include <stdarg.h> int MY_PRINT(const char ...

  4. 通过uart串口和printf函数打印

    #include "stdio.h" int __io_putchar(int ch) { HAL_UART_Transmit(&huart1,(uint8_t *)&am ...

  5. STM32F103系列_串口Usart收发函数

    STM32F103系列_串口Usart收发函数 常见问题: 串口第一个字节丢失? 串口不稳定? 串口调用英文数字没问题,但中文乱码? 串口调用与TIM冲突,卡住? 代码 Usart.c Usart.h ...

  6. STM32中关于串口通信的printf()函数重定向问题

    在STM32串口通信程序中使用printf()函数发送数据非常方便,但是需要先进行简单的配置,下面介绍两种配置方法. 方法一.对工程属性进行配置 第1步:在main.c中包含"stdio.h ...

  7. STM8学习笔记---串口printf函数的实现

    在使用单片机的时候,串口是要经常使用的功能,特别是在调试代码的过程中,经常需要使用串口打印出某些变量值,来判断程序执行流程是否正常.但是单片机默认情况下没有printf函数,如果需要使用printf函 ...

  8. ABOV单片机UART串口通讯中Printf函数实现讲解及示例代码-[MC96F6332D]

    一.准备工作 1.KEIL C51编译环境 2.CodeGen8 代码生成器 3.MC96F6332D 开发板 4.USB-OCD II仿真器 二.生成串口代码 1.在CodeGen8 代码生成器的外 ...

  9. STM32多串口printf函数

    1.配置usart2的串口配置,gpio,rcc enable,跟上面类似 2.勾选usb micro lib,跟上面类似 3.添加头文件#include <stdarg.h>,编写USA ...

最新文章

  1. fail2ban安全设置
  2. redis的基本使用笔记二
  3. 浅谈非法NAT接入对网络的安全风险
  4. 在阿里云上遇见更好的Oracle(四)
  5. JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
  6. 编译编译时,用不到的库,一定不要链接
  7. c语言实例100_pic单片机,PIC单片机C语言编程实例
  8. IT人的算法书单:挖掘程序的灵魂
  9. 5分钟latex 使用入门写llncs论文
  10. 求链表中的中点、上中点、下中点
  11. DFRobot新推出一款适合短时间环境数据记录的Gravity: 串口数据记录器
  12. java excel 列_Java 删除Excel中的行和列
  13. TikTok在国内运营一个月,20万粉丝蛮简单的,绝对避免抖音国际版零播放问题
  14. 我就想知道知道我错哪了!!啊啊啊啊!
  15. mysql-mmm 故障_mysql-mmm故障解决一例
  16. python calu()函数_python面向对象
  17. linux设备驱动归纳总结(八):4.总线热插拔
  18. 年轻人的浮躁,这社会的喧嚣
  19. 项目管理证书 PMP 考试费用要多少?
  20. 大黄蜂(HORNET):比Tor更快更安全的匿名网络

热门文章

  1. Adobe reader 在打开时如何恢复上一次阅读位置
  2. SQL点滴35—SQL语句中的exists
  3. 转正后的感悟(对正在实习的朋友的建议吧)
  4. SNF快速开发平台2019-APP移动端实际应用效果
  5. CS224d lecture 7札记
  6. 《幸福就在你身边》第一课、你有追求美好生活的权利【哈佛大学幸福课精华】...
  7. practical of programming 第二章 java的quick sort
  8. 性能测试之JMeter中JSON断言详解
  9. raster | R中的栅格操作符(下)[翻译]
  10. mysql 如何选择2行_MYSQL – 从大表中的第二行中选择数据