TMS320F28379D 单片机的库函数外部中断延时函数实现多个按键消抖的程序:
时间: 2024-03-20 15:43:01 浏览: 100
消抖处理的按键程序
3星 · 编辑精心推荐
针对TMS320F28379D单片机的库函数外部中断延时函数实现多个按键消抖的程序可参考如下:
```c
#include "F2837xD_Device.h"
#include "F2837xD_Examples.h"
#define KEY1 GpioDataRegs.GPBTOGGLE.bit.GPIO34
#define KEY2 GpioDataRegs.GPBTOGGLE.bit.GPIO33
#define KEY3 GpioDataRegs.GPBTOGGLE.bit.GPIO32
#define KEY4 GpioDataRegs.GPBTOGGLE.bit.GPIO31
#define KEY1_PIN 34
#define KEY2_PIN 33
#define KEY3_PIN 32
#define KEY4_PIN 31
#define KEY_DBOUNCE_TIME 20 //按键消抖时间,单位ms
Uint16 KeyState = 0;
Uint16 KeyStateLast = 0;
void Init_GPIO_for_Key(void)
{
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO34设置为GPIO模式
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 0; // GPIO34设置为输入模式
GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; // GPIO34设置为同步模式
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0; // GPIO33设置为GPIO模式
GpioCtrlRegs.GPBDIR.bit.GPIO33 = 0; // GPIO33设置为输入模式
GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 0; // GPIO33设置为同步模式
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // GPIO32设置为GPIO模式
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 0; // GPIO32设置为输入模式
GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 0; // GPIO32设置为同步模式
GpioCtrlRegs.GPBMUX1.bit.GPIO31 = 0; // GPIO31设置为GPIO模式
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 0; // GPIO31设置为输入模式
GpioCtrlRegs.GPBQSEL1.bit.GPIO31 = 0; // GPIO31设置为同步模式
EDIS;
}
void Init_GPIO_for_LED(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0; // GPIO31设置为GPIO模式
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // GPIO31设置为输出模式
GpioDataRegs.GPASET.bit.GPIO31 = 1; // GPIO31输出高电平
GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0; // GPIO30设置为GPIO模式
GpioCtrlRegs.GPADIR.bit.GPIO30 = 1; // GPIO30设置为输出模式
GpioDataRegs.GPACLEAR.bit.GPIO30 = 1; // GPIO30输出低电平
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0; // GPIO29设置为GPIO模式
GpioCtrlRegs.GPADIR.bit.GPIO29 = 1; // GPIO29设置为输出模式
GpioDataRegs.GPACLEAR.bit.GPIO29 = 1; // GPIO29输出低电平
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 0; // GPIO28设置为GPIO模式
GpioCtrlRegs.GPADIR.bit.GPIO28 = 1; // GPIO28设置为输出模式
GpioDataRegs.GPACLEAR.bit.GPIO28 = 1; // GPIO28输出低电平
EDIS;
}
void Init_GPIO(void)
{
Init_GPIO_for_Key();
Init_GPIO_for_LED();
}
void Init_ePWM(void)
{
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // 使能 EPWM1 时钟
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 使能 Time Base 时钟同步
EDIS;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 向上计数模式
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁用相位同步
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟分频 TB_DIV1 = 1
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟分频 TB_DIV1 = 1
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 同步选择 TB_CTR_ZERO = 1
EPwm1Regs.TBCTL.bit.FREE_SOFT = 11; // 禁用 SOFT STOP
EPwm1Regs.TBCTR = 0; // Time Base 计数器清零
EPwm1Regs.CMPA.bit.CMPA = 3750; // 比较器A值,对应 50% 占空比
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // 立即设置输出A
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 当计数器增加到 CMPA 时,清空输出A
}
void Init_interrupt(void)
{
InitPieCtrl(); // 初始化 Pie 控制器
IER = 0x0000; // 禁用所有中断
IFR = 0x0000; // 清除所有中断标志
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // 使能 GPIO34 中断
PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // 使能 GPIO33 中断
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // 使能 GPIO32 中断
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // 使能 GPIO31 中断
PieVectTable.XINT1 = &Key_Interrupt; // GPIO34 中断处理函数
PieVectTable.XINT2 = &Key_Interrupt; // GPIO33 中断处理函数
PieVectTable.XINT3 = &Key_Interrupt; // GPIO32 中断处理函数
PieVectTable.XINT4 = &Key_Interrupt; // GPIO31 中断处理函数
IER |= M_INT1; // 使能中断1
EnableInterrupts(); // 使能全局中断
}
__interrupt void Key_Interrupt(void)
{
Uint16 PinNum = 0;
if(XintRegs.XINT1CR.bit.POLARITY == 0) // GPIO34 中断
{
PinNum = KEY1_PIN;
XintRegs.XINT1CR.bit.POLARITY = 1; // 下降沿触发
}
else if(XintRegs.XINT2CR.bit.POLARITY == 0) // GPIO33 中断
{
PinNum = KEY2_PIN;
XintRegs.XINT2CR.bit.POLARITY = 1; // 下降沿触发
}
else if(XintRegs.XINT3CR.bit.POLARITY == 0) // GPIO32 中断
{
PinNum = KEY3_PIN;
XintRegs.XINT3CR.bit.POLARITY = 1; // 下降沿触发
}
else if(XintRegs.XINT4CR.bit.POLARITY == 0) // GPIO31 中断
{
PinNum = KEY4_PIN;
XintRegs.XINT4CR.bit.POLARITY = 1; // 下降沿触发
}
if(PinNum > 0)
{
Uint16 KeyStateTemp = 0;
DELAY_US(KEY_DBOUNCE_TIME * 1000); // 消抖延时
if(GpioDataRegs.GPBDAT.bit.GPIO34 == 0) KeyStateTemp |= 1 << 0;
if(GpioDataRegs.GPBDAT.bit.GPIO33 == 0) KeyStateTemp |= 1 << 1;
if(GpioDataRegs.GPBDAT.bit.GPIO32 == 0) KeyStateTemp |= 1 << 2;
if(GpioDataRegs.GPBDAT.bit.GPIO31 == 0) KeyStateTemp |= 1 << 3;
KeyState = KeyStateTemp;
}
XintRegs.XINT1CR.bit.POLARITY = 0; // 上升沿触发
XintRegs.XINT2CR.bit.POLARITY = 0; // 上升沿触发
XintRegs.XINT3CR.bit.POLARITY = 0; // 上升沿触发
XintRegs.XINT4CR.bit.POLARITY = 0; // 上升沿触发
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 清除中断标志
}
void LED_Control(void)
{
if(KeyState != KeyStateLast)
{
if(KeyState & 0x01) GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;
else GpioDataRegs.GPASET.bit.GPIO31 = 1;
if(KeyState & 0x02) GpioDataRegs.GPACLEAR.bit.GPIO30 = 1;
else GpioDataRegs.GPASET.bit.GPIO30 = 1;
if(KeyState & 0x04) GpioDataRegs.GPACLEAR.bit.GPIO29 = 1;
else GpioDataRegs.GPASET.bit.GPIO29 = 1;
if(KeyState & 0x08) GpioDataRegs.GPACLEAR.bit.GPIO28 = 1;
else GpioDataRegs.GPASET.bit.GPIO28 = 1;
KeyStateLast = KeyState;
}
}
void main(void)
{
InitSysCtrl(); // 初始化系统时钟
Init_GPIO(); // 初始化 GPIO
Init_ePWM(); // 初始化 EPWM
Init_interrupt(); // 初始化中断
EINT; // 使能全局中断
while(1)
{
LED_Control(); // LED 控制
}
}
```
上述代码中,我们使用了 TMS320F28379D 单片机的 GPIO 中断功能实现了多个按键的检测。在按键检测函数中,我们使用延时函数 `DELAY_US()` 实现了按键消抖功能,确保按键的稳定性。同时,我们使用了 LED 控制函数,实现了按键状态的指示功能。
阅读全文