ReceiveData = *(u32 *)&SPI2_RxBUF[1];
ReceiveData = *((u32 *)&SPI2_RxBUF[1]);
对于C语言来说语法上没什么区别,*与& 都是同等优先级,结合方式从右到左。
这两句都是取SPI2_RxBUF[1]的地址,强制转换为32位地址指针,取指针即可得到32位数据,然后赋值给ReceiveData。
先看一段代码
可以看到程序运行之后:ReceiveData = 0x00010000 这是Windows下QT的编译环境
那么再看一段Keil中STM32仿真时的代码
程序运行到了265行,但是处于262行的等式,可以发现他们并不相等。keil编译环境,
ReceiveData = *(u32 *)&SPI2_RxBUF[1]; 该等式ReceiveData值为0x00000000,高位直接被编译器舍弃了。
ReceiveData = *((u32 *)&SPI2_RxBUF[1]); 该等式ReceiveData才是0x00010000,需要加上括号才可以,才成功被赋值。
所以C语言的语法,对于初学者可以大致熟悉即可,不用像教科书那样去抠字眼,考试那样去做题,具体优先级直接加括号实际些。
这个问题我还找了好久才发现,一开始一直以为是SPI数据传输是不是出现了问题,一步步检查还花费了不少时间。
有朋友可能注意到:赋值的时候有两种写法
ReceiveData = *((u32 *)&SPI2_RxBUF[1]);
ReceiveData = (u32)SPI2_RxBUF[2]<<16 | SPI2_RxBUF[1];
基于当前的平台我们可以知道它是小端序。
unsigned short int SPI2_RxBUF[4] = {0x0000,0x0000,0x0001,0xffff};
地址//0x20004000 0x20004002 0x20004004 0x20004006
数据//0x0000, 0x0000, 0x0001, 0xffff
第一种写法
//mov 直接取地址,(u32 *)0x20004002 去取32位数据 1个机器周期
//mov 赋值
第二种写法
//栈,R0 R1 R2 ... R7 CPU内部的寄存器, N个机器周期,耗时间
//mov R1 0x0001
//左移的汇编指令,移16位,
//mov R2 0x0000
//或 R1 R2
//mov 赋值
哈哈,我的汇编不好,只知道大概的意思,简单来书如果是连续内存存储的,直接用取地址的方式快一些,简单而且方便。
如有不对之处望海涵及留言告知。一起学习共同进步
邮箱:fifteenpeng@163.com
——十五