栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32-寄存器编程-使用寄存器点亮LED

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32-寄存器编程-使用寄存器点亮LED

一、工程文件的建立

1、我们建立一个”工程模板“文件夹,在它下面在新建4个文件夹

Listing存放编译器编译适合产生的C/汇编/链接的列表信息
Project存放工程
Output存放编译产生的调用信息、hex文件、预览信息、封装库等
User存放用户编写的驱动文件

2、打开keil5点击Project新建一个工程放到我们刚建的”工程模板“文件夹中的Project中命名按喜好来就行,这里建议使用英文。

3、 在弹出的界面中我们选中F1系列中103中的任意一款芯片,这里我选的STM31F103R6,因为我们用的Proteus仿真中有这款芯片,等下可以仿真。

4、我们在Project视图栏里对Source Group 1 右击我们的鼠标Add New一个c文件名字随意就好这里建议英文。

 5、我们到keil5的根目录下找到此路径下的启动文件夹这里看你安装在哪里了

 我这里就不详细介绍这些启动文件了这里给张表想要更深的了解这些东西关注我后面我会更新STM32启动文件详解。

启动文件区别
startup_stm32f10x_ld.sld:low-density 小容量,Flash容量为16 ~ 32K
startup_stm32f10x_md.smd:medium-density中容量,Flash容量为64 ~ 128K
startup_stm32f10x_hd.shd:high-density大容量,Flash容量为256 ~ 512K
startup_stm32f10x_xl.sxl:超大容量,Flash容量为512K ~ 1024K
以上4种都属于基本型
startup_stm32f10x_cl.scl:connectivity line devices 互联型
startup_stm32f10x_ld_vl.svl:value line devices 超值型系列
startup_stm32f10x_md_vl.s
startup_stm32f10x_hd_vl.s

6、这里我用的是startup_stm32f10x_ld.s,把他复制到我们建立的工程文件夹中的User文件夹并在我们的工程里添加它。

7、我们可以看看这个启动文件,详细的我会在后面更新的STM32启动文件详解中介绍这里我们只看我们等下需要的部分,找到这个函数Reset_Handler

 129行定义了一个子程序:Reset_Handler。 PROC是子程序定义伪指令。这里就相当于C语言中定义了一个函数,函数名是Reset_Handler。

130行EXPORT表示Reset_Handler这个子程序可以被其他模块调用。相当于C语言中对函数进行声明。[WEAK]表示弱定义,如果编译器发现在别的地方定义了同名的函数,则在链接时用别处的地址进行链接。

131、132行的TMPORT表示定义的标号在其他文件中,在链接的时候需要到其他文件中去寻找。用C语言来解释从其他文件引入函数声明。以便下面对外部函数调用。

SystemInit是需要我们自己实现,需要编写一个同名称的函数,用来初始化STM32的时钟,用来时STM32达到稳定运行。这个函数固件库里有但我们寄存器编程的化还是要写的(但这个函数只要写个空的同名函数就行了,只要骗过编译器我们已经写了,里面可以不用写东西。STM32在我们没有配置时钟的时候会自己使用内部的系统时钟)关注我在后面更新的时钟章节会详细介绍

_main不用我们定义(不要与C语言中的主函数main混淆了)这是一个C库函数,该函数主要功能是:初始化栈、堆,配置系统环境,并在函数最后调用用户编写的主函数,从此进入C的环境。

133行把SystemInit的地址写入到寄存器R0。

134行程序跳转到R0中执行程序,就是执行SystemInit函数。

135行吧_main的地址写入到寄存器R0。

136行程序跳转到R0中执行程序,就是执行_main函数。

137程序结束。

8、看完启动文件我们就可以开始写我们的代码了,哪我们该怎么动手呢,看过我前篇文章STM32-存储器和寄存器中知道,寄存器就是就是给一个已经分配好地址的特殊内存空间的一个别名,既然是地址那么我们就可以用C语言中的指针来操作它。那么我们来实现寄存器映射(不知到什么意思可以翻看我前面STM32-存储器和寄存器文章)。

stm32f10x.h头文件

#ifndef _STM32F103_H_
#define _STM32F103_H_


#define PERIPH_BASE         ((unsigned int) 0x40000000)


#define APB2PERIPH_BASE     (PERIPH_BASE+0x10000)


#define AHBPERIPH_BASE      ((unsigned int)0x40020000)


#define GPIOB_PERIPH_BASE   (APB2PERIPH_BASE+0x0c00)


#define RCC_BASE     (AHBPERIPH_BASE+0x1000)


#define GPIO_CRL            *(unsigned int*)(GPIOB_PERIPH_BASE+0x00)
#define GPIO_ODR            *(unsigned int*)(GPIOB_PERIPH_BASE+0x0c)
#define GPIO_BSRR           *(unsigned int*)(GPIOB_PERIPH_BASE+0x10)
#define GPIO_BRR            *(unsigned int*)(GPIOB_PERIPH_BASE+0x14)


#define RCC_APB2ENR        *(unsigned int*)(RCC_BASE+0x18)

#endif

这里我吧手册中的存储器印象地址放这里详情可以查看手册STM32FXX手册  https://pan.baidu.com/s/1sk1_DSbL5ZV33I7zqzJEsg 
提取码:pyj1

 寄存器的地址就是在外设GPIOB的地址上加上地址偏移,可以在手册中查看比如CRL(端口配置低寄存器)就是GPIOB_PERIPH_BASE(GPIOB外设基地址)+0x00(偏移地址)后面几个寄存器以此类推。

 main主函数

#include "stm32f103.h"
int main()
{
    
	RCC_APB2ENR|=((1)<<3);

    
	GPIO_CRL&=~((0x0f)<<(4*0));

    
	GPIO_CRL|=((1)<<(4*0));

    
	GPIO_ODR |= (0<<0);

}
void SystemInit()  
{

}

1、开启GPIO端口时钟

2、 配置PB0为通用推挽输出,速度为10MHz

3、 PB0输出低电平

9、编译后我们来看看仿真结果可以看出来LED已经被点亮了

其实寄存器编程和固件库编程本质上都一样都是配置各种寄存器,可以看我前面的文章STM32-固件库编程点亮LED对照的看一下,关注我后面我会更新STM32所有特色外设的介绍,STM32时钟篇章

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920228.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号