打印
[STM32F1]

求助,串口助手发送一串字符,比如10个,但只能收到第一个字符,后面的丢失,求原因!

[复制链接]
9766|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhlzbl|  楼主 | 2014-9-25 23:02 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如题,我使用stm32F103,通过pc机串口助手发送一串字符,约10个字符,结果通过printf显示,只能进一次串口接收中断,也就是只能收到第一个字符,然后就不会继续进入中断了,造成后面的9个字符丢失,求高手分析原因及解决办法。谢谢!!!!!!!
沙发
zhlzbl|  楼主 | 2014-9-26 08:45 | 只看该作者
顶贴! 没人知道么??

使用特权

评论回复
板凳
qq4988| | 2014-9-26 08:58 | 只看该作者
是中断接收吗?最好把程序贴上来,大家一起找问题

使用特权

评论回复
地板
xlsbz| | 2014-9-26 09:02 | 只看该作者
最好的方法是先到网上找个例子 网上那么多例子 肯定能有好用的。
然后再慢慢研究。

使用特权

评论回复
5
zhlzbl|  楼主 | 2014-9-26 09:08 | 只看该作者
qq4988 发表于 2014-9-26 08:58
是中断接收吗?最好把程序贴上来,大家一起找问题

对,usart1的中断接收。程序如下:
uint8_t WL433_rec_data[128];
void USART1_IRQHandler(void)
{
        static uint16_t i = 0,maxlen=0;;
        printf("uart1-interrupt..aa\n");
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);//clear interrupt flag
                printf("i = %d\n",i);
                WL433_rec_data[i++] = (uint8_t)USART_ReceiveData(USART1);
                USART_SendData(USART1,WL433_rec_data[i-1]);
                if(i>=128)
                   i = 0;
        }
}
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;  
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃÓÅÏȼ¶·Ö×é2(3,3)£¬Ö»ÐèÉèÖÃÒ»´Î
       
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //ͨµÀÉèÖÃΪ´®¿Ú1ÖжÏ
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //ÖжÏÕ¼Ïȵȼ¶0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //ÖжÏÏìÓ¦ÓÅÏȼ¶0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //´ò¿ªÖжÏ
        NVIC_Init(&NVIC_InitStructure);                             //³õʼ»¯
}
void USART_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;
    USART_ClockInitTypeDef USART_ClockInitStructure;

        //usart ͬ²½Ê±ÖÓclk³õʼ»¯£¬ÒòΪûÓÐÓõ½Í¬²½Í¨ÐÅģʽ£¬¹ÊCR2¼Ä´æÆ÷.11=USART_Clock_Disableµô¼´¿É¡£
    USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
    USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
    USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                     
    USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
    USART_ClockInit(USART1, &USART_ClockInitStructure);//uart4&5²»Ö§³Öͬ²½Ê±ÖÓ
    USART_ClockInit(USART2, &USART_ClockInitStructure);//
    USART_ClockInit(USART3, &USART_ClockInitStructure);//
       
        //USART1 for WL433
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    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);
       
     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//½ÓÊռĴæÆ÷²»Îª¿ÕÖжÏʹÄÜ       
}

使用特权

评论回复
6
diweo| | 2014-9-26 09:56 | 只看该作者
先把printf去掉再说吧。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
zhlzbl + 1 很给力!
7
Ketose| | 2014-9-26 09:57 | 只看该作者
楼主最好不要在接收中断是调用发送。而且USART_SendData发送是没有做发送完成判断的。如果发太快就有可能丢数据。

使用特权

评论回复
8
liuyuqiong1| | 2014-9-26 10:14 | 只看该作者
zhlzbl 发表于 2014-9-26 09:08
对,usart1的中断接收。程序如下:
uint8_t WL433_rec_data[128];
void USART1_IRQHandler(void)

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//½ÓÊռĴæÆ÷²»Îª¿ÕÖжÏʹÄÜ  怎么没开发送使能?

使用特权

评论回复
9
zhlzbl|  楼主 | 2014-9-26 10:18 | 只看该作者
Ketose 发表于 2014-9-26 09:57
楼主最好不要在接收中断是调用发送。而且USART_SendData发送是没有做发送完成判断的。如果发太快就有可能丢 ...

关键现在程序只能进一次接收中断,而且程序现在已经加入了对发送完成的标志的判断。
另外,是示波器观察,可以看到stm32的rx是多个字节的数据,但每个字节后都有一个脉冲即停止位。
弱弱的问一句,停止位应该是在字符串最后只有一个,还是每个字节都有一个停止位呢?

使用特权

评论回复
10
zhlzbl|  楼主 | 2014-9-26 10:20 | 只看该作者
liuyuqiong1 发表于 2014-9-26 10:14
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//½ÓÊռĴæÆ÷²»Îª¿ÕÖжÏʹÄÜ   ...

发送使用的轮训检查标志的方式,没有用发送中断方式,这个应该没有影响。

使用特权

评论回复
11
liuyuqiong1| | 2014-9-26 10:25 | 只看该作者
zhlzbl 发表于 2014-9-26 10:20
发送使用的轮训检查标志的方式,没有用发送中断方式,这个应该没有影响。 ...

void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;  
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃÓÅÏȼ¶·Ö×é2(3,3)£¬Ö»ÐèÉèÖÃÒ»´Î
        
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //ͨµÀÉèÖÃΪ´®¿Ú1ÖжÏ
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //ÖжÏÕ¼Ïȵȼ¶0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //ÖжÏÏìÓ¦ÓÅÏȼ¶0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //´ò¿ªÖжÏ
        NVIC_Init(&NVIC_InitStructure);                             //³õʼ»¯
}你这个定义了,好像没用~~~

        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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(WR_USART, &USART_InitStructure);
        USART_ClearFlag(WR_USART,USART_FLAG_TC);
        USART_ITConfig(WR_USART, USART_IT_RXNE, ENABLE);
          USART_ITConfig(WR_USART, USART_IT_TXE, DISABLE);

        NVIC_Configuration();
        USART_Cmd(USART1, ENABLE);你这样试试       

使用特权

评论回复
12
qq4988| | 2014-9-26 10:30 | 只看该作者
你把接收中断中的发送语句都去掉试一下哦

使用特权

评论回复
13
liuyuqiong1| | 2014-9-26 10:35 | 只看该作者
zhlzbl 发表于 2014-9-26 10:18
关键现在程序只能进一次接收中断,而且程序现在已经加入了对发送完成的标志的判断。
另外,是示波器观察 ...

你发后又等那个USART_FLAG_TC释放?while((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET);

使用特权

评论回复
14
zhlzbl|  楼主 | 2014-9-26 10:41 | 只看该作者
qq4988 发表于 2014-9-26 10:30
你把接收中断中的发送语句都去掉试一下哦

现在把中断发送的语句都屏了,仍然不行。
尝试把IRQ中的printf全部关闭,再main中判断flag并打印接收的到字符串,结果可以了,看来是和IRQ中加printf有关系!!可以原来做别的项目时,用stm32的平台,也都在串口中断中加了很多printf,都可以用。
为啥这次就不行呢,奇怪!!

使用特权

评论回复
15
zhlzbl|  楼主 | 2014-9-26 10:41 | 只看该作者
liuyuqiong1 发表于 2014-9-26 10:35
你发后又等那个USART_FLAG_TC释放?while((USART1->SR & USART_FLAG_TC) == (uint16_t)RESET);

已经把发送相关的调用都关闭了,也不行。
尝试把IRQ中的printf全部关闭,再main中判断flag并打印接收的到字符串,结果可以了

使用特权

评论回复
16
zhlzbl|  楼主 | 2014-9-26 10:43 | 只看该作者
diweo 发表于 2014-9-26 09:56
先把printf去掉再说吧。

尝试把IRQ中的printf全部关闭,再main中判断flag并打印接收的到字符串,结果真的可以了。原来别的项目也在串口中断中加了printf,没有问题呢,为啥这次就不行呢???求原因!

使用特权

评论回复
17
qq4988| | 2014-9-26 10:55 | 只看该作者
zhlzbl 发表于 2014-9-26 10:41
现在把中断发送的语句都屏了,仍然不行。
尝试把IRQ中的printf全部关闭,再main中判断flag并打印接收的到 ...

你现在是接收一个字节,就发送一串字符,接收一个字节就发送一串,发送一串,太占时间了吧,以前也是这样做的吗?

使用特权

评论回复
18
zhlzbl|  楼主 | 2014-9-26 11:36 | 只看该作者
qq4988 发表于 2014-9-26 10:55
你现在是接收一个字节,就发送一串字符,接收一个字节就发送一串,发送一串,太占时间了吧,以前也是这样 ...

IRQ是接收一个字节,发送一个字节,不是发送一串字符,连续接收多次字节,也就是连续发送多个字节。
另外,我加的发送函数是临时测试用的,最终会关闭并在主函数中加入发送的函数。

使用特权

评论回复
19
qq4988| | 2014-9-26 11:40 | 只看该作者
你这一句是发送一串啊

11.jpg (18.88 KB )

11.jpg

使用特权

评论回复
20
zhlzbl|  楼主 | 2014-9-26 11:55 | 只看该作者
qq4988 发表于 2014-9-26 11:40
你这一句是发送一串啊

你是说printf的使用相当于发送了一串对么?
printf使用的usart2,接收是usart1,不是同一个串口。
把此处的printf关闭后,就可以正常接收字符串啦~!的确是printf惹的祸!吼吼~

使用特权

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

本版积分规则

1

主题

12

帖子

0

粉丝