打印
[C语言]

小发一帖,今天所遇问题的总结,大虾请直接无视

[复制链接]
1417|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sfesdm|  楼主 | 2014-4-27 21:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 sfesdm 于 2014-4-27 21:37 编辑

一直习惯串口的数据在中断里面发送,用一个函数来触发发送,部分代码如下:
void SendMessage(uint8_t *Addr,uint16_t Len)
{
        Send.Start = Addr;
        Send.End   = Addr+Len-1;
        USART_SendData(USART1,*Addr); //发送第一个数据
}

void USART1_IRQHandler(void)
{
        if(USART_GetITStatus(USART1,USART_IT_TC) != RESET)
        {
                if(Send.Start++ < Send.End)
                {
                        USART_SendData(USART1,*Send.Start);  //
                }
                else
                {
                        USART_ClearFlag(USART1,USART_FLAG_TC);//清零TC
                }
        }
}

今天为了观察一个16位数据的结果,于是把这个值通过串口发送出来,但是结果一直有问题,找不到问题点在哪里。于是把步骤最简化,形如下面的程序:
void fun(void)
{
    uint16_t Temp = 0x1234;
    SendMessage(uint8_t *)&Temp,2);
}
结果关擦到的数据都是0x34,0x00(小端格式的数据),百思不得其解,然后把Temp定义为全局变量,结果就正确了。。。最后终于悟出,原来如此!这跟局部变量的生存期有关!


因为调用fun函数的时候,所做的操作很少,只是调用了SendMessage函数来发送Temp的数据。
而调用SendMessage函数,只是把指针指向了Temp的地址,再触发发送一个数据,然后就算执行完函数,返回了,这个时间是非常短的。
轮到fun返回之后,因为Temp是临时变量,在函数返回之后,就可作为它用,它的值就会改变。而此时,串口可能第一个数据都还没发送完,等到发送完第一个数据,指针指向的下一个地址,数据已经改变!所以,当然发送了一个不可预料的数据了。
当把Temp定义为全局变量,或者静态变量后,它的生存期跟主程序一样长,所以,结果当然没问题。

总结:不管在实际当中,会不会真的像上面那样操作,对于指针、变量生存期等等,都要小心操作,考虑全面,不然,一不小心,这样的BUG,会搞得人欲哭无泪了。

相关帖子

沙发
coody| | 2014-4-27 22:29 | 只看该作者
一般我写程序,局部变量仅仅在本函数内有效。

使用特权

评论回复
板凳
lanmp| | 2014-4-27 23:25 | 只看该作者
你这流程问题很大,应该用全局变量Buffer缓冲。你只存头尾怎么行。

使用特权

评论回复
地板
nickyamw| | 2014-4-28 10:41 | 只看该作者
肯定要添加一个全局的发送缓冲区

使用特权

评论回复
5
diweo| | 2014-4-28 12:06 | 只看该作者
这跟函数返回指针是差不多道理

使用特权

评论回复
6
sfesdm|  楼主 | 2014-4-28 12:46 | 只看该作者
lanmp 发表于 2014-4-27 23:25
你这流程问题很大,应该用全局变量Buffer缓冲。你只存头尾怎么行。

有一个专门的全局发送区的,只是这里为了观察结果而已

使用特权

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

本版积分规则

49

主题

346

帖子

3

粉丝