本文以PA0端口输出高低电平为例介绍一些简单的用法。单纯的介绍一下&与|的在赋值时的用法,不介绍所用到的寄存器的原因。
如文章有错或有描述不清的地方欢迎大家批评,指正。
通过查阅手册可知,GPIOA的时钟使能位为APB2外设时钟使能寄存器的位2。
以下有两种方式为寄存器赋值:
RCC->APB2ENR |= 0x0004; //第一种 RCC->APB2ENR = RCC->APB2ENR | 0x0004;
RCC->APB2ENR |= 1<<2; //第二种 RCC->APB2ENR = RCC->APB2ENR | (1<<2);
如果直接将4直接赋值给寄存器,那么除了位2其它位也会受到影响,那么RCC_APB2ENR中的16位将会变为0x0004,所以赋值时为了避免影响其它位,应采用&=或者|=的赋值方式。这样既可避免非操作位受到影响,又可将操作位赋值为1。
其中第二种方式实际上就是001左移2位后转换为了100,在数值上与0x4是相等的,但显然第二种更方便一些,不用进行二进制、十进制与十六进制之间的一些转换,便可以进行某些位的操作。
使能时钟后,接下来要进行GPIO寄存器中某些寄存器的配置。
首先进行相关参数的配置,将PA0设置为通用推挽输出,速度为50MHz。
GPIOA->CRL &= 0xFFFFFFFF0; //GPIOA->CRL = GPIOA->CRL & 0xFFFFFFFF0;
GPIOA->CRL |= 0x000000003; //GPIOA->CRL = GPIOA->CRL | 0x000000003;
先将PA0对应的位0~位3置0,再进行设置。此方式中有个特点就是需要将其它无须操作的位也要一并写出,虽然直接赋值可以一次性配置多个IO口,但如果仅仅只是对一个端口进行配置个人感觉还是比较繁琐,所以可以采用下面这种方式进行赋值:
GPIOA->CRL &= 0x0<<(4*n); //GPIOA->CRL = GPIOA->CRL & (0x0<<(4*n));
GPIOA->CRL |= 0x3<<(4*n); //GPIOA->CRL = GPIOA->CRL | (0x3<<(4*n));
因为4bit才表示配置一个端口,所以0x0表示要把对应端口的4个bit置0,乘4表示一次要移动4位(4个bit,一个端口),n代表着在CRL寄存器中的端口数,如果是在CRH寄存器中需将端口数-8后填入。本例中n为0。其中0x3根据自己需要配置的模式,算出对应的十六进制修改即可。
配置完IO口后进行相应输出。简单总结了两种方式,各有特点。第一种较为简洁,第二种格式化比较明显。
GPIOA->ODR |= 1<<0; //置1 GPIOA->ODR = GPIOA->ODR | (1<<0);
GPIOA->ODR &= ~(1<<0); //置0 GPIOA->ODR = GPIOA->ODR & (~(1<<0));
GPIOA->ODR |= 0x0000|(1<<0); //置1 GPIOA->ODR = GPIOA->ODR | (0x0000|(1<<0));
GPIOA->ODR &= 0xFFFF&(0<<0); //置0 GPIOA->ODR = GPIOA->ODR & (0xFFFF&(0<<0));