打印

奇怪!STM32 串口 使用 scanf 缺一位!!!

[复制链接]
12016|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 lw30402048 于 2012-8-22 22:35 编辑

首先说明一下,我使用的芯片是STM32F103ZE,编译环境是 IAR6.40,3.5的库,然后自己参照网上的写了串口重映射,即 printf 和 scanf,printf实验成功,但是 使用 scanf 时,比如PC上 通过串口助手输入 1123,那么STM32接受后,返回确实 123,第一个1就丢失了,不知道是什么原因?还请那位大侠 指点下。 附件是我自己建的 工程,还包括了 串口助手 发送数据的截图,还请大家有空 实验下,只需5分钟的时间,再次谢谢 关注的朋友。

STM32 USART-printf重定向-scanf缺位待解决.rar

3.32 MB

沙发
lw30402048|  楼主 | 2012-8-22 22:28 | 只看该作者
本帖最后由 lw30402048 于 2012-8-23 19:49 编辑

调用的函数 分别是:
// printf 相关
int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    USART_SendData(USART1, (uint8_t) ch);
   
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {}
   
    return ch;
}
// scanf 相关
int fgetc(FILE *f)
{
    // 等待串口1输入数据
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {}
   
    return (int)USART_ReceiveData(USART1);
}

使用特权

评论回复
板凳
lw30402048|  楼主 | 2012-8-22 22:31 | 只看该作者
其中 fputc 与 printf 相关, fgetc和scanf相关
上面2个函数 在MDK 调用时正常;
可 到了IAR 当使用scanf时 就不正常,不知为啥?
那位高手解答下哈

附件有我的工程,IAR6.40,3.5的库,我都弄好了,那位有空可以试试看,用的串口1

使用特权

评论回复
地板
lw30402048|  楼主 | 2012-8-22 22:32 | 只看该作者
晚上 21IC怎么这么慢,上传的附件都这么慢。。。

使用特权

评论回复
5
lw30402048|  楼主 | 2012-8-22 22:45 | 只看该作者
串口 发送的数据,及STM32的回复

usart.JPG (54.6 KB )

usart.JPG

使用特权

评论回复
6
lw30402048|  楼主 | 2012-8-22 22:46 | 只看该作者
上面可以看到, 输入 1123,回复却是 123

使用特权

评论回复
7
lw30402048|  楼主 | 2012-8-22 22:48 | 只看该作者
对了,工程里面的程序,while(1)循环里,
应该是
printf("input 3 number a,b,c :\r\n");
        
        scanf("%d", &a);
        printf("a=%d\r\n",a);
        //scanf("%d", &b);
        //scanf("%d", &c);
        //printf("a=%d, b=%d, c=%d\r\n",a,b,c);
才是上面的结果!

使用特权

评论回复
8
IJK| | 2012-8-23 09:34 | 只看该作者
先看看buffer里的数是否收全。

使用特权

评论回复
9
lw30402048|  楼主 | 2012-8-23 19:51 | 只看该作者
先看看buffer里的数是否收全。
IJK 发表于 2012-8-23 09:34


你的意思是看
// scanf 相关
int fgetc(FILE *f)
{
    // 等待串口1输入数据
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {}
   
    return (int)USART_ReceiveData(USART1);
}
里面的USART_ReceiveData(USART1)吗? 这是调系统的函数,但是你说的接受的 buffer 不知道 系统是哪个?还请 赐教

使用特权

评论回复
10
lw30402048|  楼主 | 2012-8-23 20:10 | 只看该作者
我观察了下 是不是 库函数用int型的,而我只输入1的话,只有一个字节的原因?
但是 我输12,他就回 2,还是不对呀
有谁 知道吗?解答下哈

使用特权

评论回复
11
lw30402048|  楼主 | 2012-8-23 20:10 | 只看该作者
// scanf 相关
int fgetc(FILE *f)

使用特权

评论回复
12
杜专| | 2012-8-23 21:49 | 只看该作者
查晶振把  串口丢数据情况不多一般都是晶振引起的, 不要用用32K时钟 用晶振时钟

使用特权

评论回复
13
lxj19901115| | 2012-8-24 11:45 | 只看该作者
数据类型出错,int 应该称u8

使用特权

评论回复
14
lw30402048|  楼主 | 2012-8-25 11:53 | 只看该作者
12# 杜专
我串口接收用中断方式,一个都不丢的!串口配置 一模一样

使用特权

评论回复
15
lw30402048|  楼主 | 2012-8-25 11:54 | 只看该作者
13# lxj19901115 试过 没有

使用特权

评论回复
16
xu84403451| | 2012-12-11 21:53 | 只看该作者
int fgetc(FILE *f)
{
             while(!(USART2->SR&1<<5));
      return (uint16_t)(USART2->DR & (uint16_t)0x01FF);
}

我这是串口二,这么写我就好使了。

使用特权

评论回复
17
wuxi_stl| | 2013-1-17 10:44 | 只看该作者
我昨天也遇到同样的问题,
搜索后得到这样的帖子:
https://my.st.com/public/STe2eco ... mp;currentviews=782

解释如下:
There are two different sets of runtime libraries provided:
● The IAR DLIB Library, which supports ISO/ANSI C and C++. This library also
supports floating-point numbers in IEEE 754 format and it can be configured to
include different levels of support for locale, file descriptors, multibytes, et cetera.
● The IAR CLIB Library is a light-weight library, which is not fully compliant with
ISO/ANSI C. Neither does it fully support floating-point numbers in IEEE 754
format or does it support Embedded C++. (This library is used by default).

Migration from CLIB to DLIB
There are some considerations to have in mind if you want to migrate from the CLIB
library, the legacy C library, to the modern DLIB C/C++ library:
● The CLIB exp10() function defined in iccext.h is not available in DLIB.
● The DLIB library uses the low-level I/O routines __write and __read instead of
putchar and getchar.
● If the heap size in your old compiler version using CLIB was defined in a file
named heap.c, you must now set the heap size either in the extended linker
command file (*.xcl) or in the Embedded Workbench to use the DLIB library.

Source: http://supp.iar.com/FilesPublic/ ... ferenceAddendum.pdf

The compiler comes with the IAR DLIB Library, a complete library, compliant with
Standard C and C++. This library also supports floating-point numbers in IEEE 754
format and it can be configured to include different levels of support for locale, file
descriptors, multibyte characters, et cetera.

Source: http://supp.iar.com/FilesPublic/ ... opmentGuide.ENU.pdf

我重写函数__read()后,可以解决lz的问题。

使用特权

评论回复
18
wuxi_stl| | 2013-1-17 14:19 | 只看该作者
size_t __read(int Handle, unsigned char *Buf, size_t BufSize)
{
  size_t nChars = 0;
  
  if (Handle != 0)
  {
        return -1;
  }
  for(/*EMPTY*/; BufSize > 0; --BufSize)
  {
        unsigned char c = NULL;
       
        // 等待串口1输入数据
        while(!(USART1->SR&1<<5));
        c = (unsigned char)(USART1->DR & (uint16_t)0x01FF);
       
        if(c == 0)
          break;
        *Buf++ = c;
        ++nChars;
  }
  return nChars;
}

使用特权

评论回复
19
紫辰晓风| | 2013-4-26 17:38 | 只看该作者
串口发送的时候 把检测的标志位 USART_FLAG_TC 改成 USART_FLAG_TXE就好使了,我们以前也遇到过。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

140

帖子

1

粉丝