stm32跑马灯——寄存器和位操作
作者:互联网
寄存器版:
GPIO基础:
每组io口有7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。
硬件连接:
例如:
由上图1可知:要使用到LED0和LED1,他们的IO口分别为PB5和PE5
由上图2可知:要使用到LED0和LED1,他们的IO口分别为PA8和PD2
GPIO的输出模式为推挽输出。
代码:
- 使能IO口时钟:配置寄存器RCC APB2ENR.
- 初始化IO口模式:配置寄存器GPIOx CRH/CRL
- 操作IO口,输出高低电平:配置寄存器GPIOX_ODR或者BSRR/BRR.
这里采用上图1的的原理图:
led.h:
#ifndef __LED_H //避免重复引用
#define __LED_H
void LED_Init(void);//LED初始化函数,无入口参数
#endif
led.c:
#include "led.h"
#include "stm32f10x.h"//引用顶层头文件,否则函数不可用
void LED_Init(void)
{
//使能GPIO时钟
//寄存器有很多位,运用下列方法操作其中一位:
RCC->APB2ENR|=1<APB2ENR|=1<CRL&=0xFF0FFFFF;//与运算:先将位清零
GPIOB->CRL|=0x00300000;//或运算:设置50MHz速度和推挽输出
GPIOB->ODR|=1<CRL&=0xFF0FFFFF;
GPIOE->CRL|=0x00300000;
GPIOB->ODR|=1<<5;
}
main.c:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
int main(void)
{
delay_init();//调用延时函数
LED_Init();
while(1){
//设置高电平
GPIOB->ODR|=1<ODR|=1<ODR|=~(1<ODR|=~(1<<5);
//运用非运算,是1全为0,0全为1
delay_ms(500);//设置延时500ms
}
}
位操作版:
位带操作
原理和过程:支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的,例如BSRR寄存器有32个位,那么可以映射到32个地址上,我们去访问(读-改-写)这32个地址就达到访问32个比特的目的。
哪些区域支持位操作:
在 CM3 中有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设 区的最低 1MB 范围。
每个有效区有32比特,每个比特映射一个地址。(通过改变映射地址32位的0/1来操作比特)
这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”。(每个比特膨胀为32位的地址)
代码:
led.h:
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PBout(5)// PB5
#define LED1 PEout(5)// PE5
void LED_Init(void);//初始化
#endif
led.c:
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高
}
main.c:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
int main(void)
{
delay_init();//调用延时函数
LED_Init();
while(1){
//设置高电平
PBout(5)=1;
PEout(5)=1;
delay_ms(500);//设置延时500ms
//设置低电平
PBout(5)=0;
PEout(5)=0;
delay_ms(500);//设置延时500ms
}
}
本文转载自:http://blog.bools.cn/archives/424
标签:位操作,LED,32,void,led,stm32,跑马灯,GPIO,include 来源: https://blog.csdn.net/SumubeiFZ/article/details/119065309