野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 29502|回复: 16

关于第一个例程,流水灯,我这样写为什么就不能运行了呢?

[复制链接]
发表于 2014-1-15 13:57:16 | 显示全部楼层 |阅读模式
本帖最后由 hkhkdyx 于 2014-1-15 17:04 编辑

改动后的截图,仅仅把GPIO_InitStructure变为 *GPIO_InitStructure, 然后把GPIO_InitStructure.GPIO_Mode
改为了GPIO_InitStructure->GPIO_Mode,把GPIO_Init(GPIOB, &GPIO_InitStructure);改为GPIO_Init(GPIOB, GPIO_InitStructure); 编译器也没报错,为什么下载到板子就不能运行了呢?希望高手指点迷津啊。
QQ截图20140115135503.png
此贴问题已经解决!
非常感谢各位的指教,问题已经查清,原因是没有初始化指针,导致变成野指针。解决办法是把指针初始化一下就行了。
再次感谢“yinhao”哥们,
“定义了一个结构体:GPIO_InitTypeDef GPIO_InitStructure;
你的GPIO_Init(GPIOB, &GPIO_InitStructure);
实际上是 GPIO_InitTypeDef* GPIO_InitStruct = &GPIO_InitStructure; 这样的赋值过程
就是用这个函数的参数里的这个指针指向了那个结构体的实体。所以你一开始应该定义一个结构体,然后取地址作为函数的参数。”
非常精辟解释了为什么直接定义结构体,而不用结构体指针的原因。

PS:用指针的办法实现整理:
void LED_GPIO_Config(void)
{       
                // 声明外部函数 malloc 和 free
                extern void *malloc(unsigned int num_bytes);
                extern void free(void *ptr);
               
                /*定义一个GPIO_InitTypeDef类型的结构体指针*/
                GPIO_InitTypeDef *GPIO_InitStructure;
                GPIO_InitStructure = (GPIO_InitTypeDef*) malloc (sizeof(GPIO_InitTypeDef));
       
                /*开启GPIOB和GPIOF的外设时钟*/
                RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE);

                /*选择要控制的GPIOB引脚*/                                                                                                                          
                GPIO_InitStructure->GPIO_Pin = GPIO_Pin_0;       

                /*设置引脚模式为通用推挽输出*/
                GPIO_InitStructure->GPIO_Mode = GPIO_Mode_Out_PP;   

                /*设置引脚速率为50MHz */   
                GPIO_InitStructure->GPIO_Speed = GPIO_Speed_50MHz;

                /*调用库函数,初始化GPIOB*/
                GPIO_Init(GPIOB, GPIO_InitStructure);       
               
                /*选择要控制的GPIOF引脚*/                                                                                                                          
                GPIO_InitStructure->GPIO_Pin = GPIO_Pin_7;

                /*调用库函数,初始化GPIOF7*/
                GPIO_Init(GPIOF, GPIO_InitStructure);
               
                /*选择要控制的GPIOF引脚*/                                                                                                                          
                GPIO_InitStructure->GPIO_Pin = GPIO_Pin_8;

                /*调用库函数,初始化GPIOF7*/
                GPIO_Init(GPIOF, GPIO_InitStructure);                          

                /* 关闭所有led灯        */
                GPIO_SetBits(GPIOB, GPIO_Pin_0);
               
                /* 关闭所有led灯        */
                GPIO_SetBits(GPIOF, GPIO_Pin_7|GPIO_Pin_8);         

                // 释放内存
                free(GPIO_InitStructure);
}
回复

使用道具 举报

发表于 2014-1-15 14:06:58 | 显示全部楼层
“GPIO_InitStructure变为 *GPIO_InitStructure” 这个错了,这样就相当于搞了个野指针,没有实体,把 *号去掉吧
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:16:03 | 显示全部楼层
没有对指针初始化,指针乱指,出错
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:16:11 | 显示全部楼层
施叶丰 发表于 2014-1-15 14:06
“GPIO_InitStructure变为 *GPIO_InitStructure” 这个错了,这样就相当于搞了个野指针,没有实体,把 *号去 ...

我也知道这样不行,可是为什么不能定义为结构体指针?   看库函数里面对GPIO_Init的定义  void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)  第二个参数就是定义为结构体指针。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:16:55 | 显示全部楼层
丁玉 发表于 2014-1-15 14:16
没有对指针初始化,指针乱指,出错

如何把这个指针初始化下呢
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:18:28 | 显示全部楼层
哈哈  楼主想玩指针吗? 你定义了个指针变量,但是没有指向任何实体。
楼主一定要这么玩的话,可以加上:
GPIO_InitStructure = (GPIO_InitTypeDef*) malloc (sizeof(GPIO_InitTypeDef));
为它申请内存。但是最后记得free掉: free(GPIO_InitStructure);
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:19:15 | 显示全部楼层
hkhkdyx 发表于 2014-1-15 14:16
如何把这个指针初始化下呢

malloc ,推荐楼主搜索一下什么叫 野指针
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:23:28 | 显示全部楼层
yinhao 发表于 2014-1-15 14:18
哈哈  楼主想玩指针吗? 你定义了个指针变量,但是没有指向任何实体。
楼主一定要这么玩的话,可以加上:
...

安装你说的  真的跑起来了,编译的时候有2条警告
..\..\User\Led\bsp_led.c(30): warning:  #223-D: function "malloc" declared implicitly
..\..\User\Led\bsp_led.c(65): warning:  #223-D: function "free" declared implicitly
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:25:30 | 显示全部楼层
hkhkdyx 发表于 2014-1-15 14:23
安装你说的  真的跑起来了,编译的时候有2条警告
..\..\User\Led\bsp_led.c(30): warning:  #223-D: fun ...

要这两个函数的添加头文件  malloc.h
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:30:03 | 显示全部楼层
红舒扬 发表于 2014-1-15 14:25
要这两个函数的添加头文件  malloc.h

请教如何在keil里面加载 malloc和free这2个关键字啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:30:21 | 显示全部楼层
红舒扬 发表于 2014-1-15 14:25
要这两个函数的添加头文件  malloc.h

请教如何在keil里面加载 malloc和free这2个关键字啊
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:36:44 | 显示全部楼层
extern void *malloc(unsigned int num_bytes);
extern void free(void *ptr);
在文件的开头加上这两句就不会出现警告了。
原因是在从别的文件用了这两个函数而没有申明它。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 14:39:14 | 显示全部楼层
yinhao 发表于 2014-1-15 14:36
extern void *malloc(unsigned int num_bytes);
extern void free(void *ptr);
在文件的开头加上这两句就 ...

强烈支持,非常感谢哥们   哥,你太帅啦,高手啊!
回复 支持 反对

使用道具 举报

发表于 2014-1-15 14:51:24 | 显示全部楼层
hkhkdyx 发表于 2014-1-15 14:16
我也知道这样不行,可是为什么不能定义为结构体指针?   看库函数里面对GPIO_Init的定义  void GPIO_Init ...

这里要教育你一下了。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
一个函数的参数是结构体指针,这是为了访问你传递的结构体。
你定义了一个结构体:GPIO_InitTypeDef GPIO_InitStructure;
你GPIO_Init(GPIOB, &GPIO_InitStructure);
实际上是 GPIO_InitTypeDef* GPIO_InitStruct = &GPIO_InitStructure; 这样的赋值过程
就是用这个函数的参数里的这个指针指向了那个结构体的实体。
所以你一开始应该定义一个结构体,然后取地址作为函数的参数。
当然,你喜欢定义一个指针,并为他申请空间,然后用这个指针直接作为函数的参数也行。但是普遍用上面的做法。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 16:55:39 | 显示全部楼层
yinhao 发表于 2014-1-15 14:51
这里要教育你一下了。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
一个 ...

帅呆了,赞一个    “实际上是 GPIO_InitTypeDef* GPIO_InitStruct = &GPIO_InitStructure;”你这句话让我豁然开朗了!  知道了为什么要直接定义一个结构体变量。   
GPIO_InitTypeDef* GPIO_InitStruct = &GPIO_InitStructure;”
我是这么理解这句话的:等价于
GPIO_InitTypeDef* GPIO_InitStruct;
GPIO_InitStruct=&GPIO_InitStructure;
回复 支持 反对

使用道具 举报

发表于 2014-1-15 17:15:36 | 显示全部楼层
void fun(int *p);
int a;
fun(&a);
int *b = (int*) malloc (sizeof(int));
fun(b);
这两种方式都行,都是把变量本身传递给函数,在函数里是可以修改变量的。
void fun2(int p2);
fun2(a);
这样是把变量a的数据作为参数传递给函数使用,函数无法修改到变量a。
这是参数定义为指针变量的作用。
由于mollac之后如果不free掉,内存将不会释放,如果一直运行可导致崩溃。
所以用mollac要谨慎!mollac用在必须动态申请内存的场合,平时不建议使用。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-15 18:06:11 | 显示全部楼层
yinhao 发表于 2014-1-15 17:15
void fun(int *p);
int a;
fun(&a);

xiexie~~
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 13:48 , Processed in 0.048794 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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