完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、STM32寄存器简介及GPIO端口的初始化设置三步骤
1、STM32寄存器简介及找寻寄存器地址 寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。 存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。 指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。 找寻寄存器地址需要查看数据手册,但是手册中没有直接给出所有的寄存器的地址,需要读者稍加计算。STM32给不同的寄存器分配了不同的地址,有点像划分了片区。在《STM32中文参考手册_V10》的第28页,有不同寄存器的地址范围。 例如,我们想要读取PB3引脚的电平,分为以下几步:
而这个寄存器的位数是32位(虽然高16位没有用到),这就是32位的单片机的意思。每个寄存器都占据4字节,32位。而CPU的总线一次可以操作32位,所以比8位单片机厉害一点。 经过这三步查找,我们可以做出以下结论: PB3的输入数据位于0x4001 0C08这个地址上,这个地址上存放数据的右起第4个位就是PB3引脚对应的高低电平。 2、GPIO端口初始化 GPIO端口的初始化设置可以大致分三步骤:时钟配置、输入输出模式设置、最大速率设置。本次实验中的STM32的点灯则需要通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,让其实现各种功能。 其过程可表示为:CPU给指令—>GPIO收到指令—>配置内部寄存器—>配置IO口模式—>控制LED亮灭。 二、用STM32F103点亮流水灯 1、工程模板的建立 工程模板的建立对我们编写程序来说非常重要,但是我们自己来建立可能对入门者比较困难。我们可以在网上选择现成的工程模板文件,这些程序都是编写组织好的,将不同的功能文件做了区分,放在了不同的文件夹中,逻辑非常清晰。这里整理了许多压缩包有不同的功能,在此次实验中我们只需要下载1-2-1-STM32F103这个压缩包就好了。 2、程序编写 2.1 分析工程模板内的函数 打开压缩包里的工程,我们可以看到有许多已经编写好的功能程序。我们以后都在这里调用我们要用的功能。 之后我们只需要编写相应的程序加入到对应功能的文件夹中就好了。打开文件夹前面的加号可以看到文件夹里面的文件。 可以观察到Startup文件夹中有启动文件,User文件夹里面有主函数,Basic文件夹里面有延时函数等功能函数。Hardware里面没有文件,我们需要编写我们需要的执行的程序加入里面。 2.2 程序的编写与添加 我们本次实验的目的是为了让三个LED灯间隔一秒钟一次亮起来,我们的思路是将灯一端全部接地,再在另外一端依次给入高电平,小灯就可以依次亮起来了,主要电路图可以如下所示: 此处我们小灯另一端接入的管脚分别为PA.0,PB.0,PC.0,流水灯的制作可以理解为三个管脚来回输出高低电平。 因为STM32点灯需要端口初始化,所以我们首先应该要将管脚初始化成我们所需要的样子。创建一个led.c文件来存放我们的初始化代码。 led.c: #include "led.h" void LED_Init(void){ //LED灯的接口初始化 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //初始化管脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置输出模式,推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速率 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_0); //将该管脚初始值定义为低电平 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_0); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC,GPIO_Pin_15); } 这里的设置输出模式为推挽输出模式,其实还有几种其他的输出方式,但是我们流水灯用到的大电流输出需要用到的就是推挽输出,另外的输出如下: GPIO_Mode_AIN:模拟输入模式至于为什么一定要将管脚初始值设置为低电平,可以将管脚输出想象成一个变量,如果没有一个定值的话,它的输出我们是不知道的,所以我们必须将它设置为一个我们知道的定值。(如果电路示意图跟我上面接法正好相反的话,就需要把初始值设置为高电平。 上面我们编写好了led.c文件,并在其中创建了一个LED_Init(void)初始化函数,我们在main文件中需要调用这个函数的时候就需要事先声明,所以我们创建一个头文件led.h用于声明我们这个函数名,再在main文件的头文件上加上#include "led.h"用于调用该头文件下的函数。 led.h: #include "stm32f10x.h" void LED_Init(void);//初始化 接下来我们需要将led.c和led.h文件导入到我们的工程中。 双击左边工程栏里的Hardware文件夹,然后找到我们刚保存的led.c文件的路径,再点击add即可。 然后我们需要在工程里的main.c函数下面和led.c函数导入led.h头文件对所需要的函数进行初始化。 首先打开User底下的main.c函数,右击选择魔法棒。 进入后先点击C/C++,然后点击Include Paths后面的三个小点: 接着在弹出来的窗口里面选择添加,然后再选择led.h函数保存的文件夹路径就ok了。 到此,我们的硬件(LED)算是编写完成,但是我们的main函数还是空空如也。所以接下来我们就要对我们的main函数进行编写了。要实现流水灯,我们就要让我们定义的输出管脚的输出在高低电平之间反复横跳,所以我们要对其进行赋值,具体操作代码如下: #include "stm32f10x.h" #include "delay.h" #include "led.h" int main (void){//主程序 RCC_Configuration(); //时钟设置 LED_Init(); while(1){ GPIO_SetBits(GPIOA,GPIO_Pin_0); //这个就是将IO口设置为高电平就是3.3V delay_ms(500); GPIO_ResetBits(GPIOA,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V delay_ms(500); GPIO_SetBits(GPIOB,GPIO_Pin_0); //这个就是将IO口设置为高电平就是3.3V delay_ms(500); GPIO_ResetBits(GPIOB,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V delay_ms(500); GPIO_SetBits(GPIOC,GPIO_Pin_15); //这个就是将IO口设置为高电平就是3.3V delay_ms(500); GPIO_ResetBits(GPIOC,GPIO_Pin_15);//这个就是将IO口设置为低电平就是0V delay_ms(500); } } GPIO_SetBits(GPIOX,GPIO_Pin_x),这个函数的意思是将该管脚置为高电平,也就是我之前提到过的赋值为1,Reset则表示赋值为0。 在将程序烧录进板子之前,我们可以在keil上仿真看看波形,以便于我们及时纠错。 2.3 Keil仿真 在开始仿真之前我们需要对keil进行一系列的配置,点击“仙女棒”,然后在Debug选项中选择软件仿真(use simulator),并且将下面的设置改成你对应的芯片即可。 然后我们编译运行程序,并进入调试页面。在调试界面点击下图按钮选择逻辑分析仪。 然后点击setup,我们就可以设置我们想看的管脚号了。 点击运行仿真,然后就可以看到仿真波形了。 3、烧录程序 我们在keil中仿真好的程序最终要烧录到STM32F103C8T6(STM32最小系统核心板)中去执行,这时我们就需要用到专门的烧录硬件和软件了,硬件是USB转TTL,用于我们的PC和板子连接,软件是Fly MCU和CH340驱动直接在CSDN上搜索就可以下载到,安装好就可以了。 3.1 关于USB-TTL与板子之间的连线方法 现在我们仔细观察我们的USB-TTL和板子,可以看到我们USB-TTL身上有五个管脚,分别是5V电源管脚、3.3V电源管脚、TXD(数据传送)管脚、RXD(数据接收)管脚、GND管脚。我们要实现PC与板子相连接就要让对应管脚连接起来,即板子的TXD接USB-TTL的RX,RXD接TX。 总结来说: PA9---RXD GND---GND PA10---TXD 3V3---3V3 其次LED灯正极就如我们上面所说的连接A0、B0、C15管脚,负极共地,连接完后如下图所示: 3.2 开发板BOOT设置 我们此时注意到板子上有两个跳线帽,分别在BOOT0和BOOT1上,我们要烧录程序之前必须改变模式BOOT0和BOOT1模式为系统存储器模式。务必将boot0设为1,boot1设为0,利用跳线帽实现。 3.3 驱动及烧录程序 在安装好CH340驱动以后,我们可以在我们的设备管理器中找到对应连接的设备。 现在只需要我们打开FlyMCU进行一定的配置后,就可以进行烧录了。配置如下图: 点击开始编程进行烧录,烧录完成后提示命令执行完毕,一切正常。 |
|
|
|
只有小组成员才能发言,加入小组>>
3311 浏览 9 评论
2994 浏览 16 评论
3493 浏览 1 评论
9058 浏览 16 评论
4087 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 00:17 , Processed in 1.226919 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号