其他分享
首页 > 其他分享> > stm32跑马灯——寄存器和位操作

stm32跑马灯——寄存器和位操作

作者:互联网

寄存器版:

GPIO基础:

file

每组io口有7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。
file

硬件连接:

例如:
file
由上图1可知:要使用到LED0和LED1,他们的IO口分别为PB5和PE5
file
由上图2可知:要使用到LED0和LED1,他们的IO口分别为PA8和PD2

GPIO的输出模式为推挽输出。

代码:

这里采用上图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 范围。
file
每个有效区有32比特,每个比特映射一个地址。(通过改变映射地址32位的0/1来操作比特)
file
这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”。(每个比特膨胀为32位的地址)
file

代码:

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