先看先程序效果:每按动一次按钮OLED显示的值加1.这个按键的检测是用中断完成的。
这个工程是在上一个工程:的基础上来完成的,主要是在Mycode文件夹里面新建了两个文件来创建中断的功能方式如下:结构很简单,就是count.c里面的东西有点多而已。
下面的代码是count.c文件的全部代码:
#include "stm32f10x.h" // Device headeruint16_t num=0;void count_init(void)
{// 第一步:配置RCC,把涉及的外设时钟都打开RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOA的时钟RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE); //开始AFIO的时钟// 第二步:配置GPIO,选择我们的端口为输入模式GPIO_InitTypeDef GPIO_InitStruct; // 创建GPIO配置的结构体GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; // 引脚2和7GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 速率50MHZGPIO_Init(GPIOB, &GPIO_InitStruct); // 端口初始化// 第三步:配置AFIO,选择我们用的这一路GPIO连接后面的EXTIGPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);// 第四步:配置EXTI,选择触发方式,比如上升沿,下降沿或者双边沿。还有选择触发方式:中断响应和事件响应EXTI_InitTypeDef EXTI_InitStruct; // 创建外部中断初始化结构体EXTI_InitStruct.EXTI_Line = EXTI_Line14; //使用2号线EXTI_InitStruct.EXTI_LineCmd = ENABLE; //使能中断(开启中断)EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断触发EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发EXTI_Init(&EXTI_InitStruct); //初始化外部中断// 第五步:配置NVIC,选择中断的合适的优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC分组。2位抢占,2为响应NVIC_InitTypeDef NVIC_InittypeDef;NVIC_InittypeDef.NVIC_IRQChannel = EXTI15_10_IRQn; //NVIC通道选择9_5通道NVIC_InittypeDef.NVIC_IRQChannelCmd = ENABLE; // 使能NVICNVIC_InittypeDef.NVIC_IRQChannelPreemptionPriority = 1; //设置当前中断的抢占优先级 2NVIC_InittypeDef.NVIC_IRQChannelSubPriority = 1; // 设置当前中断的响应优先级 2NVIC_Init(&NVIC_InittypeDef);// 最后通过NVIC,外部中断信号就能进入CPU了。}
//获取num的值的函数
uint16_t count_GET(void)
{return num;
}// 中断函数从启动文件中复制过来的,不能写错,错了就进不来了。
void EXTI15_10_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line14) == SET) // 看看是不是由Line2过来的中断标志{num++;}EXTI_ClearITPendingBit(EXTI_Line14); // 清楚line2的中断标志位
}
配置中断总共分了5步来完成的:
下面是count.h的内容,这个比较简单:
#ifndef __COUNT_H
#define __COUNT_Hvoid count_init(void);uint16_t count_GET(void); //获取num值的函数#endif
剩下的就是main函数了,去调用这些个自己写的函数就可以了:
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "count.h"int main(void)
{OLED_Init(); //oled 屏幕初始化count_init(); //计数中断初始化OLED_ShowString(2,1, "Count:"); // 1行5列 显示countuint16_t num=0;while(1){num = count_GET();OLED_ShowNum(2,8,num, 5);}
}
接下来就是编译后,导入proteus中就能看到效果了。