用寄存器HAL库完成LED流水灯程序
用寄存器HAL库完成LED流水灯程序
重庆交通大学信息科学与工程学院
《嵌入式系统开发》课程
作业报告(第4周)
班 级: 通信工程2001
姓名-学号 : 阎桂董-6200700622
实验项目名称: 作业题目
实验项目性质: 设计性
实验所属课程: 《嵌入式系统开发》
实验室(中心): 南岸校区语音大楼
指 导 教 师 : 娄路
完成时间: 2022 年 10 月 12 日
一、实验内容和任务
用寄存器&HAL库完成LED流水灯程序
二、实验要求
1. 分组要求:每个学生独立完成,即1人1组。
2. 程序及报告文档要求:具有较好的可读性,如叙述准确、标注明确、截图清晰等。
.项目代码上传github,同时把项目完整打包为zip文件,与实验报告(Markdown源码及PDF文件)、作业博客地址一起提交到学习通。
三. 实验过程介绍
1、学习和理解STM2F10系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)2、假设你手中已有 STM2最小系统核心板(STM2F10C8T6)面板板只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。
1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;
2)用C语言 寄存器方式编程实现。
)安装 stm2CubeMX,用cubemx完成初始化过程,采用HAL库编程实现。
4)在Keil下用软件仿真运行上面代码,并用虚拟逻辑观察 对应管脚上的输出波形(高低电平转换),看是否是1秒的周期。
四、STM2F10系列芯片的地址映射和寄存器映射原理
1、寄存器
1)寄存器是中央处理器内的组成部分。 寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。
2)简单来说,寄存器就是存放东西的一个空间器物。寄存器可能存放的是指令、数据或地址。
)按照功能的不同,可将寄存器分为基本寄存器和移位寄存器两大类。基本寄存器只能并行送入数据,也只能并行输出。移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入、并行输出,也可以串行输入、串行输出,还可以并行输入、串行输出,或串行输入、并行输出,十分灵活,用途也很广。
4)存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。
5)指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。
2、地址映射和寄存器映射原理
1)地址映射:由百度词条可知为了保证CPU执行指令时可正确访问存储单元,需将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址,这一过程称为地址映射。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U9EAQihu-166851411809)(C:\Users\ASUS\Desktop\屏幕截图 2022-10-1 22121.png)]
2)寄存器映射:在存储器的区域单元中,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。
五、GPIO端口的初始化设置三步骤
GPIO(英语:General-purpose input/output),通用型之输入输出的简称,功能类似8051的P0—P,其接脚可以供使用者由程控自由使用,PI脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。
既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;对于其他特殊功能,则有另外的寄存器来控制它们。
1、GPIO端口初始化设置
1)GPIO初始化步骤:
第一步:使能GPIOx口的时钟。
第二步:指明GPIOx口的哪一位,这一位的速度大小以及模式。
第三步:调用GPIOx初始化函数进行初始化。
第四步:调用GPIO-SetBits函数,进行相应位的置位
2、时钟定义
stm2的时钟是由内部或外部振荡器产生的“频率”,而被人们形象的称为“系统时钟”。最大为72MHz换成周期T为:1/72MHz≈1.9ns,其决定了程序执行的速度,给芯片提供一个稳定的执行频率。
、输入输出模式设置
上拉电阻:把不确定的信号通过电阻连接到高电平信号初始化为高电平
下拉电阻:把不确定的信号通过电阻连接到低电平信号初始化为低电平
上拉输入:会经过上拉电阻,从而初始化成高电平,通过ttl施密特触发器(将模拟信号转变为数字信号)数字信号单片机可识别,从而单片机可以开始读
下拉输入:会经过下拉电阻,从而初始化成低电平,通过ttl施密特触发器(将模拟信号转变为数字信号)数字信号单片机可识别,从而单片机可以开始读
浮空输入:引脚不接高低电平,引脚浮空,他可以直接通过ttl施密特触发器,所以它的电压是不确定的(通常用于iic,usart)
模拟输入:不经过上拉电阻和下拉电阻,也不通过施密特触发器,直接到外设模块模拟输入,用于ad转换,用于 ADC
开漏输出:可以输出高电平和低电平,但是如果需要得到高电平需要上拉电阻才行,通过输出数据寄存器到输出控制电路,经过mos管才到gpio口
开漏复用输出:是用复用功能进行输出,通过输出数据寄存器到输出控制电路,经过mos管才到gpio口,一般用于(发送,接收,信号,使动)(TX1, MOSI, MISO,SCK,SS)
推挽输出:可以输出高电平和低电平,通过输出数据寄存器到输出控制电路,经过mos管才到gpio口
推挽复用输出:可以输出高电平和低电平,通过输出数据寄存器到输出控制电路,经过mos管才到gpio口 ,可以用于(iic的sda,scl)
4、最大速率设置
GPIO的输出速率:GPIO电平每秒切换的最大次数, 单纯GPIO意义不大,不过在通讯方面对于GPIO是有要求的。GPIO口的驱动电路响应速度,不是输出信号的速度。输出信号的速度与程序有关,通过选择速度来选择不同的驱动电路,降低功耗控制噪声。
这个输出速率主要体现I/O驱动电路的输出反应能力,通过选择不同的输出驱动速率,实现最佳的噪声与和功耗控制。不难理解,选择输出驱动速率越高,噪声也越大,相应的芯片功耗也会越大。所以对于这个输出频率的选择,不要太随意,合适就好。在满足应用的需求的前提下,就不要随意往高端速率选择。
当STM2的GPIO端口设置为输出形式时,有三种速度能够挑选:2MHz、10MHz和50MHz,这个速度是指I/O口驱动电路的速度,是用来挑选不同的输出驱动模块,到达最佳的噪声控制和降低功耗的意图。
六、假设你手中已有 STM2最小系统核心板(STM2F10C8T6)面板板只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。
1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;
首先需要知道的是,STM2中对于GIPO口的操作,无非就是操作下面的寄存器而已,所谓的标准库也好,HAL库也好,它们都只是对操作寄存器的过程进行了封装,目的是为了减轻编程时的工作负担:
两个2位的配置寄存器:GPIOx_CRL、GPIOx_CRH
两个2位数据寄存器:GPIOx_IDR、GPIOx_ODR
一个2位的置位/复位寄存器:GPIOx_BSRR
一个16位复位寄存器:GPIOx_BRR
一个2位锁定寄存器:GPIOx_LCKR
时钟地址:手册中可看到的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jud0MnQD-166851411810)(C:\Users\ASUS\Desktop\屏幕截图 2022-10-1 222947.png)]
GIPO地址:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kio4XI7I-166851411811)(C:\Users\ASUS\Desktop\屏幕截图 2022-10-1 22146.png)]
GPIO的配置寄存器CRL和CRH:
每个 GPI/O 端口有两个 2 位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个 2
位数据寄存器(GPIOx_IDR,GPIOx_ODR),一个 2 位置位/复位寄存器
(GPIOx_BSRR),一个 16 位复位寄存器(GPIOx_BRR)和一个 2 位锁定寄存器
(GPIOx_LCKR)。
这里我们用的就是CRL和CRH,这两个寄存器的全称是:端口配置低寄存器(GPIOx_CRL) (x=A…E) 和 端口配置高寄存器(GPIOx_CRH) (x=A…E)。
根据数据手册中列出的每个 I/O 端口的特定硬件特征, GPIO 端口的每个位可以
由软件分别配置成多种模式。
− 输入浮空
− 输入上拉
− 输入下拉
− 模拟输入
− 开漏输出
− 推挽式输出
− 推挽式复用功能
− 开漏复用功能
每个 I/O 端口位可以自由编程,然而 I/0 端口寄存器必须按 2 位字被访问(不允许
半字或字节访问)。GPIOx_BSRR 和 GPIOx_BRR 寄存器允许对任何 GPIO 寄存
器的读/更改的独立访问;这样,在读和更改访问之间产生 IRQ 时不会发生危险。
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
CRL
CRH
配置对应引脚寄存器,基地址偏移量
设置推挽输出并设置最大速度为2Mhz
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)GPIOA_CRL&=0xFFF0FFFF; //设置位 清零 GPIOA_CRL|=0x00020000; //PA4推挽输出,把第19、18、17、16位变为0010GPIOB_CRL&=0xFF0FFFFF; //设置位 清零 GPIOB_CRL|=0x00200000; //PB5推挽输出,把第2、22、21、20变为0010GPIOC_CRH&=0xFF0FFFFF; //设置位 清零 GPIOC_CRH|=0x00200000; //PC14推挽输出,把第2、22、21、20变为0010
2)用C语言 寄存器方式编程实现
#include stm2f10x.h
//----------------APB2使能时钟寄存器 ---------------------
#define RCC_APB2ER *((unsigned volatile int*)0x40021018)
//----------------GPIOA配置寄存器 -----------------------
#define GPIOA_CRL *((unsigned volatile int*)0x40010800)
#define GPIOA_ODR *((unsigned volatile int*)0x4001080C)
//----------------GPIOB配置寄存器 -----------------------
#define GPIOB_CRL *((unsigned volatile int*)0x40010C00)
#define GPIOB_ODR *((unsigned volatile int*)0x40010C0C)
//----------------GPIOC配置寄存器 -----------------------
#define GPIOC_CRH *((unsigned volatile int*)0x40011004)
#define GPIOC_ODR *((unsigned volatile int*)0x4001100C)//延时函数void Delay(){u2 i=0;for(;i<5000000;i);}int main(void){ RCC_APB2ER|=1<<2|1<<|1<<4; //APB2-GPIOA、GPIOB、GPIOC外设时钟使能 GPIOA_CRL&=0xFFF0FFFF; //设置位 清零 GPIOA_CRL|=0x00020000; //PB5推挽输出GPIOA_ODR&=~(1<<4); //设置初始灯为灭GPIOB_CRL&=0xFF0FFFFF; //设置位 清零 GPIOB_CRL|=0x00200000; //PB5推挽输出GPIOB_ODR&=~(1<<5); //设置初始灯为灭GPIOC_CRH&=0xF0FFFFFF; //设置位 清零 GPIOC_CRH|=0x02000000; //PB5推挽输出GPIOC_ODR&=~(1<<14); //设置初始灯为灭 while(1){//A灯GPIOA_ODR|=1<<4; //PB5高电平Delay();GPIOA_ODR&=~(1<<4); //PB5低电平,因为是置0,所以用按位与//B灯GPIOB_ODR|=1<<5; //PB5高电平Delay();GPIOB_ODR&=~(1<<5); //PB5低电平,因为是置0,所以用按位与//C灯GPIOC_ODR|=1<<14; //PB5高电平Delay();GPIOC_ODR&=~(1<<14); //PB5低电平,因为是置0,所以用按位与}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4jO5BjF4-16685141181)(D:\qq\MobileFile\Screenshot_2022_101_22945.gif)]
)安装 stm2CubeMX,用cubemx完成初始化过程,采用HAL库编程实现。
1、用到的工具
STM2CubeMX
KEIL5
mcuisp
STM2F10C8T6的最小核心板
2.安装stm2CubeMX
.安装HAL库
1)打开安装好的stm2CubeMX
2)点击HELP->Manage embedded software packages
)会跳出来一个选择型号界面,勾选上你要安装的HAL库, 点击“Install ow” 直到安装成功
4.新建项目
1)回到STMCubeMX的主界面,创建新项目
2)在part name里选择自己的芯片,点击信息栏中的具体芯片信息选中,点击start project
)点击system core,进入SYS,在debug下选择serial wire
(4)配置时钟,进入上面的rcc,有两个时钟,一个是hse和lse,我们要用是GPIO接口,而这些接口都在APB2里
接下来观察时钟架构,APB2总线的时钟由hse控制,同时在这个界面得把PLLCLK右边选上
5)将hse那里设为Crystal/Ceramic Resonator
6)接下来就是点击相应的引脚设置输出寄存器了,就是output那一项,一共选了三个,是PA4,PB9,PC15
7)点击project manager,配置好自己的路径和项目名,然后IDE那项改为MDK-ARM
5.keil仿真调试
打开.uvprojx文件
打开文件,滑倒主函数那一部分
代码
SystemClock_Config();//系统时钟初始化MX_GPIO_Init();//gpio初始化while (1){ HAL_GPIO_WritePin(GPIOA,GPIO_PI_4,GPIO_PI_RESET);//PA4亮灯HAL_GPIO_WritePin(GPIOB,GPIO_PI_9,GPIO_PI_SET);//PB9熄灯HAL_GPIO_WritePin(GPIOC,GPIO_PI_15,GPIO_PI_SET);//PC15熄灯HAL_Delay(1000);//延时1sHAL_GPIO_WritePin(GPIOA,GPIO_PI_4,GPIO_PI_SET);//PA4熄灯HAL_GPIO_WritePin(GPIOB,GPIO_PI_9,GPIO_PI_RESET);//PB9亮灯HAL_GPIO_WritePin(GPIOC,GPIO_PI_15,GPIO_PI_SET);//PC15熄灯HAL_Delay(1000);//延时1s HAL_GPIO_WritePin(GPIOA,GPIO_PI_4,GPIO_PI_SET);//PA4熄灯HAL_GPIO_WritePin(GPIOB,GPIO_PI_9,GPIO_PI_SET);//PB9熄灯HAL_GPIO_WritePin(GPIOC,GPIO_PI_15,GPIO_PI_RESET);//PC15亮灯HAL_Delay(1000);//延时1s}
电路连接
根据设计的程序连接电路:
对于USB转TTL模块和stm2f10c8t6连接:
GD — GD
v — v
TXD — A10
RXD — A9
总电路:
红——B9
绿——C15
黄——A4
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dZLraGDZ-166851456860)(D:\qq\MobileFile\Screenshot_2022_101_22945.gif)]
4)在Keil下用软件仿真运行上面代码,并用虚拟逻辑观察 对应管脚上的输出波形(高低电平转换),看是否是1秒的周期。
总结
让我理解STM2F10系列芯片的地址映射和寄存器映射原理,了解了GPIO端口的初始化设置三步骤
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 16 条评论) |
本站网友 字符转换器 | 22分钟前 发表 |
不难理解,选择输出驱动速率越高,噪声也越大,相应的芯片功耗也会越大 | |
本站网友 北京申奥失败 | 12分钟前 发表 |
GPIOB-9 | |
本站网友 97yes | 5分钟前 发表 |
2. 程序及报告文档要求:具有较好的可读性,如叙述准确 | |
本站网友 车险第二年优惠 | 11分钟前 发表 |
移位寄存器中的数据可以在移位脉冲作用下依次逐位右移或左移,数据既可以并行输入 | |
本站网友 乐乐棋牌 | 27分钟前 发表 |
我们可以到每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射 | |
本站网友 悭吝 | 2分钟前 发表 |
寄存器可能存放的是指令 | |
本站网友 金水湾大酒店 | 29分钟前 发表 |
GPIO_PI_RESET);//PC15亮灯HAL_Delay(1000);//延时1s} 电路连接 根据设计的程序连接电路: 对于USB转TTL模块和stm2f10c8t6连接: GD — GD v — v TXD — A10 RXD — A9 总电路: 红——B9 绿——C15 黄——A4 [外链图片转存失败 | |
本站网友 叫卖录音 | 23分钟前 发表 |
本站网友 羊胎素的功效 | 25分钟前 发表 |
实验要求 1. 分组要求:每个学生独立完成,即1人1组 | |
本站网友 开颅手术 | 3分钟前 发表 |
假设你手中已有 STM2最小系统核心板(STM2F10C8T6)面板板只红绿蓝LED,并搭建了电路,分别GPIOA-5 | |
本站网友 泉水二手房 | 17分钟前 发表 |
)安装 stm2CubeMX,用cubemx完成初始化过程,采用HAL库编程实现 | |
本站网友 源码天下 | 29分钟前 发表 |
chip select等 | |
本站网友 上海万科城花新园 | 26分钟前 发表 |
地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令 | |
本站网友 小韩村dj | 18分钟前 发表 |
串行输出,还可以并行输入 | |
本站网友 ibm中国 | 19分钟前 发表 |
学习和理解STM2F10系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置 |