ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-07-24 23:00:20  阅读:309  来源: 互联网

标签:位操作 LED 32 void led stm32 跑马灯 GPIO include


寄存器版:

GPIO基础:

file

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

硬件连接:

例如:
file
由上图1可知:要使用到LED0和LED1,他们的IO口分别为PB5和PE5
file
由上图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 范围。
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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有