MM32F003L手册
由上图可知需要关闭内部高速时钟
但是MM32一般默认使用的都是内部高速时钟HSI,如果把内部高速时钟关闭的情况下使用外部高速时钟(HSE)PD0与PD1不能当作GPIO来使用只能作为时钟引脚来使用,因此手册上的后半句话(关闭内部高速时钟)是错误的(亲自找官方确认过了),但是AFR寄存器还是一定要配置的。
这是PD0与PD1的引脚在不同的配置之下的复用个功能,我使用的AF5,对于上面我的理解是这两个管脚对应的复用功能只有IIC1的两个管脚,其配置为AF1,如果配置为AF0或者AF2或者AF3,AF4,AF5,AF6,AF7,都等于把他配置成为GPIO,我是这样配置的,代码没出现什么问题(以上为个人理解,如有不对请告知,我会立即做出更改)。
废话不多说了,一下是代码的截图:
void KEY2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Clock_Set(KEY2_Port, ENABLE); //开启KEY1 GPIO Port 时钟
GPIO_InitStructure.GPIO_Pin = KEY3_Pin|KEY2_Pin; // K1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING; //设置成上拉输入
GPIO_Init(KEY2_Port, &GPIO_InitStructure); //初始化GPIOA5
GPIO_PinAFConfig(KEY2_Port,KEY3_Pin|KEY2_Pin,GPIO_AF_5);//开启复用功能
GPIO_SetBits(KEY2_Port, KEY2_Pin|KEY3_Pin);//默认为高点平
}
此出为按键的初始化配置
在此给大家讲解一下开启复用功能函数
GPIO_PinAFConfig(KEY2_Port,KEY3_Pin|KEY2_Pin,GPIO_AF_5);
GPIO_Pin_n可以理解为某端口脚在整个端口的位置。比方某GPIO口的第6管脚位置编码GPIO_Pin_6 被定义为 ((uint16_t)0x0040) ,在对相应GPIO管脚做基本属性配置时会用到,如配置输入输出模式、模拟输入模式的选择等。有兴趣的话,可以点击GPIO_Init( )进去看看。
而GPIO_PinSourceN一般是在对某GPIO口相应pin脚的复用功能进行选择配置才会用到。它是根据端口各脚位的位置按顺序从0开始依次递增编号,可以理解为该管脚在该端口的序号。比方某GPIO口的第6号复用功能脚的序号GPIO_PinSource6 被定义为 ((uint8_t)0x06) 。有兴趣的话,也可以打开GPIO_PinAFConfig( )函数看看。显然,GPIO_PinSource6跟上面的GPIO_Pin_6的值相差甚远。
void EXTIX_KEY2_Init(void)PD0按键中断函数
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //外部中断,需要使能AFIO时钟
KEY2_Init(); //初始化按键对应io模式
//GPIOA.0 中断线以及中断初始化配置
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource1);
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x02; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
上面为代码按键中断的初始化
下图为AFR寄存器的配置图
对于PD0与PD1所对应的按键的中断线分别对应的是线0与线1
STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处。STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
对中断与GPIO的关系不懂的可以结合上边的代码进行仔细的研究
下面贴上中断服务函数
void EXTI0_1_IRQHandler(void)
{
for(KEY_DELAY = 0; KEY_DELAY < 1000; KEY_DELAY++);
if(KEY2 == 0) {
LED1_TOGGLE();
}
if(KEY3 == 0) {
LED1_TOGGLE();
}
EXTI_ClearFlag(EXTI_Line0);
EXTI_ClearFlag(EXTI_Line1);
}
此处鄙人采用的都是让一个led进行翻转的函数
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/badaoshaonian/article/details/99723982
|