33. 定时器按键消抖实验
作者:互联网
一、定时器按键消抖简介
当按键按下以后,进入到中断服务函数中,开始一个定时器,定时周期位10ms,只有最后一个抖动信号开启的定时器才能完成的执行完一个周期。当定时器产生周期中断以后就在中断服务函数里面做具体的处理,比如开关蜂鸣器。
二、实验原理简介
三、实验程序编写
//bsp_epitimer.c
#include "bsp_epittimer.h"
#include "bsp_int.h"
#include "bsp_led.h"
/*
* @description : 初始化EPIT定时器.
* EPIT定时器是32位向下计数器,时钟源使用ipg=66Mhz
* @param - frac : 分频值,范围为0~4095,分别对应1~4096分频。
* @param - value : 倒计数值。
* @return : 无
*/
void epit1_init(unsigned int frac, unsigned int value)
{
if(frac > 0XFFF)
frac = 0XFFF;
EPIT1->CR = 0; /* 先清零CR寄存器 */
/*
* CR寄存器:
* bit25:24 01 时钟源选择Peripheral clock=66MHz
* bit15:4 frac 分频值
* bit3: 1 当计数器到0的话从LR重新加载数值
* bit2: 1 比较中断使能
* bit1: 1 初始计数值来源于LR寄存器值
* bit0: 0 先关闭EPIT1
*/
EPIT1->CR = (1<<24 | frac << 4 | 1<<3 | 1<<2 | 1<<1);
EPIT1->LR = value; /* 倒计数值 */
EPIT1->CMPR = 0; /* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 */
/* 使能GIC中对应的中断 */
GIC_EnableIRQ(EPIT1_IRQn);
/* 注册中断服务函数 */
system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)epit1_irqhandler, NULL);
EPIT1->CR |= 1<<0; /* 使能EPIT1 */
}
/*
* @description : EPIT中断处理函数
* @param : 无
* @return : 无
*/
void epit1_irqhandler(void)
{
static unsigned char state = 0;
state = !state;
if(EPIT1->SR & (1<<0)) /* 判断比较事件发生 */
{
led_switch(LED0, state); /* 定时器周期到,反转LED */
}
EPIT1->SR |= 1<<0; /* 清除中断标志位 */
}
//bsp_exit.c
#include "bsp_exit.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "bsp_beep.h"
/*
* @description : 初始化外部中断
* @param : 无
* @return : 无
*/
void exit_init(void)
{
gpio_pin_config_t key_config;
/* 1、设置IO复用 */
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0); /* 复用为GPIO1_IO18 */
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);
/* 2、初始化GPIO为中断模式 */
key_config.direction = kGPIO_DigitalInput;
key_config.interruptMode = kGPIO_IntFallingEdge;
key_config.outputLogic = 1;
gpio_init(GPIO1, 18, &key_config);
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn); /* 使能GIC中对应的中断 */
system_register_irqhandler(GPIO1_Combined_16_31_IRQn, (system_irq_handler_t)gpio1_io18_irqhandler, NULL); /* 注册中断服务函数 */
gpio_enableint(GPIO1, 18); /* 使能GPIO1_IO18的中断功能 */
}
/*
* @description : GPIO1_IO18最终的中断处理函数
* @param : 无
* @return : 无
*/
void gpio1_io18_irqhandler(void)
{
static unsigned char state = OFF;
/*
*采用延时消抖,中断服务函数中禁止使用延时函数!因为中断服务需要
*快进快出!!这里为了演示所以采用了延时函数进行消抖,后面我们会讲解
*定时器中断消抖法!!!
*/
delay(10);
if(gpio_pinread(GPIO1, 18) == 0) /* 按键按下了 */
{
state = !state;
beep_switch(state);
}
gpio_clearintflags(GPIO1, 18); /* 清除中断标志位 */
}
//bsp_gpio.c
#include "bsp_gpio.h"
/*
* @description : GPIO初始化。
* @param - base : 要初始化的GPIO组。
* @param - pin : 要初始化GPIO在组内的编号。
* @param - config : GPIO配置结构体。
* @return : 无
*/
void gpio_init(GPIO_Type *base, int pin, gpio_pin_config_t *config)
{
base->IMR &= ~(1U << pin);
if(config->direction == kGPIO_DigitalInput) /* GPIO作为输入 */
{
base->GDIR &= ~( 1 << pin);
}
else /* 输出 */
{
base->GDIR |= 1 << pin;
gpio_pinwrite(base,pin, config->outputLogic); /* 设置默认输出电平 */
}
gpio_intconfig(base, pin, config->interruptMode); /* 中断功能配置 */
}
/*
* @description : 读取指定GPIO的电平值 。
* @param - base : 要读取的GPIO组。
* @param - pin : 要读取的GPIO脚号。
* @return : 无
*/
int gpio_pinread(GPIO_Type *base, int pin)
{
return (((base->DR) >> pin) & 0x1);
}
/*
* @description : 指定GPIO输出高或者低电平 。
* @param - base : 要输出的的GPIO组。
* @param - pin : 要输出的GPIO脚号。
* @param - value : 要输出的电平,1 输出高电平, 0 输出低低电平
* @return : 无
*/
void gpio_pinwrite(GPIO_Type *base, int pin, int value)
{
if (value == 0U)
{
base->DR &= ~(1U << pin); /* 输出低电平 */
}
else
{
base->DR |= (1U << pin); /* 输出高电平 */
}
}
/*
* @description : 设置GPIO的中断配置功能
* @param - base : 要配置的IO所在的GPIO组。
* @param - pin : 要配置的GPIO脚号。
* @param - pinInterruptMode: 中断模式,参考枚举类型gpio_interrupt_mode_t
* @return : 无
*/
void gpio_intconfig(GPIO_Type* base, unsigned int pin, gpio_interrupt_mode_t pin_int_mode)
{
volatile uint32_t *icr;
uint32_t icrShift;
icrShift = pin;
base->EDGE_SEL &= ~(1U << pin);
if(pin < 16) /* 低16位 */
{
icr = &(base->ICR1);
}
else /* 高16位 */
{
icr = &(base->ICR2);
icrShift -= 16;
}
switch(pin_int_mode)
{
case(kGPIO_IntLowLevel):
*icr &= ~(3U << (2 * icrShift));
break;
case(kGPIO_IntHighLevel):
*icr = (*icr & (~(3U << (2 * icrShift)))) | (1U << (2 * icrShift));
break;
case(kGPIO_IntRisingEdge):
*icr = (*icr & (~(3U << (2 * icrShift)))) | (2U << (2 * icrShift));
break;
case(kGPIO_IntFallingEdge):
*icr |= (3U << (2 * icrShift));
break;
case(kGPIO_IntRisingOrFallingEdge):
base->EDGE_SEL |= (1U << pin);
break;
default:
break;
}
}
/*
* @description : 使能GPIO的中断功能
* @param - base : 要使能的IO所在的GPIO组。
* @param - pin : 要使能的GPIO在组内的编号。
* @return : 无
*/
void gpio_enableint(GPIO_Type* base, unsigned int pin)
{
base->IMR |= (1 << pin);
}
/*
* @description : 禁止GPIO的中断功能
* @param - base : 要禁止的IO所在的GPIO组。
* @param - pin : 要禁止的GPIO在组内的编号。
* @return : 无
*/
void gpio_disableint(GPIO_Type* base, unsigned int pin)
{
base->IMR &= ~(1 << pin);
}
/*
* @description : 清除中断标志位(写1清除)
* @param - base : 要清除的IO所在的GPIO组。
* @param - pin : 要清除的GPIO掩码。
* @return : 无
*/
void gpio_clearintflags(GPIO_Type* base, unsigned int pin)
{
base->ISR |= (1 << pin);
}
//bsp_int.c
#include "bsp_int.h"
/* 中断嵌套计数器 */
static unsigned int irqNesting;
/* 中断服务函数表 */
static sys_irq_handle_t irqTable[NUMBER_OF_INT_VECTORS];
/*
* @description : 中断初始化函数
* @param : 无
* @return : 无
*/
void int_init(void)
{
GIC_Init(); /* 初始化GIC */
system_irqtable_init(); /* 初始化中断表 */
__set_VBAR((uint32_t)0x87800000); /* 中断向量表偏移,偏移到起始地址 */
}
/*
* @description : 初始化中断服务函数表
* @param : 无
* @return : 无
*/
void system_irqtable_init(void)
{
unsigned int i = 0;
irqNesting = 0;
/* 先将所有的中断服务函数设置为默认值 */
for(i = 0; i < NUMBER_OF_INT_VECTORS; i++)
{
system_register_irqhandler((IRQn_Type)i,default_irqhandler, NULL);
}
}
/*
* @description : 给指定的中断号注册中断服务函数
* @param - irq : 要注册的中断号
* @param - handler : 要注册的中断处理函数
* @param - usrParam : 中断服务处理函数参数
* @return : 无
*/
void system_register_irqhandler(IRQn_Type irq, system_irq_handler_t handler, void *userParam)
{
irqTable[irq].irqHandler = handler;
irqTable[irq].userParam = userParam;
}
/*
* @description : C语言中断服务函数,irq汇编中断服务函数会
调用此函数,此函数通过在中断服务列表中查
找指定中断号所对应的中断处理函数并执行。
* @param - giccIar : 中断号
* @return : 无
*/
void system_irqhandler(unsigned int giccIar)
{
uint32_t intNum = giccIar & 0x3FFUL;
/* 检查中断号是否符合要求 */
if ((intNum == 1023) || (intNum >= NUMBER_OF_INT_VECTORS))
{
return;
}
irqNesting++; /* 中断嵌套计数器加一 */
/* 根据传递进来的中断号,在irqTable中调用确定的中断服务函数*/
irqTable[intNum].irqHandler(intNum, irqTable[intNum].userParam);
irqNesting--; /* 中断执行完成,中断嵌套寄存器减一 */
}
/*
* @description : 默认中断服务函数
* @param - giccIar : 中断号
* @param - usrParam : 中断服务处理函数参数
* @return : 无
*/
void default_irqhandler(unsigned int giccIar, void *userParam)
{
while(1)
{
}
}
//bsp_key.c
#include "bsp_key.h"
#include "bsp_gpio.h"
#include "bsp_delay.h"
/*
* @description : 初始化按键
* @param : 无
* @return : 无
*/
void key_init(void)
{
gpio_pin_config_t key_config;
/* 1、初始化IO复用, 复用为GPIO1_IO18 */
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0);
/* 2、、配置UART1_CTS_B的IO属性
*bit 16:0 HYS关闭
*bit [15:14]: 11 默认22K上拉
*bit [13]: 1 pull功能
*bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 000 关闭输出
*bit [0]: 0 低转换率
*/
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);
/* 3、初始化GPIO */
//GPIO1->GDIR &= ~(1 << 18); /* GPIO1_IO18设置为输入 */
key_config.direction = kGPIO_DigitalInput;
gpio_init(GPIO1,18, &key_config);
}
/*
* @description : 获取按键值
* @param : 无
* @return : 0 没有按键按下,其他值:对应的按键值
*/
int key_getvalue(void)
{
int ret = 0;
static unsigned char release = 1; /* 按键松开 */
if((release==1)&&(gpio_pinread(GPIO1, 18) == 0)) /* KEY0 */
{
delay(10); /* 延时消抖 */
release = 0; /* 标记按键按下 */
if(gpio_pinread(GPIO1, 18) == 0)
ret = KEY0_VALUE;
}
else if(gpio_pinread(GPIO1, 18) == 1)
{
ret = 0;
release = 1; /* 标记按键释放 */
}
return ret;
}
//bsp_keyfilter.c
#include "bsp_key.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_beep.h"
#include "bsp_keyfilter.h"
/*
* @description : 按键初始化
* @param : 无
* @return : 无
*/
void filterkey_init(void)
{
gpio_pin_config_t key_config;
/* 1、初始化IO复用 */
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0); /* 复用为GPIO1_IO18 */
/* 2、、配置GPIO1_IO18的IO属性
*bit 16:0 HYS关闭
*bit [15:14]: 11 默认22K上拉
*bit [13]: 1 pull功能
*bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 000 关闭输出
*bit [0]: 0 低转换率
*/
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0xF080);
/* 3、初始化GPIO为中断 */
key_config.direction = kGPIO_DigitalInput;
key_config.interruptMode = kGPIO_IntFallingEdge;
key_config.outputLogic = 1;
gpio_init(GPIO1, 18, &key_config);
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn); /* 使能GIC中对应的中断 */
/* 注册中断服务函数 */
system_register_irqhandler(GPIO1_Combined_16_31_IRQn,
(system_irq_handler_t)gpio1_16_31_irqhandler,
NULL);
gpio_enableint(GPIO1, 18); /* 使能GPIO1_IO18的中断功能 */
filtertimer_init(66000000/100); /* 初始化定时器,10ms */
}
/*
* @description : 初始化用于消抖的定时器,默认关闭定时器
* @param - value : 定时器EPIT计数值
* @return : 无
*/
void filtertimer_init(unsigned int value)
{
EPIT1->CR = 0; //先清零
/*
* CR寄存器:
* bit25:24 01 时钟源选择Peripheral clock=66MHz
* bit15:4 0 1分频
* bit3: 1 当计数器到0的话从LR重新加载数值
* bit2: 1 比较中断使能
* bit1: 1 初始计数值来源于LR寄存器值
* bit0: 0 先关闭EPIT1
*/
EPIT1->CR = (1<<24 | 1<<3 | 1<<2 | 1<<1);
/* 计数值 */
EPIT1->LR = value;
/* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 */
EPIT1->CMPR = 0;
GIC_EnableIRQ(EPIT1_IRQn); /* 使能GIC中对应的中断 */
/* 注册中断服务函数 */
system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)filtertimer_irqhandler, NULL);
}
/*
* @description : 关闭定时器
* @param : 无
* @return : 无
*/
void filtertimer_stop(void)
{
EPIT1->CR &= ~(1<<0); /* 关闭定时器 */
}
/*
* @description : 重启定时器
* @param - value : 定时器EPIT计数值
* @return : 无
*/
void filtertimer_restart(unsigned int value)
{
EPIT1->CR &= ~(1<<0); /* 先关闭定时器 */
EPIT1->LR = value; /* 计数值 */
EPIT1->CR |= (1<<0); /* 打开定时器 */
}
/*
* @description : 定时器中断处理函数
* @param : 无
* @return : 无
*/
void filtertimer_irqhandler(void)
{
static unsigned char state = OFF;
if(EPIT1->SR & (1<<0)) /* 判断比较事件是否发生 */
{
filtertimer_stop(); /* 关闭定时器 */
if(gpio_pinread(GPIO1, 18) == 0) /* KEY0 */
{
state = !state;
beep_switch(state); /* 反转蜂鸣器 */
}
}
EPIT1->SR |= 1<<0; /* 清除中断标志位 */
}
/*
* @description : GPIO中断处理函数
* @param : 无
* @return : 无
*/
void gpio1_16_31_irqhandler(void)
{
/* 开启定时器 */
filtertimer_restart(66000000/100);
/* 清除中断标志位 */
gpio_clearintflags(GPIO1, 18);
}
//bsp_clk.c
#include "bsp_clk.h"
/*
* @description : 使能I.MX6U所有外设时钟
* @param : 无
* @return : 无
*/
void clk_enable(void)
{
CCM->CCGR0 = 0XFFFFFFFF;
CCM->CCGR1 = 0XFFFFFFFF;
CCM->CCGR2 = 0XFFFFFFFF;
CCM->CCGR3 = 0XFFFFFFFF;
CCM->CCGR4 = 0XFFFFFFFF;
CCM->CCGR5 = 0XFFFFFFFF;
CCM->CCGR6 = 0XFFFFFFFF;
}
/*
* @description : 初始化系统时钟,设置系统时钟为528Mhz,并且设置PLL2和PLL3各个
PFD时钟,所有的时钟频率均按照I.MX6U官方手册推荐的值.
* @param : 无
* @return : 无
*/
void imx6u_clkinit(void)
{
unsigned int reg = 0;
/* 1、设置ARM内核时钟为528MHz */
/* 1.1、判断当前ARM内核是使用的那个时钟源启动的,正常情况下ARM内核是由pll1_sw_clk驱动的,而
* pll1_sw_clk有两个来源:pll1_main_clk和tep_clk(参考手册648页)。
* 如果我们要让ARM内核跑到528M的话那必须选择pll1_main_clk作为pll1的时钟源。
* 如果我们要修改pll1_main_clk时钟的话就必须先将pll1_sw_clk从pll1_main_clk切换到step_clk,
* 当修改完pll1_main_clk以后在将pll1_sw_clk切换回pll1_main_clk。而step_clk的时钟源可以选择
* 板子上的24MHz晶振。
*/
if((((CCM->CCSR) >> 2) & 0x1 ) == 0) /* 当前pll1_sw_clk使用的pll1_main_clk*/
{
CCM->CCSR &= ~(1 << 8); /* 配置step_clk时钟源为24MH OSC */
CCM->CCSR |= (1 << 2); /* 配置pll1_sw_clk时钟源为step_clk */
}
/* 1.2、设置pll1_main_clk为1056MHz,也就是528*2=1056MHZ,
* 因为pll1_sw_clk进ARM内核的时候会被二分频!
* 配置CCM_ANLOG->PLL_ARM寄存器
* bit13: 1 使能时钟输出
* bit[6:0]: 88, 由公式:Fout = Fin * div_select / 2.0,1056=24*div_select/2.0,
* 得出:div_select= 88
*/
CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F); /* 配置pll1_main_clk=1056MHz */
CCM->CCSR &= ~(1 << 2); /* 将pll_sw_clk时钟重新切换回pll1_main_clk */
CCM->CACRR = 1; /* ARM内核时钟为pll1_sw_clk/2=1056/2=528Mhz */
/* 2、设置PLL2(SYS PLL)各个PFD */
reg = CCM_ANALOG->PFD_528;
reg &= ~(0X3F3F3F3F); /* 清除原来的设置 */
reg |= 32<<24; /* PLL2_PFD3=528*18/32=297Mhz */
reg |= 24<<16; /* PLL2_PFD2=528*18/24=396Mhz(DDR使用的时钟,最大400Mhz) */
reg |= 16<<8; /* PLL2_PFD1=528*18/16=594Mhz */
reg |= 27<<0; /* PLL2_PFD0=528*18/27=352Mhz */
CCM_ANALOG->PFD_528=reg; /* 设置PLL2_PFD0~3 */
/* 3、设置PLL3(USB1)各个PFD */
reg = 0; /* 清零 */
reg = CCM_ANALOG->PFD_480;
reg &= ~(0X3F3F3F3F); /* 清除原来的设置 */
reg |= 19<<24; /* PLL3_PFD3=480*18/19=454.74Mhz */
reg |= 17<<16; /* PLL3_PFD2=480*18/17=508.24Mhz */
reg |= 16<<8; /* PLL3_PFD1=480*18/16=540Mhz */
reg |= 12<<0; /* PLL3_PFD0=480*18/12=720Mhz */
CCM_ANALOG->PFD_480=reg; /* 设置PLL3_PFD0~3 */
/* 4、设置AHB时钟 最小6Mhz, 最大132Mhz (boot rom自动设置好了可以不用设置)*/
CCM->CBCMR &= ~(3 << 18); /* 清除设置*/
CCM->CBCMR |= (1 << 18); /* pre_periph_clk=PLL2_PFD2=396MHz */
CCM->CBCDR &= ~(1 << 25); /* periph_clk=pre_periph_clk=396MHz */
while(CCM->CDHIPR & (1 << 5));/* 等待握手完成 */
/* 修改AHB_PODF位的时候需要先禁止AHB_CLK_ROOT的输出,但是
* 我没有找到关闭AHB_CLK_ROOT输出的的寄存器,所以就没法设置。
* 下面设置AHB_PODF的代码仅供学习参考不能直接拿来使用!!
* 内部boot rom将AHB_PODF设置为了3分频,即使我们不设置AHB_PODF,
* AHB_ROOT_CLK也依旧等于396/3=132Mhz。
*/
#if 0
/* 要先关闭AHB_ROOT_CLK输出,否则时钟设置会出错 */
CCM->CBCDR &= ~(7 << 10); /* CBCDR的AHB_PODF清零 */
CCM->CBCDR |= 2 << 10; /* AHB_PODF 3分频,AHB_CLK_ROOT=132MHz */
while(CCM->CDHIPR & (1 << 1));/
* 等待握手完成 */
#endif
/* 5、设置IPG_CLK_ROOT最小3Mhz,最大66Mhz (boot rom自动设置好了可以不用设置)*/
CCM->CBCDR &= ~(3 << 8); /* CBCDR的IPG_PODF清零 */
CCM->CBCDR |= 1 << 8; /* IPG_PODF 2分频,IPG_CLK_ROOT=66MHz */
/* 6、设置PERCLK_CLK_ROOT时钟 */
CCM->CSCMR1 &= ~(1 << 6); /* PERCLK_CLK_ROOT时钟源为IPG */
CCM->CSCMR1 &= ~(7 << 0); /* PERCLK_PODF位清零,即1分频 */
}
//bsp_beep.c
#include "bsp_beep.h"
/*
* @description : 初始化蜂鸣器对应的IO
* @param : 无
* @return : 无
*/
void beep_init(void)
{
/* 1、初始化IO复用,复用为GPIO5_IO01 */
IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0);
/* 2、、配置GPIO1_IO03的IO属性
*bit 16:0 HYS关闭
*bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper功能
*bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 110 R0/6驱动能力
*bit [0]: 0 低转换率
*/
IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER1_GPIO5_IO01,0X10B0);
/* 3、初始化GPIO,GPIO5_IO01设置为输出 */
GPIO5->GDIR |= (1 << 1);
/* 4、设置GPIO5_IO01输出高电平,关闭蜂鸣器 */
GPIO5->DR |= (1 << 1);
}
/*
* @description : 蜂鸣器控制函数,控制蜂鸣器打开还是关闭
* @param - status : 0,关闭蜂鸣器,1 打开蜂鸣器
* @return : 无
*/
void beep_switch(int status)
{
if(status == OFF)
GPIO5->DR &= ~(1 << 1); /* 打开蜂鸣器 */
else if(status == ON)
GPIO5->DR |= (1 << 1); /* 关闭蜂鸣器 */
}
//bsp_lec.
#include "bsp_led.h"
/*
* @description : 初始化LED对应的GPIO
* @param : 无
* @return : 无
*/
void led_init(void)
{
/* 1、初始化IO复用 */
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); /* 复用为GPIO1_IO03 */
/* 2、、配置GPIO1_IO03的IO属性
*bit 16:0 HYS关闭
*bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper功能
*bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 110 R0/6驱动能力
*bit [0]: 0 低转换率
*/
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
/* 3、初始化GPIO,GPIO1_IO03设置为输出*/
GPIO1->GDIR |= (1 << 3);
/* 4、设置GPIO1_IO03输出低电平,打开LED0*/
GPIO1->DR &= ~(1 << 3);
}
/*
* @description : LED控制函数,控制LED打开还是关闭
* @param - led : 要控制的LED灯编号
* @param - status : 0,关闭LED0,1 打开LED0
* @return : 无
*/
void led_switch(int led, int status)
{
switch(led)
{
case LED0:
if(status == ON)
GPIO1->DR &= ~(1<<3); /* 打开LED0 */
else if(status == OFF)
GPIO1->DR |= (1<<3); /* 关闭LED0 */
break;
}
}
//bsp_delay.c
#include "bsp_delay.h"
/*
* @description : 短时间延时函数
* @param - n : 要延时循环次数(空操作循环次数,模式延时)
* @return : 无
*/
void delay_short(volatile unsigned int n)
{
while(n--){}
}
/*
* @description : 延时函数,在396Mhz的主频下
* 延时时间大约为1ms
* @param - n : 要延时的ms数
* @return : 无
*/
void delay(volatile unsigned int n)
{
while(n--)
{
delay_short(0x7ff);
}
}
标签:定时器,33,bsp,void,消抖,param,中断,GPIO1,bit 来源: https://blog.csdn.net/lljss1980/article/details/115148272