Day4
目录
三、NVIC中断控制器(nested vectored interrupt controller)
一、蜂鸣器实验
1.蜂鸣器介绍
2.硬件连接图
3.详细代码
【beep.c】
#include "beep.h"
//初始化PF8为输出口
//BEEP IO初始化
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//初始化蜂鸣器对应引脚GPIOF8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
GPIO_ResetBits(GPIOF,GPIO_Pin_8); //蜂鸣器对应引脚GPIOF8拉低,
}
【beeph】
#ifndef __BEEP_H
#define __BEEP_H
#include "studio.h"
//LED端口定义
#define BEEP PFout(8) // 蜂鸣器控制IO
void BEEP_Init(void);//初始化
#endif
【main.c】
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
int main(void)
{
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
BEEP_Init(); //初始化蜂鸣器端口
while(1)
{
GPIO_ResetBits(GPIOF,GPIO_Pin_9); // DS0拉低,亮 等同LED0=0;
GPIO_ResetBits(GPIOF,GPIO_Pin_8); //BEEP引脚拉低, 等同BEEP=0;
delay_ms(300); //延时300ms
GPIO_SetBits(GPIOF,GPIO_Pin_9); // DS0拉高,灭 等同LED0=1;
GPIO_SetBits(GPIOF,GPIO_Pin_8); //BEEP引脚拉高, 等同BEEP=1;
delay_ms(300); //延时300ms
}
}
二、按键输入
1.硬件原理图
2.C语言关键字:static
局部变量,存储在静态存储区,函数调用结束后不会被释放,值回一直被保留下来,因此static申明的局部变量具有记忆功能
例如,第一次调用flag初始化为0,返回值为1,第二次调用不再初始化,返回值为2,第三次的调用返回值为3
3.手敲代码
首先配置Key
【Key.c】
#include "stm32f10x.h"
void Delay(__IO u32 nCount) //简单的延时函数
{
for(; nCount !=0;nCount--);
}
/**
* @brief描述:配置案件的IO口
* @param输入:/
* @retval返回值:/
*/
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*开启按键端口PE5的时钟*/
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
//GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; 输入的时候可写可不写
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
#define KEY_ON 0
#define KEY_OFF 1
/**
* @brief描述:检测是否由按键按下
* @param输入:GPIOx
GPIO_Pin:待读取的端口位
* @retval返回值:KEY_OFF,KEY_ON
*/
u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)
{
/*检测是否有按键按下*/
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON)
{
/*延时消抖*/
Delay(10000);
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON)
{
/*等待按键释放*/
while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON);
return KEY_ON;
}
else
return KEY_OFF;
}
else
return KEY_OFF;
}
添加Key的头文件
【Key.h】
#ifndef __KEY_H__
#define __KEY_H__
void Key_GPIO_Config(void);
u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin);
#endif
写main主函数
【main.c】
#include "stm32f10x.h"
#include "Key.h"
#include "led.h"
#define KEY_ON 0
#define KEY_OFF 1
int main(void)
{
/*初始化led*/
LED_GPIO_Config();
LED1(ON);
/*初始化按键*/
Key_GPIO_Config();
while(1)
{
if(Key_Scan(GPIOE,GPIO_Pin_5)==KEY_ON)
{
/*led1反转*/
GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction) \
((1-GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3))));
//把(1-GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3))的值写入到GPIOC下的GPIO_Pin_3中
}
}
}
无错误,完成!
三、NVIC中断控制器(nested vectored interrupt controller)
1.应用举例
可以把按键轮询检测改为由中断处理,提高执行效率
注意:NVIC属于cortex内核期间,不可屏蔽中断和外部中断都由他处理,SYSTICK不是由他处理的
2.NVIC的优先级组
NVIC有五组分组方式,采用库函数NVIC_PriorityGroupConfig(),可输入的参数为NVIC_PriorityGroup_0~ NVIC_PriorityGroup_4
举例
3.寄存器结构体
4.中断的初始化
5.中断使用总结
6.在实际工程中的应用
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_key.h"
/**
* @brief 配置嵌套向量中断控制器NVIC
* @param 无
* @retval 无
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief描述:配置PE5为中断口,并设置中断优先级
* @param输入:\
* @retval返回值\
*/
void EXTI_PE5_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure; \
/*配置PE5的外部时钟和AFIO时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
/*配置PE5的NVIC中断优先级*/
NVIC_Configuration();
/*配置GPIO中断线IO*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure);
/*选定要配置为EXTI的IO'口和IO口的工作模式*/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line = EXTI_Line5;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿中断
EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能
EXTI_Init(&EXTI_InitStructure);
}
/**
* @brief描述:中断服务函数
* @param输入:\
* @retval返回值:\
*/
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5)!=RESET) //确保是否产生EXTILine'中断
{//LED1取反
GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction) \
((1-GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3))));
EXTI_ClearITPendingBit(EXTI_Line5); //手动清除中断标志位
}
}
在上述工程文件中,就声明了NVIC的初始化,设置了中断的优先级,随后在EXTI外部中断函数中调用
四、今日总结
今天的学习内容主要是蜂鸣器,按键和NVIC中断,按键的代码跟着《库开发实战指南》上认真输入了一边,跟LED类似,主要是首先配置GPIO,之后分别写好头文件,再从main函数中调用,感觉思路还是很清晰的。
但是也的确感觉得到,正点原子的课虽然简洁,但是内容不够详细,很多东西一带而过,代码也只是展示一遍,因此我之后的学习思路应该是先看一遍视频作预习,之后不懂得地方看书钻研,之后跟着书本敲一遍代码,我觉得这样效果是比起只看视频要好的,敲代码虽然慢,但是保证不落下进度的话效果还是好的。
另外代码虽然无ERROR了,但是仿真器没到,也不知道能否在板子上运行,希望吧。
后记:买了新的仿真器,程序运行成功了(偷喜)