自学stm32的第一课,使用寄存器点亮第一个LED,对于代码还是有些疑问,好在已经解决,做个记录。
首先看如下代码:
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC_CRL (unsigned int)(GPIOC_BASE+0x00)
#define GPIOC_CRH (unsigned int)(GPIOC_BASE+0x04)
#define GPIOC_IDR (unsigned int)(GPIOC_BASE+0x08)
#define GPIOC_ODR (unsigned int)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR (unsigned int)(GPIOC_BASE+0x10)
#define GPIOC_BRR (unsigned int)(GPIOC_BASE+0x14)
#define GPIOC_LCKR (unsigned int)(GPIOC_BASE+0x18)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define RCC_APB2ENR (unsigned int)(RCC_BASE+0x18)
此处定义了GPIOC的地址及时钟的地址,这个就不再多做讨论,具体看下面几行代码:
RCC_APB2ENR|=1<<4; //开启GPIOC端口时钟
GPIOC_CRL&=`(0x0f<<(4*0)); //用1与原封不动的保留,用零与的话全部是零,所以保留了前四位,清零了后四位
GPIOC_CRL|=(3<<(4*0)); //用0或原封不动的保留。
注意此处代码的理解,要首先清楚与或运算的规则:
与:两个都为1,结果才为1.
那么可以得出以下结论:
1&任何数=任何数
0&任何数=0
则用(~0x0f)即0xf0即11110000相与时,可以知道,高四位被保留,低四位被清零。故此可以理解GPIOC_CRL&=`(0x0f<<(4*0));
又此处执行后,GPIOC_CRL的值的高四位被保留,低四位清零,又因或:只要有一个为1则为1。那么可以知道:
1|任何数=1
0|任何数=任何数
用xxxx0000与00000001按位或,则可以知道前7位被保留,最后一位变成1.故此可以理解 GPIOC_CRL|=(3<<(4*0));