1. 按键亮灯
设计 GPIO 实验项目 1,功能:当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮。
实验要求基于寄存器的GPIO配置,所以需要手动操作寄存器来配置时钟和输入输出模式(如果不要求,在cubemx里可以直接配置)。
跑马灯和按键KB1,KB2的端口模式为推挽输出和输入,因此需要编程将它们设置为对应的模式:
参考下面的端口位配置表,
一个端口占用配置寄存器的四位来设置工作模式,可以知道CRL(0-7(低八位)的引脚对应CRL配置寄存器)里输出跑马灯和输入按键KB1,KB2的每个端口应配置为:0011(16进制0x3)和0100(16进制0x4)
那么,使用 CubeMX 创建工程,只设置芯片选型、 系统时钟、调试端口; GPIO 配置在程序中通过寄存器配置完成。
按键按下为低电平,所以检测 数据输入寄存器(GPIOx_IDR)与(&)上对应位为1的数的 结果,比如PE0就是与 0x01。
if((GPIOE->IDR&0X01)==0){
flag=1;
}
else if((GPIOE->IDR&0X02)==0){
flag=2;
}
功能是 当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮,因为跑马灯是高电平点亮,就是数据输出寄存器 GPIOF_ODR 对应位 置为1,D0闪亮的话就是对这一位不断取反,这一位异或1其他位异或0即可。
if(flag==1){
GPIOF->ODR|=0XFF;
}
else if(flag==2){
GPIOF->ODR^=0X01;
HAL_Delay(50);
}
主要代码如下:
#flag设为全局变量,方便调试查看
int flag=0;
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
RCC->APB2ENR|=1<<7;//使能PORTF时钟
GPIOF->CRL&=0X00000000;
GPIOF->CRL|=0X33333333;//PF.0-PF.7推挽输出
GPIOF->ODR=0X00;//清除显示
RCC->APB2ENR|=1<<6;//使能PORTE时钟
GPIOE->CRL&=0X00;
GPIOE->CRL|=0X44;//PE.0-PE.1开漏输入
while (1)
{
if((GPIOE->IDR&0X01)==0){
flag=1;
}
else if((GPIOE->IDR&0X02)==0){
flag=2;
}
else flag=0;
if(flag==1){
GPIOF->ODR|=0XFF;
}
else if(flag==2){
GPIOF->ODR^=0X01;
HAL_Delay(50);
}else{
GPIOF->ODR=0X00;
}
}
}
2.顺时针方向旋转的跑马灯
实现顺时针方向旋转的跑马灯,跑马灯延时 0.2 秒。按照灯的顺序,将GPIOF_ODR 对应位 置为1。
基于寄存器:
RCC->APB2ENR|=1<<6;
GPIOE->CRL&=0X00000000;
GPIOE->CRL|=0X44;
//while里
for(int i=0;i<8;i++){
GPIOF->ODR=0X01<<i;
//这里的延时不是0.2s,自行调整
for(int k=0;k<100000;k++);
}
HAL库:
uint16_t x=0x0001;
for(int i=0;i<8;i++){
//GPIOF->ODR=0X01<<i;
//for(int k=0;k<100000;k++);
HAL_GPIO_WritePin(GPIOF,x<<i,1);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOF,x<<i,0);
}
3.按键控制跑马灯方向
编写程序,当按键 KB1 按下时,跑马灯按顺时针方向旋转,按下 KB2 时,跑马灯 按逆时针方向旋转。
结合前两者代码,为了方便,逆时针用新的变量y=0x0080 右移 来选择八个灯的引脚。
RCC->APB2ENR|=1<<6;
GPIOE->CRL&=0X00000000;
GPIOE->CRL|=0X44;
uint16_t x=0x0001;
uint16_t y=0x0080;
while (1)
{
if((GPIOE->IDR&0X01)==0){
flag=1;
}
else if((GPIOE->IDR&0X02)==0){
flag=2;
}
else if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_6)==0){
flag=3;
}
//else flag=0;
if(flag==1){
for(int i=0;i<8;i++){
HAL_GPIO_WritePin(GPIOF,x<<i,1);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOF,x<<i,0);
}
}
else if(flag==2){
for(int i=0;i<8;i++){
HAL_GPIO_WritePin(GPIOF,y>>i,1);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOF,y>>i,0);}
}else if(flag==3){
}else{
GPIOF->ODR=0X00;
}
}
}