先看先程序效果:每按动一次按钮OLED显示的值加1.这个按键的检测是用中断完成的。
这个工程是在上一个工程:的基础上来完成的,主要是在Mycode文件夹里面新建了两个文件来创建中断的功能方式如下:结构很简单,就是count.c里面的东西有点多而已。
下面的代码是count.c文件的全部代码:
#include "stm32f10x.h" // Device header
uint16_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和7
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 速率50MHZ
GPIO_Init(GPIOB, &GPIO_InitStruct); // 端口初始化
// 第三步:配置AFIO,选择我们用的这一路GPIO连接后面的EXTI
GPIO_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; // 使能NVIC
NVIC_InittypeDef.NVIC_IRQChannelPreemptionPriority = 1; //设置当前中断的抢占优先级 2
NVIC_InittypeDef.NVIC_IRQChannelSubPriority = 1; // 设置当前中断的响应优先级 2
NVIC_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_H
void 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列 显示count
uint16_t num=0;
while(1)
{
num = count_GET();
OLED_ShowNum(2,8,num, 5);
}
}
接下来就是编译后,导入proteus中就能看到效果了。