野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20643|回复: 12

已重定向,printf好使,但scanf、gets 这两个输入函数不好使. 问题出在哪?怎么解决?

[复制链接]
发表于 2014-12-10 10:21:11 | 显示全部楼层 |阅读模式
本帖最后由 金色黄铜 于 2014-12-10 13:00 编辑

代码如下,试图用scanf函数从usart1获取一个字符串,然后再将它用printf发给计算机。

<main.c>
  1. u8 usart_buffer[20];

  2. int main(void)
  3. {
  4.         
  5.         USART1_Config();
  6.         NVIC_Config();

  7.         while(1)
  8.         {
  9.                 scanf("%s",usart_buffer);
  10.                 printf("%s",usart_buffer);
  11.         }
  12.                
  13. }
复制代码



<bsp_usart1.c>里的重定向代码。


  1. int fputc(int ch, FILE *f)
  2. {
  3.         USART_SendData(USART1,(uint8_t) ch);
  4.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET);
  5.         return (ch);
  6. }

  7. int fgetc(FILE *f)
  8. {
  9.         while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)== RESET);
  10.         return (int) USART_ReceiveData(USART1);
  11.         
  12. }
复制代码


回复

使用道具 举报

 楼主| 发表于 2014-12-10 10:30:56 | 显示全部楼层
除了在usart的中断向量服务程序里自己写代码一个字节一个字节地取,难道就不能通过scanf直接读入一个字符串吗?

因为明显重定向着这块的第二部分代码应该是服务于输入函数的,而且在程序里输入scanf函数语法上也不会提示错误,所以我认为编译环境应该是支持scanf函数的。

但实际上如果使用scanf函数,程序就会一直停在这里,电脑通过串口发数据程序也还是一直停在这里,没反应。

那么到底是哪个地方的问题?正确的做法应该是怎样?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-10 10:40:28 | 显示全部楼层
开发环境是开发板光盘里带的MDK.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-12 12:05:17 | 显示全部楼层
没有人回答吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-12 14:24:57 | 显示全部楼层
调试的结果似乎显示输入、输出函数之间好像发生了互相干扰:

1、使用getchar函数能够顺利从usart读取单个字符,但如果后面再执行printf函数程序就会死;
2、使用scanf函数无法从usart读取数据,程序执行到这个地方就会死——看来读取多个字符是不行的。
回复 支持 反对

使用道具 举报

发表于 2014-12-12 14:35:43 | 显示全部楼层
金色黄铜 发表于 2014-12-12 14:24
调试的结果似乎显示输入、输出函数之间好像发生了互相干扰:

1、使用getchar函数能够顺利从usart读取单 ...

可以用的呀,你看看野火的rtc例程,那个程序有一个调节时间的函数用scanf来获取输入的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-12 14:58:08 | 显示全部楼层
flyleaf 发表于 2014-12-12 14:35
可以用的呀,你看看野火的rtc例程,那个程序有一个调节时间的函数用scanf来获取输入的

我试试……
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-15 09:30:05 | 显示全部楼层
flyleaf 发表于 2014-12-12 14:35
可以用的呀,你看看野火的rtc例程,那个程序有一个调节时间的函数用scanf来获取输入的

我看了一下那个程序的代码,fire 是自己写了一个名为 USART_Scanf 的函数一个字节一个字节地从串口读入数据的,不是直接调用C 语言标准的scanf 函数,更不是通过scanf 函数直接读入一个字符串。

单另自己写一个读入USART数据的函数,一个字节一个字节读,这个我也会啊。

我的疑问是:为什么直接调用C语言标准的scanf函数为什么就不好使?而printf 就好使?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-15 09:43:26 | 显示全部楼层
fire 为什么自己写了一个函数来读取USART数据,而不是直接调用scanf函数?就像直接调用printf函数那样?

是不是他也发现C语言自带的scanf 函数在STM32上不好使?
回复 支持 反对

使用道具 举报

发表于 2019-7-8 15:52:42 | 显示全部楼层
我用了野火的rtc和usart代码,同样发现scanf函数不好使,输入后丢数据,而且要输入好几次才能得到数据。楼主的问题解决了么?
回复 支持 反对

使用道具 举报

发表于 2019-7-8 17:39:42 | 显示全部楼层
夜雨声烦 发表于 2019-7-8 15:52
我用了野火的rtc和usart代码,同样发现scanf函数不好使,输入后丢数据,而且要输入好几次才能得到数据。楼 ...

重定向fgetc函数需要检测USART_IT_RXNE标志位,同时串口中断函数里也要检测这个标志位,二者冲突,所以scanf函数不好使,串口初始化时不使能中断scanf函数就好使了
回复 支持 反对

使用道具 举报

发表于 2020-4-9 10:13:18 | 显示全部楼层
夜雨声烦 发表于 2019-7-8 17:39
重定向fgetc函数需要检测USART_IT_RXNE标志位,同时串口中断函数里也要检测这个标志位,二者冲突,所以sc ...

早屏蔽了,没用,scanf函数不好使,总是有数据问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-6-24 17:38:17 | 显示全部楼层
夜雨声烦 发表于 2019-7-8 15:52
**** 作者被禁止或删除 内容自动屏蔽 ****

那就是个垃圾,别费那个劲了。

现在发现 usart 接收就“DMA+空闲中断+环形存储器(自己写)”最好使,算是目前我找到的完美方案了。

不用DMA做串口接收的代码,在工程上根本不靠谱——每个字节都中断一次,连续、大量收发数据的时候很容易出问题。
嵌入式程序编写的核心思想之一就是:中断越少越好。这对于提供程序的可靠性很最重要。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 22:27 , Processed in 0.029283 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表