startup_stm32f10x_ld.s 对应小容量(little),startup_stm32f10x_h这个是st公司为其制作的评估板写的程序d.s对应中容量产品。
stm32启动文件详解_stm32f4启动文件区别
头文件中变量声明时不能对变量赋值,C文件没问题,我的就是这个原因,把头文件中的赋值去掉就可以了! IRQ是中断服务程序,不需要自己定义,我用的库是可以放在任意位置的,如果你要编辑中断服务程序,直接从启动文件中拷贝程序名,加入程序体就行了,注意2、在STM32的软件配置中这条语句的作用就是:开启对应中断线上的中断,启用外部中断0和1。这通常通过设置相应的中断使能位来完成。清标志位
如何打注:抢占优先级和响应优先级一样,其值越低则表示其优先级越高;开iar? 找安装目录下的common/bin下面的IarIdePm.exe;
__IO uint32_t SHCSR; /!< Offset: 0x024 (R/W) System Handler Control and State Register /所有中断响应函数在stm32f10x_it.c文件中,
如果你不用中断,把这个文件去掉是没事的
都包含这个文件,是RCC->AHB1ENR = 1<<5; //使能GPIO端口的F时钟为}[cpp] view plain copy了以后建工程方便,一般教程类的文件都包含这个
打开103的启动文件staruSTM32的使用原理:p_stm32f10x_md.s,
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler 代码启动段?找安装目录下搜索找到相应的cstartup.s,启动过程参考iar user guide 给出的下图。 ; TIM3
DCD TIM4_IRQHandler ; TIM4
这里面只有TIM1-TIM4的定时器中断,TIM6是没有中断响应这个功能的。
上面的 NVIC中断,要从starup_stm32f10x_md.s这里面找的,不能自己定义这上面没有的中断。
如果对你有帮助的话,给分吧。。。
Linux对于开发者来说真的是一个非常好的系统,为开发者来说在这里,我们知道:我们的EXTI3对应的中断的位置是9,所以我们只需设置ISER[0]的第9位即可;所以我们在这里就将这条应该不陌生,通常我们在Windows下开发stm32很方便,有非常多的工具,IDE等支持,同样是作系统,Linux开发STM32也一点不会。
//SCB和NVIC,可参考STM32F3与STM32F4系列Cortex M4内核编程手册.pdfstm32f10x_it.c
中断处理函数都放在这个文件里面。
main.c
这个不用解释了吧
stm32f10x.h
这个是头文件,它包含了stm32的一些常用宏,寄存器结构体的定义,高版本的库还放着中断/向量extern CO_Data表。
stm32f10x_rcc.c
这个文件里的固件函数包含了一些对复位、时钟的控制的函数
stm32f10x_gpio.c这个文件里的固件函数包含了对gpio的作函数
stm32_eval.c
_stm32f10x.c主要包含了对系统时钟设置,一般是对倍频时钟的设置
具体可以看一下文件内容啊,呵呵
那么当这个中断条件满足时,就会去中断函数里边执行其函数体;欢迎追问
具体情况具体对待,你可以看我下面的实验对号入座来分析你的问题:
在整ST的3.4.0固件库的时候,打开了它的工程模板,发现里面有多个启动文件:x0dx0ax0dx0a多个启动文件x0dx0a按说添加多个启动文件,编译会出错的。可是这个工程pass得非常好??keil是怎么识别到要编译startup_stm32f10x_hd.s的?寻觅了半天才注意到那些文件图标上的轻微别。x0dx0astartup_stm32f10x_hd.s这个文件上没有其他文件图标上的三个红点,表示它现在是包含在项目中的。查看它的配置属性:x0dx0ax0dx0a注意到了:Include in Target Build。x0dx0a也就是说在编译的时候编译这个文件。其他几个文件这个选项都是没有勾选的,也就是不编译。实验目的:
当按键按下时,让PF10引脚的LED灯亮,
无论按下与否,PF9引脚的LED灯循环闪烁;
实验程序:
[cpp] view plain copy
/led.c/
#include "stm32f4xx.h" //在SYSTEM目录下可以找到
#include "sys.h"
void LED_Init(void){
GPIO_Set(GPIOF,PIN9|PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_25M,GPIO_PUPD_PU);
PFout(9) = 1;
/led.h/
#ifndef _LED_H
#define _LED_H
void LED_Init(void);
#endif
[cpp] view plain copy
/key.c/
#include "sys.h"
void Key_Init(void){
RCC->AHB1ENR|=1<<4; //使能PORTE时钟
//void GPIO_Set(GPIO_TypeDef GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD);//GPIO设置函数
GPIO_Set(GPIOE,PIN3,GPIO_MODE_IN,0,0,GPIO_PUPD_PU); //PE3设置上拉输入,这样的话,
//当按键没有按下时,默认电平为高;
/key.h/
#ifndef _KEY_H
#define _KEY_H
void Key_Init(void);
#endif
[cpp] view plain copy
/exti.c/
#include "sys.h"
#include "delay.h"
#include "stm32f4xx.h"
/
本示例的作用就是,
当按键按下时,蜂鸣器发出声音,
当按键再次按下时,蜂鸣器静音;
/
中断初始化函数:
主要是关于寄存器的相关配置
void EXTI3_Init(void){
//方法一:
RCC->APB2ENR |= 1 << 14; //开启SYSCFG时钟
SYSCFG->EXTICR[0] |= 0x4 << 12;//设置IO口与中断线的映射关系;
EXTI->IMR |= 1 << 3; //开启对应中断线上的中断
EXTI->FTSR |= 1 << 3; //设置中断触发条件
SCB->AIRCR |= 0x5 << 8; //设置分组
NVIC->IP[9] |= 0; //设置优先级,具体可分析MY_NVIC_Init()函数;
NVIC->ISER[0] |= 1 << 9; //使能中断;
//方法二:
使用SYSTEM目录下提供的API来实现,
}void EXTI3_IRQHandler(void){
/
此按键,在按键按下时,处理不是很到位,
有待进一步改进,主要是在连按那一个环节。
delay_ms(20); //消抖
if(PEin(3) == 0){
PFout(10) = !PFout(10);
}/
在中断里边记得清中断:
EXTI->PR |= 1 << 3;
/exti.h/
#ifndef _EXTI_H
#define _EXTI_H
void EXTI3_Init(void);
#endif
[cpp] view plain copy
/test.c/
#include "sys.h"
#include "delay.h"
#include "key.h"
#include "beep.h"
#include "led.h"
//int i = 0;
int main(void){
Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
delay_init(168); //初始化延时函数
Beep_Init();
Key_Init();
EXTI3_Init();
PFout(9) = 0;
delay_ms(500);
PFout(9) = 1;
delay_ms(500);
}}
实验分析:
我们主要分析一下exti.c中的寄存器设置的这几个步骤:
1. RCC->APB2ENR |= 1 << 14;
这一步的作用就是使能SYSCFG时钟,
在使用外部中断的时候一定要先使能SYSCFG时钟;
2. SYSCFG->EXTICR[0] |= 0x4 << 12;
这一步的作用就是设置IO口与中断线的映射关系;
那么问题来了,我如何知道的我的IO口与哪根中断线是关联起来的呢?
而我们是通过KEY1按键,对应的IO口就是PE3,所以由上图的映射关系,我们知道,我们应该选择中断线3与之对应;
在提供的头文件stm32f4xx.h中,我们可以看到:
[cpp] view plain copy
{__IO uint32_t MEMRMP; /!< SYSCFemory remap register, Address offset: 0x00 /
__IO uint32_t PMC; /!< SYSCFG peripheral mode configuration register, Address offset: 0x04 /
uint32_t RESERVED[2]; /!< Reserved, 0x18-0x1C /
[cpp] view plain copy
__IO uint32_t CMPCR; /!< SYSCFG Compensation cell control register, Address offset: 0x20 /
SYSCFG_TypeDef;
由于PE3对应的中断线为EXTI3,所以,我们我们这里仅需配置EXTI3,而EXTI3是在SYSCFG_EXTICR1中的;
所以我们仅需配置SYSCFG_EXTICR1寄存器的12位-15位为0100,而SYSCFG_EXTICR1寄存器在配置文件中,
对应的是SYSCFG->EXTICR[0],所以我们就写成了SYSCFG->EXTICR[0] |= 0x4 << 12;
3. EXTI->IMR |= 1 << 3;
由于我们作的中断线是EXTI3,而IMR寄存器各位解释如下:
所以对应的,我们作EXTI_IMR寄存器的第3位MR3即可;
4. EXTI->FTSR |= 1 << 3;
这条语句的作用就是设置中断触发条件;
因为我们key.c中,将按键的引脚设置成了上拉;所以在这里,我得将其设置成下降沿触发;
又由于我们这条中断线是中断线3,所以这条语句就写成了:EXTI->FTSR |= 1 << 3
5. SCB->AIRCR |= 0x5 << 8;
这条语句的作用就是:设置分组;
所以,在这里我们只需设置SCB的AIRCR的 bit10-8即可;查看SCB的结构体,得知:
[cpp] view plain copy
{__I uint32_t CPUID; /!< Offset: 0x000 (R/ ) CPUID Base Register /
__IO uint32_t ICSR; /!< Offset: 0x004 (R/W) Interrupt Control and State Register /
__IO uint32_t VTOR; /!< Offset: 0x008 (R/W) Vector Table Offset Register /
__IO uint32_t AIRCR; /!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register /
__IO uint32_t SCR; /!< Offset: 0x010 (R/W) System Control Register /
__IO uint32_t CCR; /!< Offset: 0x014 (R/W) Configuration Control Register /
__IO uint8_t SHP[12]; /!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) /
__IO uint32_t HFSR; /!< Offset: 0x02C (R/W) HardFault Status Register /
__IO uint32_t DFSR; /!< Offset: 0x030 (R/W) Debug Fault Status Register /
__IO uint32_t MMFAR; /!< Offset: 0x034 (R/W) MemMa Fault Address Register /
__IO uint32_t BFAR; /!< Offset: 0x038 (R/W) BusFault Address Register /
__I uint32_t PFR[2]; /!< Offset: 0x040 (R/ ) Processor Feature Register /
__I uint32_t DFR; /!< Offset: 0x048 (R/ ) Debug Feature Register /
__I uint32_t ADR; /!< Offset: 0x04C (R/ ) Auxiliary Feature Register /
__I uint32_t MMFR[4]; /!< Offset: 0x050 (R/ ) Memory Model Feature Register /
__I uint32_t ISAR[5]; /!< Offset: 0x060 (R/ ) Instruction Set Attributes Register /
uint32_t RESERVED0[5];
__IO uint32_t CPACR; / /!< Offset: 0x088 (R/W) Coprocessor Access Control Register /
} SCB_Type;
所以,在这里,我们把这条语句写成了SCB->AIRCR |= 0x5 << 8;
亦即设置成了101,也就是抢占优先级占2位,响应优先级占2位;
上述说的子优先级也就是我们说的响应优先级;
6. NVIC->IP[9] |= 0;
有上条语句,我们可以得知:IP寄存器由240个8bit的寄存器组成,每个可屏蔽中断占用8bit,这样总共可以表示240个可屏蔽中断,
而STM32F4只用到了其中的82个。IP[81]~IP[0]分别对应中断81~0.而每个可屏蔽中断占用的8bit并没有全部使用,而是只用了高4位;
这4位,又分为抢占优先级和响应优先级;抢占优先级在前,响应优先级在后;也就是说,抢占优先级在高位,响应优先级在低位;
而我们又知道:我们这个中断是外部中断3,所以查看中断向量表可知:
在这里我们把NVIC->IP[9] |= 0;则表示,我们设置外部中断3的抢占优先级为0,响应优先级也为0,其各占2位;
7. NVIC->ISER[0] |= 1 << 9;
这一步的作用就是使能中断;
ISER是一个中断使能寄存器组;这里用8个32位寄存器来控制,每个位控制一个中断;但是STM32F4的可屏蔽中断
最多只有82个,所以对我们来说,有用的就是三个(ISER[0~2]),总共可以表示96个中断;而STM32F4只用了其中的
前82个中断,ISER[0]的0bit~31分别对应中断0~31;ISER[1]的bit0~32对应中断32~63;ISER[2]的bit0~32对应中断64~81;
语句写成了:NVIC->ISER[0] |= 1 << 9;
8.至于外部中断函数的名称如何编写,我们可以从启动文件中去找到;
当我们设置的外部中断函数与启动文件中定义的名称一致时,
我们只需要在中断发生后,记得清中断,防止中断重复发生;
注意事项:
在本实验中,关于按键处理那一块,处理不是很到位,
主要应该是处在连按这一块,暂时没去整它,待我需要时,再去整整。
转载于
STM32 中断初识
前段时间经常用stm32f4 discovery,但是因为对NVIC , EXTI不是很了解,所以使用的过程中一直都在避免使用中断,这两天没什么事决定来学习一下stm32 的中断,写一下自己的心得,如有谬误之处,欢迎指正。
密码:4g
您好,
/步骤一:在新建好的工程目录下新建文件夹CanFestival,再在CanFestival下新建文件夹driver、inc和src,再在inc文件夹下面新建stm32文件夹(我这里主要以移植到stm32为例说明,如果是移植到VC或其他下,这里也可以命名为其他名字,如vc)。
步骤二:将CanFestival-3-10src目录下的dcf.c、emcy.c、lifegrd.c、lss.c、nmtMaster.c、nmtSle.c、objacces.c、pdo.c、sdo.c、states.c、sync.c、timer.c共12个文件拷贝到CanFestivalsrc目录下;将CanFestival-3-10include目录下的所有.h文件共19个文件全部拷贝到CanFestivalinc目录下,再把CanFestival-3-10examplesAVRSle目录下的ObjDict.h文件拷贝过来,一共20个;将CanFestival-3-10includeAVR目录下的applicfg.h、canfestival.h、config.h、timerscfg.h共4个头文件拷贝到canfestivalincstm32目录下;将CanFestival-3-10examplesTestMasterSle目录下的TestSle.c、TestSle.h、TestMaster.h、TestMaster.c拷贝到canfestivaldriver目录下,并在该目录下新建stm32_canfestival.c文件。
步骤四:将文件目录canfestivalinc、canfestivalincstm32、canfestivaldriver等路径添加到工程包含路径。
步骤五:在stm32_canfestival.c中包含头文件#include
"canfestival.h",并定义如下函数:
void setTimer(TIMEVAL
value)
{}
{return 1;
}unsigned char canSend(CAN_PORT
notused, Message m)
{return 1;
}可以先定义一个空函数,等到编译都通过了之后,再往里面添加内容,这几个函数都是定义来供canfestival源码调用的,如果找不到这几个函数编译就会报错。
步骤六:通过以上几步,所有的文件都弄齐了,但是编译一定会出现报错,注释或删除掉config.h文件中的如下几行就能编译通过:
如果还有其他报错,那有可能是因为不同源码版本、不同、不同人遇到的错误也会不相同,这里的过程只能做一定的参考,不一定完全相同,解决这些错误需要有一定的调试功底,需要根据编译出错提示来进行修改对应地方,一般都是有些函数没声明或者某个头文件没有包含或者包含了一些不必要的头文件而该文件不存在或者是一些变量类型不符合需定义之类的,如果能够摆平所有的编译出错,那么移植就算成功了,如果你被编译出错摆平了,那么游戏就结束,没得玩了。
步骤七:解决了所有的编译错误后,接下来实现刚才定义的3个空函数,函数void setTimer(TIMEVAL
value)主要被源码用来定时的,时间到了就需要调用一下函数TimeDispatch(),函数TIMEVAL
getElapsedTime(void)主要被源码用来查询距离下一个定时触发还有多少时间,unsigned char canSend(CAN_PORT
notused, Message m)函数主要被源码用来发一个CAN包的,需要调用驱动来将一个CAN包发出去。
我们在stm32_canfestival.c文件里定义几个变量如下:
unsigned int NextTime=0;//下一次触发时间计数
unsigned int
TIMER_MAX_COUNT=70000;//时间计数
static TIMEVAL last_time_set =
TIMEVAL_MAX;//上一次的时间计数
setTimer和getElapsedTime函数实现如下:
//Set the next alarm
//
void setTimer(TIMEVAL
value)
{NextTime=(TimeCNT+value)%TIMER_MAX_COUNT;
}// Get the elapsed time since the
last occured alarm //
{int ret=0;
ret = TimeCNT>
last_time_set ? TimeCNT - last_time_set : TimeCNT + TIMER_MAX_COUNT -
last_time_set;
last_time_set =
TimeCNT;
return ret;
}另外还要开一个1毫秒的定时器,每1毫秒调用一下下面这个函数。
void
timerForCan(void)
{TimeCNT++;
if
(TimeCNT>=TIMER_MAX_COUNT)
{TimeCNT=0;
}if
(TimeCNT==NextTime)
}与此同时,查看EXTI_FTSR寄存器,可以看到:}
can发包函数canSend跟CAN驱动有关,CAN通道可以使用真实的CAN总线,也可以使用虚拟的CAN通道(如文件接口、网络通道等等)。
启动时初始化:
在初始化的文件里(比如main.c)添加以下几行代码
"TestSle.h"
unsigned char
nodeID=0x21;
TestSle_Data;
在调用函数(比如main函数)里调用以下代码初始化
setNodeId(TestSle_Data,
setState(TestSle_Data,
Initialisation); // Init the state
其中T estSle_Data在TestSle.c中定义
然后开启调用TimerForCan()的1毫秒定时器,在接收CAN数据那里调用一下源码函数canDispatch(TestSle_Data,
m);
canfestival源码就可以跑了,如果需要跟主设备联调,还要实现canSend函数,这个与的Can驱动相关。
void RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
都是.c文件,不是头文__IO uint32_t AFSR; /!< Offset: 0x03C (R/W) Auxiliary Fault Status Register /件啊。1、个参数选外设端口。
2、第二个选enable or disable。
3、直接看库源文件STM32F10x_StdPeriph_Driversrcstm32f10x_rcc.c,1090行,已经写明了可用的参数。
扩展资料:
除新增的功能强化型外设接口外,STM32互连系列还提供与其它STM32微相同的标准接口,这种外设共用性提升了整个产品家族的应用灵活性,使开发人员可以在多个设计中重复使用同一个软件。新ST的M32的标准外设包括10个定时器、两个12位1-Msample/s 模数转换器 (交错模式下2-Msample/s)、两个12位数模转换器、两个I2C接口、五个USART接口和三个SPI端口。
新产品外设共有12条DMA通道,还有一个CRC计算单元,像其它STM32微一样,支持96位标识码。低功耗模式共有四种,可将电流消耗降至两微安。从低功耗模式快速启动也同样节省电能;启动电路使用STM32内部生成的8MHz信号,将微从停止模式唤醒用时小于6微秒。
参考资料来源:
版权声明:本文内容由互联。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发 836084111@qq.com 邮箱删除。