STM32实例-通过操作寄存器实现流水灯效果

发布者:Alisallll最新更新时间:2023-01-04 来源: zhihu关键字:STM32  操作寄存器  流水灯效果 手机看文章 扫描二维码
随时随地手机看文章

我们需要在外部定义一个SystemInit 函数设置 STM32 的时钟;STM32 上电后,会执行 SystemInit 函数,最后执行我们 C 语言中的 main 函数。

下面就开始使用寄存器来操作 STM32 使 PC0 输出一个低电平。要操作 STM32寄存器,我们就需要使用 C 语言对其封装,这部分程序我们都放在 stm32f10x.h中。具体代码如下:

#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)

要控制 PF9 输出低电平,需知道 GPIO 这个外设它是挂接在哪个总线上的,

通过Block2外设基地址及APB2总线的偏移地址就可以得到APB2外设的基地址。

GPIO 就是挂接在 APB2 总线上的,根据 GPIOC 的偏移地址就可以得到 GPIOC 外设的基地址,GPIOC 外设内部含有很多个寄存器,比如GPIOC_CRL、GPIOC_CRH 端口配置寄存器、GPIOC_BSRR 置位复位寄存器等,通过他们各自的偏移地址就可以获取对应的寄存器地址,然后要操作地址里面的内容就需要使用到指针,将其强制转换为 unsigned int*指针类型,然后在通过一个*指针来操作该地址里面的内容。在 STM32 中凡是使用到外设功能,都要使能对应的外设时钟,否则即使配置好端口初始化也无法正常使用。因此还需要知道时钟 RCC 外设的基地址,通过数据手册“存储器映射”章节可以知道 RCC 时钟外设是挂接在 AHB 总线上, 根据其偏移值可以得到 RCC 时钟外设的基地址,然后可通过《STM32F1xx 中文参考手册》的“6 小容量、中容量和大容量产品的复位和时钟控制(RCC)”的“6.3.7 APB2 外设时钟使能寄存器(RCC_APB2ENR)”可找到对应的端口 RCC 使能寄存器,只要将 GPIOC 端口时钟使能即可。

使用 C 语言封装好寄存器后,就开始编写 main 函数。

main.c代码:

#include “stm32f10x.h”
#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)//在引用的头文件中声明过GPIOC_BASE
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)
#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)
void SystemInit(){}
u32 i;
void Delay(i)
{
while(i–);
}
int main()
{
RCC_APB2ENR =(0X01<<4); //使能时钟
while(1)
{
//D1点亮
GPIOC_CRL &= ~( 0x0F<< (4*0)); //设置推挽输出模式
GPIOC_CRL |= (3<<4*0);
GPIOC_BSRR = (0x01<<(16+0)); //PC0管脚输出低电平
Delay(0x3FFFF); //延时
GPIOC_BSRR = (0x0000ffff);//D1输出高电平
//D2亮
GPIOC_CRL &= ~( 0x0F<< (4*1));
GPIOC_CRL |= (3<<4*1);
GPIOC_BSRR = (0x01<<(16+1));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D3
GPIOC_CRL &= ~( 0x0F<< (4*2));
GPIOC_CRL |= (3<<4*2);
GPIOC_BSRR = (0x01<<(16+2));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D4
GPIOC_CRL &= ~( 0x0F<< (4*3));
GPIOC_CRL |= (3<<4*3);
GPIOC_BSRR = (0x01<<(16+3));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D5
GPIOC_CRL &= ~( 0x0F<< (4*4));
GPIOC_CRL |= (3<<4*4);
GPIOC_BSRR = (0x01<<(16+4));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D6
GPIOC_CRL &= ~( 0x0F<< (4*5));
GPIOC_CRL |= (3<<4*5);
GPIOC_BSRR = (0x01<<(16+5));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D7
GPIOC_CRL &= ~( 0x0F<< (4*6));
GPIOC_CRL |= (3<<4*6);
GPIOC_BSRR = (0x01<<(16+6));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
//D8
GPIOC_CRL &= ~( 0x0F<< (4*7));
GPIOC_CRL |= (3<<4*7);
GPIOC_BSRR = (0x01<<(16+7));
Delay(0x3FFFF);
GPIOC_BSRR = (0x0000ffff);
}
}

注意:

①包含 stm32f10x.h 头文件,在这个头文件中我们定义的都是寄存器,因此如果要在其他文件中使用这些寄存器就需要把这个头文件包含进来, 否则编译就会报错。

②SystemInit 函数,在前面讲解启动文件时已经说明,程序运行的时候先进入这个函数进行 STM32 的初始化,如果不写这个函数编译器就会报错。这里我们编写这个函数,里面并不对其操作。

③开启 GPIOC 时钟。要使 PC0 正常工作输出一个低电平,必须要打开它的时钟。RCC_APB2ENR 寄存器是在 stm32f10x.h 头文件中定义好的,只要查下《STM32F1xx 中文参考手册》RCC 时钟使能寄存器内容就可以知道此寄存器的第4 位是控制 GPIOC 外设的时钟使能位,只有该位为 1 时才使能,如果为 0 即关闭GPIOC 时钟。所以要让 1 左移 4 位。

④配置 GPIOC 为通用推完输出模式。STM32 的 GPIO 模式有很多,可根据CRx 寄存器设置,CRL 对应 GPIO 的低 8 位,CRH 对应 GPIO 的高 8 位。如果不是特殊需求,一般输出采用推挽输出模式。我们要让 PC0 管脚输出一个低电平,故使用推挽输出模式。只要查下《STM32F1xx 中文参考手册》GPIO 配置寄存器内容就可以知道此寄存器内每 4 位控制一个管脚。

⑤使 PC0 输出低电平。GPIOC_BSRR 为置位、复位寄存器,只要查下

《STM32F1xx 中文参考手册》GPIO 置位复位寄存器内容就可以知道,其高 16 位用于复位,如果当高 16 位某位为 1,表示那一位管脚输出低电平,为 0 不影响其输出电平。如果当低 16 位的某位为 1,表示那一位管脚输出高电平,为 0 不影响其输出电平。所以要让 1 左移 16+0 位。


关键字:STM32  操作寄存器  流水灯效果 引用地址:STM32实例-通过操作寄存器实现流水灯效果

上一篇:手把手教会你:使用STM32F103驱动ST7567液晶屏
下一篇:详解STM32中的ADC

推荐阅读最新更新时间:2024-11-12 14:51

STM32学习手记③-EXTI中断
用系统滴答定时器的精确定时函数,新手尽量少用,容易出错,还是用简单的延时操作好了。 抢占式优先级别与响应式优先级概念不懂,因为没看什么资料书就直接上程序了,以后有时间要看看相关方面的书。 STM的外部中断与51的不同,他的外部中断不是固定的IO口,例如,STM32有80个IO口,他每个IO口都可以映像到16个个外部中断,即PA3可以映像成外部中断1,也可以映像成外部中断2。 中断开启过程: 1、在RCC里将要使用的IO口时钟打开(为什么一定要设置RCC_APB2Periph_AFIO,不懂,待以后理解) 2、在GPIO里将该IO口映像到相应的外部中断 3、在NVIC里将该中断通道打开 中断使用注意事项:
[单片机]
STM32学习:按键控制LED
前言 涉及知识点:上下拉电阻,stm32_GPIO工作模式,stm32按键控制,GPIO电平读取,宏定义 内容:两个按键控制两个LED灯亮灭。 一、所用知识点复习 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 1、stm32工作模式(注意上下拉输入的区别) 2、按键抖动与常见按键接法 按键抖动: 按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。 抖动时间的长短由按键的机械特性决定
[单片机]
<font color='red'>STM32</font>学习:按键控制LED
STM32使用外部16MHZ晶振总结
做小封装产品设计的朋友或许知道3225-4PIN的晶振,为何8MHZ晶振批量价格要到2元一片,而16MHZ晶振只需要0.4元甚至更少。究其原因是因为3225封装的晶振目前全球最低频率一般为8MHZ,而国内8MHZ达不到精度指标,所以市场上的8MHZ晶振一般为进口晶振,因此成本被垄断。 图1 3225封装晶振 STM32单片机学习者一开始用的晶振一般是2PIN的8MHZ晶振,一旦正真做产品研发的时候,使用到3225的8MHZ晶振的话,成本是个不小的挑战。笔者现针对这个问题,提出使用16MHZ晶振代替的方法。 图2 STM32时钟树状图 由上图可以看出,如果想兼容8MHZ晶振,必须在时钟倍频前2分频。程序设计如
[单片机]
<font color='red'>STM32</font>使用外部16MHZ晶振总结
STM32实现:摄像头扫到二维码后提取二维码中的信息分别放到数组中
把想要的信息编辑好放到二维码中(网上有好多在线生成二维码的工具) char name ;//从二维码扫到的姓名:eg:weibo char ID ;//从二维码扫到的ID:eg:16208207033 //二维码解密函数 void Code_Decrypt(int admin) { strncpy(name, Usart2_buf, 5);//获取姓名 name =''; strncpy(ID, Usart2_buf+5, 11);//获取ID ID =''; } //串口2终中断(串口2接收到数据先给GetData1,再存入Usart2_buf) void USART2_IRQHan
[单片机]
stm32 I2C问题 I2C_CheckEvent()
STM32的IIC接口写的比较复杂,稍不注意,很多地方都会搞错,如果是用GPIO模拟的IIC,问题应该不大,无非应答不不应答的问题。 但是既然STM32自带IIC,并且有接口函数,干嘛不用呢 问题1: I2C_CheckEvent() 检查时停在此处: /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 问题2: 第一次读写正确后再运行程序停在此处: /* Test on EV6 and clear it */ while(!I2C_CheckEvent
[单片机]
STM32-(18):SPI与数码管(SPI)
SPI串行接口 SPI是由Motorala公司提出的一种同步串行外围接口。它在速度要求不高、低功耗、需保存少量参数的智能化传感系统中得到了广泛应用。 SPI是一个全双工的同步串行接口。在数据传输过程中,总线上只能是一个主机和一个从机进行通信。 1、MISO(Master In Slave Out) 主机输入、从机输出信号。 2、MOSI(Master Out Slave In) 主机输出、从机输入信号。 3、SCK(Serial Clock) 串行时钟信号。(用来同步使用的) 4、SS(Slave Select) 从机选择信号,低电平有效。 SPI系统连接 SPI总线可在软件的控制下构成各种简单或复杂的系统。 SPI通信
[单片机]
STM32-(18):SPI与数码管(SPI)
STM32串口通信(usart)
在开始学写STM32串口通信的代码实现前,首先先了解一下两块芯片之间通信的分类,按照数据传输方式可以分为 并行通信:数据各个位同时传输,速度快,占用引脚资源多 串行通信:数据按位传输,速度较慢,占用引脚资源少 按照数据传送的方向,可以分为 单工:只支持数据在一个方向上传输 半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信。 全双工:允许数据同时在两个方向上传输,因此全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。 串口通信就是一种串行全双工通信方式,而串行通信又可分为 同步通信:带时钟同步信号传输(如SPI , II
[单片机]
STM32-1-STM32时钟系统
在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。 在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法 如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理: 1)对于10
[单片机]
STM32-1-STM32时钟系统
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved