OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4205|回复: 24

printf函数用不了

[复制链接]

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
发表于 2018-7-10 11:27:20 | 显示全部楼层 |阅读模式
2金钱
单片机:STM32F103C8T6,串口:USART1

我照着原子哥例程在usart.h中 #include "stdio.h"
然后在usart.c中加入如下代码:
#if 1
#pragma import(__use_no_semihosting)            

struct __FILE
{
        int handle;

};

FILE __stdout;      

_sys_exit(int x)
{
        x = x;
}

int fputc(int ch, FILE *f)
{      
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    USART_SendData(USART1,(u8) ch);        
        return ch;
}
#endif


最后在如下代码使用printf函数,但是串口助手没任何反应:
void USART1_IRQHandler(void)
{
        u8 Res;
        if(USART_GetITStatus(USART1,USART_IT_RXNE))
        {
                Res=USART_ReceiveData(USART1);
                if(Res==1)
                {
                        LED();
                        printf("完成");       
                }
               
        }
}

最佳答案

查看完整内容[请看2#楼]

怎么在中断跑流水灯啊你,在中断程序设置标志位在主函数跑吧,中断不要执行这么多操作,我还以为是亮灯呢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-10 11:27:21 | 显示全部楼层
午夜狼嚎 发表于 2018-7-12 09:04
就是一个流水灯函数;

怎么在中断跑流水灯啊你,在中断程序设置标志位在主函数跑吧,中断不要执行这么多操作,我还以为是亮灯呢
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-10 15:14:48 | 显示全部楼层
你串口助手发送“1”了吗
回复

使用道具 举报

1

主题

119

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1998
金钱
1998
注册时间
2013-10-7
在线时间
329 小时
发表于 2018-7-10 15:24:59 | 显示全部楼层
打开调试,在串口中断函数中打断点,看下是否触发进入中断
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-10 17:25:40 | 显示全部楼层
qiuzhicheng 发表于 2018-7-10 15:14
你串口助手发送“1”了吗

发了的
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-10 17:25:57 | 显示全部楼层
浪花雷雨 发表于 2018-7-10 15:24
打开调试,在串口中断函数中打断点,看下是否触发进入中断

进了的
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165538
金钱
165538
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-7-11 02:41:52 | 显示全部楼层
你应该在主函数里面,调用printf,试试。 先验证下你的串口能否正常收发。
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-11 08:27:47 | 显示全部楼层
正点原子 发表于 2018-7-11 02:41
你应该在主函数里面,调用printf,试试。 先验证下你的串口能否正常收发。

原子哥工作这么晚吗?凌晨3点了,,白天上班怎么办
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 09:13:00 | 显示全部楼层
正点原子 发表于 2018-7-11 02:41
你应该在主函数里面,调用printf,试试。 先验证下你的串口能否正常收发。

我在主函数里面每100ms直接调用可以打印。但为什么在中断函数里面不行呢?
while(1)
        {
       
                        delayms(100);
                        printf("你好");       
               
        }
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-11 10:06:50 | 显示全部楼层
void USART1_IRQHandler(void)
{
        u8 Res;
        if(USART_GetITStatus(USART1,USART_IT_RXNE))
        {
                printf("完成");   
                Res=USART_ReceiveData(USART1);              
        }
串口随便发数据,看会不会打印
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 12:32:44 | 显示全部楼层
qiuzhicheng 发表于 2018-7-11 10:06
void USART1_IRQHandler(void)
{
        u8 Res;

这样也可以,为什么呢?
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-7-11 12:55:16 | 显示全部楼层
qiuzhicheng 发表于 2018-7-11 08:27
原子哥工作这么晚吗?凌晨3点了,,白天上班怎么办

看球了。
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-7-11 13:01:25 | 显示全部楼层
看看收到的数据是否真的是1.
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-7-11 13:12:36 | 显示全部楼层
Res是u8类型,而1显然是int。并且从助手发送1的实际数据是0x31。应该是:if(Res == 0x31)
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 17:00:52 | 显示全部楼层
xiatianyun 发表于 2018-7-11 13:12
Res是u8类型,而1显然是int。并且从助手发送1的实际数据是0x31。应该是:if(Res == 0x31)

接收到的是1,LED的相关操作也能实现,就是printf没反应。但是像9楼那样换一下顺序,就能打印了,还没想明白
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-11 17:13:33 | 显示全部楼层
午夜狼嚎 发表于 2018-7-11 17:00
接收到的是1,LED的相关操作也能实现,就是printf没反应。但是像9楼那样换一下顺序,就能打印了,还没想 ...

1加双引号试一下
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-11 17:16:50 | 显示全部楼层
把LED();去掉
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-7-11 17:33:57 | 显示全部楼层
午夜狼嚎 发表于 2018-7-11 17:00
接收到的是1,LED的相关操作也能实现,就是printf没反应。但是像9楼那样换一下顺序,就能打印了,还没想 ...

接收到的是1?
你用什么来知道的?如果调试应当把数据显示模式换成int而不是char。具体我没有看。
我刚才试验了,确实必须是0x31。
如果你的助手用16进制发送1,则没有问题。
如果是字符发送,1就是0x31,判断也应该是0x31。或者像楼上说的把字符1转换为int。
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 17:36:43 | 显示全部楼层

这样也可以。但是现在关键是已经确认支持printf函数的相关定义是没问题的,printf函数可以用。可为什么我在中断处理函数里面用不了
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 17:39:39 | 显示全部楼层
xiatianyun 发表于 2018-7-11 17:33
接收到的是1?
你用什么来知道的?如果调试应当把数据显示模式换成int而不是char。具体我没有看。
我刚 ...

我用在线调试看的,接收到的就是1,并且在判断里面有个LED处理函数,LED相关操作是正常进行的,如果接收到的不是1,是不会有任何LED操作的,调试助手是用16进制发的。
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-7-11 18:29:26 | 显示全部楼层
午夜狼嚎 发表于 2018-7-11 17:39
我用在线调试看的,接收到的就是1,并且在判断里面有个LED处理函数,LED相关操作是正常进行的,如果接收 ...

问题出在fputc()函数。
我看了教程里的fputc()和你的不一样。
[mw_shl_code=c,true]//重定义fputc函数
int fputc(int ch, FILE *f)
{      
        while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
        return ch;
}[/mw_shl_code]
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-11 19:26:29 | 显示全部楼层
xiatianyun 发表于 2018-7-11 18:29
问题出在fputc()函数。
我看了教程里的fputc()和你的不一样。
[mw_shl_code=c,true]//重定义fputc函数  ...

大哥,真的很感谢您认真为我解答问题。但是第一,您看懂了这段代码表示的意思了吗?学一下寄存器吧。第二,printf函数的相关支持定义是没问题的,printf函数是可以使用的。只是现在在中断函数里不能使用
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-12 08:07:53 | 显示全部楼层
午夜狼嚎 发表于 2018-7-11 17:36
这样也可以。但是现在关键是已经确认支持printf函数的相关定义是没问题的,printf函数可以用。可为什么我 ...

去掉可以就是你这句有问题了,你这句是什么操作
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-12 09:04:56 | 显示全部楼层
qiuzhicheng 发表于 2018-7-12 08:07
去掉可以就是你这句有问题了,你这句是什么操作

就是一个流水灯函数;
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-7-12 10:21:42 | 显示全部楼层
qiuzhicheng 发表于 2018-7-12 09:17
怎么在中断跑流水灯啊你,在中断程序设置标志位在主函数跑吧,中断不要执行这么多操作,我还以为是亮灯呢

恍然大悟啊。我流水灯进入了死循环,出不来了,所以无法执行printf。感谢指点,这个问题真的是,一开始我找问题的方向就错了。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-15 13:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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