STM32单片机(四)-编程要点

同一优先级的运算符,运算次序由结合方向所决定。

简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

注意:sizeof是运算符,不要与函数混淆。

二 结合方向

 运算符的结合性:

   C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。例如算术运算符的结合性是自左至右,即先左后右。如有表达式 x-y+z则 y 应先与“-”号结合,执行 x-y 运算,然后再执行+z 的运算。这种自左至右的结合方向就称为“左结合性”。而自右至左的结合方向称为“右结合性”。  最典型的右结合性运算符是赋值运算符。如 x=y=z,由于“=”的右结合性,应先执行 y=z 再执行 x=(y=z)运算。C语言运算符中有不少为右结合性,应注意区别,以避免理解错误。

x << 1 得到的结果是左移1位后的值,它被保存在一个临时变量中,与x无关,即x的值不变。
x <<= 1 相当于 x = x << 1,是将x左移1位以后的值保存回x中,x发生了变化。 

GPIOE->ODR|=1<<5;      怎么理解呢?

1、先把1看做十六进制,0x01即0000 0001,1<<5,0x01左移5位变为,0x20即0010 0000

2、再进行 | 或运算,0x20与GPIOE->ODR进行或运算,就是对第五位进行置1,其它位不变。

3、赋值=,把刚刚或运算后的值,赋值给GPIOE->ODR

C语言中*(volatile unsigned int *)0x500的解释:

如下;

(unsigned int *)0x500:将地址0x500强制转化为int型指针,注意现在是指针类型,所以它必须有数据类型,0x500只是地址值。

可以访问sizeof(unsigned int)长的字节数据。
*(unsigned int *)0x500=0x10:对地址为0x500赋值为0x10

使用一个32位处理器,要对一个32位的内存地址进行访问,可以利用宏定义这样定义

  #define RAM_ADDR     (*(volatile unsigned long *)0x0000555F)//先强制转换为unsigned int类型指针,然后再通过*访问。

 然后就可以用C语言对这个内存地址进行读写操作了
 读:tmp = RAM_ADDR;//tmp=*(0x0000555F)
 写:RAM_ADDR = 0x55;

volatile   易变的

volatile是一个类型限定符,如const一样

volatile变量可变允许除了程序之外的比如硬件来修改他的内容

变量如果加了 volatile 修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。

访问该数据任何时候都会直接访问该地址处内容,即通过cache提高访问速度的优化被取消 
对于((volatile unsigned long ) 0xE0028000)为随硬件需要定义的一种地址,前面加上“”指针,为直接指向该地址,整个定义约定符号IOPIN代替,调用的时候直接对指向的地址寄存器写内容既可。这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。上述表达式拆开来分析,首先(volatile unsigned long *) 0xE0028000的意思是把0xE0028000强制转换成volatile unsigned long类型的指针,暂记为p,那么就是#define A *p,即A为P指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作

一篇不错的文章

C语言再学习 -- 关键字volatile

https://blog.csdn.net/qq_29350001/article/details/54024070

地址的定义

文章

https://www.cnblogs.com/wp2312139418/p/5869181.html

设置GPIOB_0输出为高电平

#define GPIOB 0x40010C00

#define GPIOx_ODR 0x0c

#define GPIOB_ODR *((volatile unsigned int *)(GPIOB + GPIOx_ODR))

//重点是这里的意思,先把GPIOB_ODR地址计算出来,再转换为 unsigned int类型指针 ,那么就可以通过指针GPIOB_ODR访问地址为0x40010C00+0x0c里面的4个字节的值了。
(unsigned int 的大小跟操作系统有关,如果是STM32的话,就是32位的,占四个字节,寄存器不正好32位的吗,所以才强制转换为unsigned int)

GPIOB_ODR |= 1 << 0;//1左移0位,也是1,赋值给0x40010C0c地址开始的四个字节
即0x40010C0c的四个字节的值为0x00000001

stm32 寄存器组起始地址

 

 

猜你喜欢

转载自blog.csdn.net/fzf1996/article/details/88602876