中断函数
void USART1_IRQHandler(void) { receive = (u8)USART_ReceiveData(USART1); USART_SendData(USART1,receive); USART_ClearFlag(USART1,USART_FLAG_RXNE); }
NVIC中断
NVIC在3.5的库中定义在misc文件中,打开中断的函数一般分散在相应的外设函数中。 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 0组的没有抢占只有执行优先级,4组只能抢占 typedef struct {
u8 NVIC_IRQChannel;
u8 NVIC_IRQChannelPreemptionPriority; u8 NVIC_IRQChannelSubPriority; FunctionalState NVIC_IRQChannelCmd; } NVIC_InitTypeDef;
USART1_IRQn定义在stm32f10x.h中
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5; NVIC_Init(&NVIC_InitStructure); 1.
中断函数文件stm23f10x_ti.c其实是个弱函数集,里面的中断函数可以写在任何文件里。因为中断函数名是在启动文件里定义的,函数名是不能变的(除非改启动文件*.s的汇编文件,不推荐)。Stm32f10x.h包含了config头文件,包含了启动文件,因此只要包含这个头文件,中断函数可以写在任何地方。 2.
新库是用USART1_IRQn代表中断通道,老库是USART1_IRQChannel。新库的USART1_IRQn定义在stm32f10x.h中
WWDG_IRQHandler PVD_IRQHandler TAMPER_IRQHandler RTC_IRQHandler FLASH_IRQHandler RCC_IRQHandler EXTI0_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler DMA1_Channel3_IRQHandler DMA1_Channel4_IRQHandler DMA1_Channel5_IRQHandler DMA1_Channel6_IRQHandler DMA1_Channel7_IRQHandler ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler USB_LP_CAN1_RX0_IRQHandler CAN1_RX1_IRQHandler CAN1_SCE_IRQHandler EXTI9_5_IRQHandler TIM1_BRK_IRQHandler TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler TIM1_CC_IRQHandler TIM2_IRQHandler TIM3_IRQHandler TIM4_IRQHandler I2C1_EV_IRQHandler I2C1_ER_IRQHandler I2C2_EV_IRQHandler I2C2_ER_IRQHandler SPI1_IRQHandler SPI2_IRQHandler USART1_IRQHandler USART2_IRQHandler USART3_IRQHandler EXTI15_10_IRQHandler RTCAlarm_IRQHandler USBWakeUp_IRQHandler TIM8_BRK_IRQHandler TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler TIM8_CC_IRQHandler ADC3_IRQHandler FSMC_IRQHandler SDIO_IRQHandler TIM5_IRQHandler SPI3_IRQHandler UART4_IRQHandler UART5_IRQHandler TIM6_IRQHandler TIM7_IRQHandler
DMA2_Channel1_IRQHandler DMA2_Channel2_IRQHandler DMA2_Channel3_IRQHandler DMA2_Channel4_5_IRQHandler
以上是部分中断函数名字,一些核内中断,像systick,都在启动文件里面
外部中断EXTI
第一步:打开GPIO时钟RCC,打开AFIO时钟RCC
注意:什么时候需要开启辅助IO时钟,使用了AFIO的事件控制寄存器、AFIO的重映射功能以及外部中断(EXTI)控制寄存器
第二步:GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
同一组中断使用一个就不能使用其他的了,这里使用了PB1,那么PA1、PC1~PG1都不能
连接上中断线路,AFIO_EXTICR 寄存器类似于多路单选开关
第三步:配置GPIO_InitTypeDef,需要用的GPIO,模式可以配置为浮空输入、上拉或者下拉,在有
外部上下拉的时候选择浮空输入
第四步:配置EXTI_InitTypeDef,即配置外部中断的触发模式等
第五步:配置NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);和NVIC_InitTypeDef。 第六步:编写中断函数 void EXTI1_IRQHandler(void) { }
把PB0配置为下降沿中断,该管脚外部有上拉电路。
GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //配置GPIO外部中断脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); //配置GPIO管脚模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//可以是浮空输入,带上拉或者带下拉,因为电路本身有上拉,所以浮空就好 GPIO_Init(GPIOB,&GPIO_InitStructure); //打开EXTI中断
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //最后编写中断函数 void EXTI1_IRQHandler(void) { }
if(EXTI_GetITStatus(EXTI_Line1) == SET) { }
printf(\EXTI_ClearITPendingBit(EXTI_Line1);
if(EXTI_GetITStatus(EXTI_Line1) == SET) //获取中断标志 { }
printf(\EXTI_ClearITPendingBit(EXTI_Line1);
//清除标注
SysTick
这个新库改的面目全非,函数不好找,但是简化了很多函数,最重要的一点是,SysTick相关函数写在内核中,所有同内核ARM芯片都一样的程序了,意义深远。基本上就应用两个函数就行。 ST官方库里面的example里原话:
/* Setup SysTick Timer for 1 msec interrupts. ------------------------------------------
1. The SysTick_Config() function is a CMSIS function which configure: - The SysTick Reload register with value passed as function parameter. - Configure the SysTick IRQ priority to the lowest value (0x0F). - Reset the SysTick Counter register.
- Configure the SysTick Counter clock source to be Core Clock Source (HCLK). - Enable the SysTick Interrupt. - Start the SysTick Counter.
2. You can change the SysTick Clock source to be HCLK_Div8 by calling the
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8) just after the SysTick_Config() function call. The SysTick_CLKSourceConfig() is defined inside the misc.c file.
3. You can change the SysTick IRQ priority by calling the
NVIC_SetPriority(SysTick_IRQn,...) just after the SysTick_Config() function call. The NVIC_SetPriority() is defined inside the core_cm3.h file.
4. To adjust the SysTick time base, use the following formula:
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
- Reload Value is the parameter to be passed for SysTick_Config() function - Reload Value should not exceed 0xFFFFFF */
说的很清楚,
1.设置初值的函数是SysTick_Config();这个函数在core_cm3.h里面,参数就是初值。例如:系统时钟是72Mhz 那么要产生1ms的时基,应该填入SysTick_Config(72 000 000/1000)看第四条,调整时基,初值计算方法是 value = 模块时钟(Hz) * 想设定的时间(s)时钟72 000 000 HZ* 0.001s就是72000000/1000
2.如果想调节模块时钟,就是8分频系统时钟,在上一个函数之后调用SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8) 这个函数在misc.c文件中。
3.可以改变SysTick IRQ的优先级,在1后面调用函数NVIC_SetPriority(SysTick_IRQn,...),函数定义在core_cm3.h中
代码实现定时函数delay Main.c
#include \#include %uint32_t TimingDelay;
void Delay(__IO uint32_t nTime); int main(void) {
mThransMessageInit(1); SysTick_Config(9000);
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); printf(\ while(1) { printf(\ Delay(1000); } }
void Delay(__IO uint32_t nTime) {
TimingDelay = nTime;
while(TimingDelay != 0); }
It.c
extern uint32_t TimingDelay;//声明外部变量
void SysTick_Handler(void) {
if(TimingDelay != 0) {TimingDelay--;} }
TIM定时器
定时器很复杂,库函数作用整理如下: TI1_Config到TI4_Config();
函数名字可以看出是配置TI1~TI4的,具体参数 TIMx,: 选择哪个定时器,多有都可以
TIM_ICPolarity : 捕获上升沿还是下降沿 TIM_ICPolarity_Rising TIM_ICPolarity_Falling
TIM_ICSelection,: timer’s input compare selection输入信号选择
TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. 见图
TIM_ICFilter,: 选择输入硬件滤波器 value between 0x00 and 0x0F.
TIM_ARRPreloadConfig ();
配置自动重装寄存器ARR,enable是立即写入影子寄存器,disable是在每次更新事件UEV信号是写