
% V" n- f# j3 h/ R4 a 学习笔记 for STM32F103C8 redesigned by zhang bin 2012-10-30 versions:V-0.1 All Rights Reserved
main.c如下,注释的比较详细,把下面的例子即说明都看明白基本上就可以用了:
//抢占级别高的会打断其他中断优先执行,而响应级别高的会在其他中断执行完优先执行。 //EXTI:外部中断/事件控制器
//EXTI控制器可以产生高达19个软件事件/中断请求 //将19根线配置为中断源,将19根线配置为事件源,将19根线配置为软件中断/事件线,详见《STM32F103xxx使用手册》 //P135
//在这个文件中主要是进行各种初始化配置,包括GPIO配置、EXTI配置、系统时钟配置等 //中断服务程序则在stm32f10x_it.c文件中,该文件提供所有异常处理程序和外围中断服务程序的模板,详见该文件
#include "stm32f10x_lib.h"
EXTI_InitTypeDef EXTI_InitStructure; //定义外部中断初始化结构体变量 内部含有4个成员 详见EXTI_InitTypeDef的定义 ErrorStatus HSEStartUpStatus; //定义错误状态变量,是枚举类型
void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void);
int main(void) { #ifdef DEBUG debug(); #endif
RCC_Configuration(); //系统时钟配置
NVIC_Configuration(); //NVIC配置
GPIO_Configuration(); //配置GPIO
//STM32的外部中断不是固定的,是可以映射的。如EXTI6既可以映射到PB6也可以映射到PA6,详见外部中断/事件与GPIO的映射关系 //将IO端口注册至中断线(将IO口映射到中断线N) // GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6); //选择GPIO管脚用作外部中断线路 //第一个参数选择用作外部中断线源的GPIO端口 第二个参数是待设置的外部中断线路,可以是GPIO_PinSourcex(x可以0~15)
//配置按钮中断线触发方式 设置中断配置结构体成员 EXTI_InitStructure.EXTI_Line = EXTI_Line6; //选择外部中断线 EXTI_Line0~EXTI_Line18共19根线 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,可以为EXTI_Mode_Interrupt中断请求或者 //EXTI_Mode_Event事件请求 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //触发方式下降沿触发 还可以为EXTI_Trigger_Rising上升沿触发或者 //EXTI_Trigger_Rising_Falling上升沿下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能 ENABLE使能,DISABLE失能 EXTI_Init(&EXTI_InitStructure); //根据参数结构体初始化EXTI中断
EXTI_GenerateSWInterrupt(EXTI_Line6); //产生一个软件中断 EXTI_Line6中断允许 //到此中断配置完成,可以写中断处理函数。
while (1) { } }
void RCC_Configuration(void) { //复位RCC外部设备寄存器到默认值 RCC_DeInit();
//打开外部高速晶振 RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟准备好 HSEStartUpStatus = RCC_WaitForHSEStartUp();
//外部高速时钟已经准别好 if(HSEStartUpStatus == SUCCESS) {
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
//配置AHB(HCLK)时钟=SYSCLK RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置APB2(PCLK2)钟=AHB时钟 RCC_PCLK2Config(RCC_HCLK_Div1);
//配置APB1(PCLK1)钟=AHB 1/2时钟 RCC_PCLK1Config(RCC_HCLK_Div2);
//配置ADC时钟=PCLK2 1/4 RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//配置PLL时钟 == 外部高速晶体时钟*9 8MHz*9MHz=72MHz RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//配置ADC时钟= PCLK2/4 RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//使能PLL时钟 RCC_PLLCmd(ENABLE);
//等待PLL时钟就绪 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { }
//配置系统时钟 = PLL时钟 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//检查PLL时钟是否作为系统时钟 while(RCC_GetSYSCLKSource() != 0x08) { } }
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOA,GPIOB和AFIO的APB2 }
void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; //定义配置GPIO的结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选中第8个脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure); //用配置好的结构体初始化GPIOB PB8用于驱动led
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //选中6脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB PB6脚连接外部中断线6的中断源 //所有的端口都有外部中断的能力,为了使用外部中断线,端口必须配置为输入模式
}
void NVIC_Configuration(void) //配置嵌套向量中断控制器 { NVIC_InitTypeDef NVIC_InitStructure;//定义初始化NVIC的结构体变量
#ifdef VECT_TAB_RAM //配置向量表基址 NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //分配中断向量表 #else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置中断优先级 //设置优先级分组:先占优先级和从优先级 输入参数设定优先级分组位长度 本例中NVIC_PriorityGroup_1:先占优先级1为,从优先级3位 //详见《STM32函数说明》P165 //优先级分组只能设定一次
//EXTI5-9共用一个中断源,EXTI10-15共用一个中断源 //详见详见《STM32函数说明》P166 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //中断通道 指定IRQ通道 这里指定外部中断线9-5中断 因为使用的是EXTI6 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设定指定IRQ通道的先占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设定指定IRQ通道的从优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //设定指定IRQ通道中断使能 DISABLE失能 NVIC_Init(&NVIC_InitStructure);//根据结构体中指定的参数初始化NVIC中断 }
#ifdef DEBUG
void assert_failed(u8* file, u32 line) {
while (1) { } } #endif
stm32f10x_it.c文件中的中断服务函数如下:
void EXTI9_5_IRQHandler(void) //外线路5-9的中断处理程序 { if(EXTI_GetITStatus(EXTI_Line6) != RESET) //检测制定的EXTI6线路触发请求是否发生。 //该函数检查指定的EXTI线路出发请求是否发生 { //其实就是对PB8取反 GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)((1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_8)))); //该函数可以对指定的端口位进行操作 指定端口和位,然后指定操作。第三个参数指定待写入的值 //该参数必须取枚举类型BitAction的其中一个值,可以是Bit_RESET:清除数据端口位和Bit_SET:设置数据端口位 //GPIO_ReadOutputDataBit()函数读取指定的IO端口管脚的输出,参数指定端口和位
//EXTI_ClearFlag(EXTI_Line6); //清除中断标志位(必须) 我在网上看到要求必须,但是在本例中并没有这句
EXTI_ClearITPendingBit(EXTI_Line6); //清除EXTI线路挂起位 } } |
很好的帖子 以后可以直接拿来用的 |