STM32学习笔记1Word文件下载.docx

上传人:b****3 文档编号:16557053 上传时间:2022-11-24 格式:DOCX 页数:74 大小:98.60KB
下载 相关 举报
STM32学习笔记1Word文件下载.docx_第1页
第1页 / 共74页
STM32学习笔记1Word文件下载.docx_第2页
第2页 / 共74页
STM32学习笔记1Word文件下载.docx_第3页
第3页 / 共74页
STM32学习笔记1Word文件下载.docx_第4页
第4页 / 共74页
STM32学习笔记1Word文件下载.docx_第5页
第5页 / 共74页
点击查看更多>>
下载资源
资源描述

STM32学习笔记1Word文件下载.docx

《STM32学习笔记1Word文件下载.docx》由会员分享,可在线阅读,更多相关《STM32学习笔记1Word文件下载.docx(74页珍藏版)》请在冰豆网上搜索。

STM32学习笔记1Word文件下载.docx

然后在弹出的“SelectDeviceforTarget1”对话框中选择合适的芯片。

由于我采用的是STM32F103VET6,所以选择ST–STM32F103VE。

选择好芯片之后,会弹出一个消息框,“CopySTM32StartupCodetoProjectFolderandAddFiletoProject?

”问你是否需要加载启动代码。

选择“是”后进入工程。

所谓启动代码,就是处理器在启动的时候执行的一段代码,主要任务是初始化处理器模式,设置堆栈,初始化变量等等。

由于以上的操作均与处理器体系结构和系统配置密切相关,所以一般由汇编来编写。

而对于初学者而言,自己设计启动代码有一定的难度,MDK开发平台内置了一些常用芯片的启动代码,因此在新建工程的时候,最好是采用默认的启动代码。

当然,芯片制造厂商也会自己编写一些启动代码,放在官网上供开发者下载。

进入工程之后,我们就可以开始写代码了。

首先得新建一个文件,然后将其保存成为*.c的格式,这样开发环境就可以识别出编写的代码里面一些常用的关键字和其他信息了。

我就直接保存成为main.c。

然后在屏幕左边的ProjectWorkspace中的SourceGroup1单击右键,选择AddFilestoGroup“SourceGroup1”,将我们刚刚保存起来的main.c添加到SourceGroup1中,或者直接双击SourceGroup1,也可以添加文件。

接下来就可以开始写代码了,对于初学者而言,最基础的操作应该是对芯片IO口的操作了。

因此我在学习ARM的时候,第一个工程就选择了让开发板上的3个LED灯顺序点亮。

STM32F103VET6中一共有A-G共7组通用输入输出接口(General-PurposeInputs/Outputs),每个GPIO引脚都可以由软件配置成输出(推挽或开漏)、输入(带或不带上拉或下拉)或复用的外设功能端口。

多数GPIO引脚都与数字或模拟的复用外设共用。

具体的细节请参考Datasheet。

在《基于MDK的STM32处理器开发应用》一书中,“7.1通用IO端口”详细描述了各个端口的功能、寄存器格式以及其他相关信息,因此就不在这里赘述了。

回到MDK开发平台,现在要在main.c中加入相关代码了。

代码清单如下:

#include"

stm32f10x_lib.h"

intmain()

{

inti;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOB,ENABLE);

//开启外设时钟

GPIOD->

CRL=0x33333333;

//设置端口配置寄存器

GPIOB->

while

(1)

{

ODR=0xffffffbf;

//设置端口输出寄存器

for(i=0;

i<

1000000;

i++);

//延时

ODR=0xffffffff7;

ODR=0x00000000;

ODR=0xffffffff;

}

}

上述代码中,#include"

包含了开发stm32f10x系列芯片所需的基本头文件,在进行程序编写的时候,务必要包含此头文件。

RCC_APB2PeriphClockCmd()函数是设置外设时钟。

ARM与C51单片机不同的是,不用外设的时候,如IO口、ADC、定时器等等,都是禁止时钟的,以达到节能的目的,只有要用到的外设,才开启它的时钟。

因此在需要用到GPIOB和GPIOD的时候,我们需要先开启它的时钟,具体用到的是函数库里面的函数:

voidRCC_APB2PeriphClockCmd(uint32_tRCC_APB2Periph,FunctionalStateNewState)

其中,第一个参数需要指示要开启什么端口的时钟,RCC_APB2Periph_GPIOx就是开启GPIOx的时钟,第二个参数需要指示是开启还是关闭,ENABLE/DISABLE。

开启外设时钟之后,然后就开始对GPIO的配置寄存器进行设置了,具体设置方式参考《基于MDK的STM32处理器开发应用》一书中,“7.1通用IO端口”。

While循环里面就是给GPIO的端口输出寄存器赋值,由于我手上这款奋斗开发板的三个LED灯分别接的是D3、D6和B5,所以只要将D端口和B端口相应的位上置1就可以了。

编译之后我们发现编译器报错,UndefinedsymbolRCC_APB2PeriphClockCmd,是因为我们使用了的RCC_APB2PeriphClockCmd()函数在头文件中声明了,却没有在C文件中定义,这个函数在..Keil\ARM\RV31\LIB\ST\STM32F10x\stm32f10x_rcc.c中,将这个文件复制到工程的根目录下,然后在屏幕左边的Workspace中添加进来,就可以了。

至于如何下载到ARM开发板中,不同的开发板有不同的方法,而开发板生产厂商一般都会将有关的文档连同开发板一起附送,在此就不详细赘述了。

其实,在MDK的库中,还定义了很多宏,可以避免让我们自己去查找相关资料来设置寄存器的各个位。

比如,在本次实验中,对于LED等的亮灭也可以通过以下代码来实现。

GPIO_InitTypeDefGPIO_InitStructure;

//定义GPIO宏操作结构体

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOB,ENABLE);

//外设时钟配置,开启GPIOB和GPIOD的时钟

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

//将B5口配置为通用推挽输出

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

//口线翻转速度为50MHz

GPIO_Init(GPIOB,&

GPIO_InitStructure);

//配置GPIOB口

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_3;

//将D3和D6口配置为推挽输出

GPIO_Init(GPIOD,&

//配置GPIOD口

{

GPIO_SetBits(GPIOB,GPIO_Pin_5);

//B5口输出高电平

GPIO_ResetBits(GPIOD,GPIO_Pin_6);

//D6口输出低电平

GPIO_ResetBits(GPIOD,GPIO_Pin_3);

//D3口输出低电平

GPIO_ResetBits(GPIOB,GPIO_Pin_5);

GPIO_SetBits(GPIOD,GPIO_Pin_3);

GPIO_SetBits(GPIOD,GPIO_Pin_6);

由于我们使用了GPIO_InitTypeDef类型,所以我们需要找到它的定义,这个定义包含在“…\Keil\ARM\RV31\LIB\ST\STM32F10x\stm32f10x_gpio.c”中,将文件复制到工程根目录下,然后再添加进入工程中,编译才不会报错。

在绝大多数C编译器中,要求所有的变量声明都在执行语句块之前,也就是说如果需要定义的变量需要先在进入main函数一开始就全部定义好,如果执行了某一条语句之后再定义变量的话,就会报错

STM32学习笔记

(2):

外部中断的使用

2011年3月20日外部中断

中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。

今天就将来探讨一下关于STM32中的中断系统。

1基本概念

ARMCoetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。

STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。

STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。

68个通道的优先级控制字至少构成17个32位的优先级寄存器。

4bit的中断优先级可以分成2组,从高位看,前面定义的是抢占式优先级,后面是响应优先级。

按照这种分组,4bit一共可以分成5组

第0组:

所有4bit用于指定响应优先级;

第1组:

最高1位用于指定抢占式优先级,后面3位用于指定响应优先级;

第2组:

最高2位用于指定抢占式优先级,后面2位用于指定响应优先级;

第3组:

最高3位用于指定抢占式优先级,后面1位用于指定响应优先级;

第4组:

所有4位用于指定抢占式优先级。

所谓抢占式优先级和响应优先级,他们之间的关系是:

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。

如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;

如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

每一个中断源都必须定义2个优先级。

有几点需要注意的是:

1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;

2)抢占式优先级别相同的中断源之间没有嵌套关系;

3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。

2GPIO外部中断

STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。

比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能够再使用了,在此情况下,我们只能使用类似于PB1,PC2这种末端序号不同的外部中断源。

每一组使用一个中断标志EXTIx。

EXTI0–EXTI4这5个外部中断有着自己的单独的中断响应函数,

EXTI5-9共用一个中断响应函数,

EXTI10-15共用一个中断响应函数。

对于中断的控制,STM32有一个专用的管理机构:

NVIC。

对于NVIC的详细解释,可以参考《ARMCortex-M3权威指南》,JosephYiu著,宋岩译,北京航空航天大学出版社出版,第8章NVIC与中断控制。

中断的使能,挂起,优先级,活动等等部都是NVIC在管理的。

因为我学习STM32重点在于如何开发程序,所以内部的一些东西,在此我就不详细说明了,有感兴趣的可以参看上面提到的那本数。

3程序开发

其实上面那些基本概念和知识只是对STM32的中断系统有一个大概的认识,用程序说话将会更能够加深如何使用中断。

使用外部中断的基本步骤如下:

1.设置好相应的时钟;

2.设置相应的中断;

3.IO口初始化;

4.把相应的IO口设置为中断线路(要在设置外部中断之前)并初始化;

5.在选择的中断通道的响应函数中中断函数。

由于我用的奋斗开发板没有引出相应的芯片引脚,所以只能用按键来触发相应的中断。

根据原理图,K1/K2/K3连接的是PC5/PC2/PC3,因此我将用EXTI5/EXTI2/EXTI3三个外部中断。

PB5/PD6/PD3分别连接了三个LED灯。

中断的效果是按下按键,相应的LED灯将会被点亮。

1.设置相应的时钟

首先需要打开GPIOB、GPIOC和GPIOE(因为按键另外一端连接的是PE口)。

然后由于是要用于触发中断,所以还需要打开GPIO复用的时钟。

相应的函数在GPIO的学习笔记中有了详细了解释。

详细代码如下:

voidRCC_cfg()

//打开PEPDPCPB端口时钟,并且打开复用时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);

设置相应的时钟所需要的RCC函数在stm32f10x_rcc.c中,所以要在工程中添加此文件。

2.设置好相应的中断

设置相应的中断实际上就是设置NVIC,在STM32的固件库中有一个结构体NVIC_InitTypeDef,里面有相应的标志位设置,然后再用NVIC_Init()函数进行初始化。

voidNVIC_cfg()

NVIC_InitTypeDefNVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//选择中断分组2

NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQChannel;

//选择中断通道2

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

//抢占式中断优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

//响应式中断优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

//使能中断

NVIC_Init(&

NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQChannel;

//选择中断通道3

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;

//抢占式中断优先级设置为1

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

//响应式中断优先级设置为1

NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQChannel;

//选择中断通道5

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;

//抢占式中断优先级设置为2

NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;

//响应式中断优先级设置为2

由于有3个中断,因此根据前文所述,需要有3个bit来指定抢占优先级,所以选择第2组。

又由于EXTI5-9共用一个中断响应函数,所以EXTI5选择的中断通道是EXTI9_5_IRQChannel,详细信息可以在头文件中查询得到。

用到的NVIC相关的库函数在stm32f10x_nivc.c中,需要将此文件复制并添加到工程中。

具体位置可以查看关于GPIO的笔记。

这段代码编译起来没有任何问题,但是在链接的时候就会报错,需要把STM32F10xR.LIB加入工程中,具体位置在…\Keil\ARM\RV31\LIB\ST\STM32F10xR.LIB。

3.IO口初始化

voidIO_cfg()

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;

//选择引脚2

//输出频率最大50MHz

//带上拉电阻输出

GPIO_Init(GPIOE,&

GPIO_ResetBits(GPIOE,GPIO_Pin_2);

//将PE.2引脚设置为低电平输出

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_5;

//选择引脚235

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

//选择输入模式为浮空输入

GPIO_Init(GPIOC,&

//设置PC.2/PC.3/PC.5

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_6;

//选择引脚36

GPIO_Init(GPIOD,&

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;

//选择引脚5

GPIO_Init(GPIOB,&

其中连接外部中断的引脚需要设置为输入状态,而连接LED的引脚需要设置为输出状态,初始化PE.2是为了使得按键的另外一端输出低电平。

GPIO中的函数在stm32f10x_gpio.c中。

4.把相应的IO口设置为中断线路

由于GPIO并不是专用的中断引脚,因此在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来,具体代码如下:

voidEXTI_cfg()

EXTI_InitTypeDefEXTI_InitStructure;

//清空中断标志

EXTI_ClearITPendingBit(EXTI_Line2);

EXTI_ClearITPendingBit(EXTI_Line3);

EXTI_ClearITPendingBit(EXTI_Line5);

//选择中断管脚PC.2PC.3PC.5

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource2);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource3);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

EXTI_InitStructure.EXTI_Line=EXTI_Line2|EXTI_Line3|EXTI_Line5;

//选择中断线路235

EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrup

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 其它考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1