打印
[STM32F0]

STM32F0 系列单片机,指针取整型值错误,用F0的进来看下

[复制链接]
2524|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

STM32F0 系列单片机,指针取整型值错误,用F0的进来看下,代码如下,附件里也有个工程可以下来单步运行下,这是什么问题如何解决.

uint8_t a[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};        //定义a 数组
int main(void){
        
        uint32_t*b=0;        //指针b
        uint32_t cc;        //临时变量
        b=(uint32_t*)(a+1);        //给a的指针地址+1他        
        cc  =*b;                                        //取值这步运行就出错    //如果程序没出错cc的值应该为0x04030201,    但取值就出错
        if(cc == 1)cc=0;
        while(1){
                        
        }
}

STM32F051.rar

302.05 KB

这是F0空工程包函上面的代码.

沙发
mmuuss586| | 2015-4-19 17:44 | 只看该作者
那你现在的值是多少呢?

使用特权

评论回复
板凳
mark0668|  楼主 | 2015-4-19 20:07 | 只看该作者
mmuuss586 发表于 2015-4-19 17:44
那你现在的值是多少呢?

看图

1.jpg (80.69 KB )

执行到这

执行到这

2.jpg (65.36 KB )

再执行就到这出错了

再执行就到这出错了

使用特权

评论回复
地板
mark0668|  楼主 | 2015-4-19 20:09 | 只看该作者

我把这代码放到F4 运行可以正确取值不会出错,F0 就这样出错了

使用特权

评论回复
5
FAQ| | 2015-4-19 20:39 | 只看该作者

使用特权

评论回复
6
FAQ| | 2015-4-19 20:42 | 只看该作者
应该不是F0的问题,直接让b指向的地址为0就是错误的。

使用特权

评论回复
7
mark0668|  楼主 | 2015-4-19 20:45 | 只看该作者

int main(void){
       
       
        uint32_t cc=4;        //临时变量
        uint32_t*b=&cc;        //指针b
        b=(uint32_t*)(a+2);        //给a的指针地址+1他       
        cc  =b[0];                                        //取值这步运行就出错
        if(cc == 1)cc=0;
        while(1){
                       
        }

}

按你这方法刚试了,结果还是一样

使用特权

评论回复
8
john_lee| | 2015-4-19 21:01 | 只看该作者
对齐问题。
在cortex-m0上,总线对访问内存数据是有一个对齐约束的:访问32位内存数据,该数据必须对齐到32位地址;访问16位内存数据,该数据必须对齐到16位地址,否则访问时将导致 hard fault。
你定义的 a 数组,链接器应该是将其对齐到了 32 位(或 16 位)地址,那么 a + 1 的地址,显然不满足访问的总线约束。

使用特权

评论回复
9
mark0668|  楼主 | 2015-4-19 21:27 | 只看该作者
确实是,能被 4整除的地址取值没有问题,有没有这M0 这方面更详细的内容?在哪里写有?

使用特权

评论回复
10
戈卫东| | 2015-4-19 22:25 | 只看该作者
本帖最后由 戈卫东 于 2015-4-19 22:26 编辑

对齐问题。M0不允许非对齐的访问,M4允许。
把小的类型的指针转换成大的类型的指针都会出现这个异常。

使用特权

评论回复
11
zyj9490| | 2015-4-19 23:56 | 只看该作者
*b={0x01,0x02,0x03,0x04}

使用特权

评论回复
12
mark0668|  楼主 | 2015-4-20 00:01 | 只看该作者
zyj9490 发表于 2015-4-19 23:56
*b={0x01,0x02,0x03,0x04}

你这个什么意思?

使用特权

评论回复
13
zyj9490| | 2015-4-20 00:04 | 只看该作者
mark0668 发表于 2015-4-19 20:45
int main(void){
       
       

好多非法操作,对C指针非法使用,导致的,B[0]应表示成:*(b+0),才是因为B不是数组名。

使用特权

评论回复
14
zyj9490| | 2015-4-20 00:07 | 只看该作者
mark0668 发表于 2015-4-20 00:01
你这个什么意思?

指针操作的四字节的数。CC不会等于1的。

使用特权

评论回复
15
mark0668|  楼主 | 2015-4-20 00:25 | 只看该作者
本帖最后由 mark0668 于 2015-4-20 00:29 编辑
zyj9490 发表于 2015-4-20 00:07
指针操作的四字节的数。CC不会等于1的。

能被4整除的地址是可以取值的,所以代码是没问题的
例如:b=(uint32_t*)(a+4);  这样是可以的, b的指针地址为0x20000000   这样是可以取值, 0x20000001  这样就不行.

使用特权

评论回复
16
SLHSu37| | 2015-4-20 08:03 | 只看该作者
这编程风格··java

使用特权

评论回复
17
ticomi| | 2015-4-20 08:07 | 只看该作者
指针,无论是全局还是局部,不可用悬空,在定义时一定要让其指向一个位置(地址),否则极容易出现问题。

使用特权

评论回复
18
justtest111| | 2015-4-20 08:46 | 只看该作者
typedef __packed struct
{
        uint8_t num;
}ARRAY;
ARRAY a[20];
试试这种。

使用特权

评论回复
19
dami| | 2015-4-20 09:01 | 只看该作者
本帖最后由 dami 于 2015-4-20 09:02 编辑

uint32_t*b=0;        //指针b 错了。

uint8_t a[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};        //定义a 数组
int main(void){
        
        uint32_t*b;        //指针b
        b =&a[0];
        uint32_t cc;        //临时变量
        b=a+1;        //给a的指针地址+1他        
        cc  =*b;                                        //取值这步运行就出错    //如果程序没出错cc的值应该为0x04030201,    但取值就出错
        if(cc == 1)cc=0;
        while(1){
                        
        }
}

使用特权

评论回复
20
lvyunhua| | 2015-4-20 12:07 | 只看该作者
b=a+1;        //给a的指针地址+1他   

应该是这里问题,改成b++试试。

使用特权

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

本版积分规则

14

主题

421

帖子

2

粉丝