打印
[STM32F1]

其实还是C语言的问题+keil

[复制链接]
2137|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lqab1983|  楼主 | 2013-12-2 15:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32F103VEt6  keil4.23

typedef  struct{
        double  latitude;  //经度
        double  longitude; //纬度
        int     latitude_Degree;        //度
        int                latitude_Cent;                //分
        int           latitude_Second;    //秒
        int     longitude_Degree;        //度
        int                longitude_Cent;                //分
        int           longitude_Second;   //秒
        float         speed;      //速度
        float         direction;  //航向
        float         height_ground;    //水平面高度
        float         height_sea;       //海拔高度
        int     satellite;        //卫星数
        uchar         NS;
        uchar         EW;
        DATE_TIME D;
}GPS_INFO;     
GPS_INFO GPS;
char *context = NULL; context = (char*)malloc(2048);
memcpy(context, &(GPS), sizeof(GPS_INFO));
BD1_TXSQ(123456,context);

int BD1_TXSQ(u32 Dest_Address, char *context)
{
        memcpy(txsq_buff+17,context,context_lens);
        free(context);
}

这是我程序的相关部分,我就奇怪了,为什么一执行到memcpy 即memcpy(context, &(GPS), sizeof(GPS_INFO));就程序死了!

谁能帮帮我
沙发
ayb_ice| | 2013-12-2 16:07 | 只看该作者
都不检查内存分配成功的吗,明显的不符合要求嘛
极有可能根本就没有内存可以分配,这需要配置好堆的,有些需要初始化,看手册吧

使用特权

评论回复
板凳
airwill| | 2013-12-2 17:49 | 只看该作者
楼上分析得有道理.
建议不要随便使用 malloc. 考虑使用静态分配, 比如直接定义
char   context[2048];

使用特权

评论回复
地板
hkcj| | 2013-12-2 17:50 | 只看该作者
有可能就是内存分配的问题   楼主   仔细查一查   看看   这一块   我也不是很熟悉啊   

使用特权

评论回复
5
lqab1983|  楼主 | 2013-12-3 09:23 | 只看该作者
谢谢你们啊,我试用数组后,确实就没问题了。肯定是内存分配的问题。但是想知道怎么进行内存检查啊。。。

使用特权

评论回复
6
SLHSu37| | 2013-12-3 09:30 | 只看该作者
malloc用起来不是很爽··
还是直接定义数组吧

使用特权

评论回复
7
lqab1983|  楼主 | 2013-12-3 10:03 | 只看该作者
还有就是 我memcpy后  我想把结构体里各种类型的数据 按十六进制发送出去  可以吗 ?

int BD1_TXSQ(u32 Dest_Address, const char *context)
{
        u8 i;
        u8 checknum_txsq = 0;
        int context_lens = 0;
        int txsq_lens = 0;
        char txsq_buff[300] = {0};
         
         //协议头 40bit
         txsq_buff[0] = '$';
         txsq_buff[1] = 'T';
         txsq_buff[2] = 'X';
         txsq_buff[3] = 'S';
         txsq_buff[4] = 'Q';

         //电文长度
         context_lens = strlen(context);
         
         //协议长度
         txsq_lens = context_lens + 18;
         txsq_buff[5] = (txsq_lens) >> 8;
         txsq_buff[6] = txsq_lens & 0xff;
         
         //本机地址
         txsq_buff[7] = ICXX.localID[0];
         txsq_buff[8] = ICXX.localID[1];
         txsq_buff[9] = ICXX.localID[2];         
         
         //信息类别
         txsq_buff[10] = 0x46;         //0100 0110
       
        //目的地址
        txsq_buff[11] = Dest_Address >> 16;
        txsq_buff[12] = Dest_Address >> 8;
        txsq_buff[13] = Dest_Address & 0xff;

        //电文长度
        txsq_buff[14] = context_lens >> 8;
        txsq_buff[15] = context_lens & 0xff;
                                                                               
        //是否应答
        txsq_buff[16] = 0x00;

        //电文内容
        memcpy(txsq_buff+17,context,context_lens);
       
        //校验和
        for(i = 0; i < txsq_lens - 1; i++)
        {
                checknum_txsq ^= txsq_buff[i];
        }
        txsq_buff[txsq_lens-1] = checknum_txsq;
       
        //串口3发送
        for(i = 0;i < txsq_lens; i++)
        {
                USART_ClearFlag(USART3,USART_FLAG_TC);
                USART_SendData(USART3,txsq_buff[i]);
                  while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
                  {;}
        }
        return 1;
}
我怎么 不出数据了?

使用特权

评论回复
8
lqab1983|  楼主 | 2013-12-3 11:16 | 只看该作者
在keil 中使用malloc()函数经常会遇到不正常的情况,通常表现为不能正确分配内存空间,或者只能分配很小的空间。

出现这个问题的原因大概有三个:

1、所用的ARM芯片本身内存已经被其代码占用,所余空间不够malloc分配。

解决办法:A、释放其他代码浪费的RAM空间;B、扩容。

2、未进行堆的初始化:在KEIL中使用malloc函数时,必需要对heap进行初始化,否则不能正常使用malloc。

解决办法:A、使用KEIL自带的启动代码,该汇编启动代码本身已经完成了对heap的初始化;(我们通常建立的工程都是使用KEIL自带的启动代码,或者在该基础上修改的代码,所以这个问题基本上不用考虑)

B、自己编写heap初始化汇编代码,该初始化代码必须放在调用C代码之前,最好放在启动代码中。

3、堆空间太小。

解决办法:在堆初始化代码中,将堆大小增加,一般0x400大小足够,如果不够的话,可根据实际调试情况进行增加。

使用特权

评论回复
9
lqab1983|  楼主 | 2013-12-3 11:18 | 只看该作者
再问个问题  我用串口3发送  能否把结构体里这些乱七八糟的类型 数据发出来?
for(i = 0;i < txsq_lens; i++)
        {
                USART_ClearFlag(USART3,USART_FLAG_TC);
                USART_SendData(USART3,txsq_buff[i]);
                  while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
                  {;}
        } 可以吗?   
我存的结构体内容是   FE 43 FA ED EB AC A8 40 B4 C8 76 BE 2F 24 C7 40 1F

使用特权

评论回复
10
hdp7891000| | 2013-12-3 12:24 | 只看该作者
可以,两边都强制类型转换

使用特权

评论回复
11
sun98703855| | 2013-12-3 14:06 | 只看该作者
不明觉厉。

使用特权

评论回复
12
122541325| | 2013-12-3 19:42 | 只看该作者
貌似可以吧,要强制转换 的

使用特权

评论回复
13
m__dd| | 2013-12-3 20:10 | 只看该作者
lqab1983 发表于 2013-12-3 11:16
在keil 中使用malloc()函数经常会遇到不正常的情况,通常表现为不能正确分配内存空间,或者只能分配很小的 ...

(char*)malloc(2048)。“一般0x400大小足够”,明显不够。

使用特权

评论回复
14
香水城主| | 2013-12-4 10:13 | 只看该作者
使用动态内存分配,一般要求实际的内存容量是最大需要容量之和的150~200%,甚至更多。如果每次要求分配的容量越大,每次分配要求的容量差别越大,则上述比例也越大,这种现象的原因就是动态分配产生的内存碎片化问题。

在单片机这种资源紧缺的环境下,建议不要使用动态内存分配,应该使用静态分配,或使用栈空间,即函数的局部变量。

使用特权

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

本版积分规则

17

主题

53

帖子

0

粉丝