请解释以下程序:void InitSysCtrl(void){DisableDog();}
时间: 2023-12-16 15:06:39 浏览: 85
这是一个函数定义,函数名为 `InitSysCtrl`,没有参数,返回值为 `void`,即没有返回值。
函数内部有一条语句 `DisableDog()`,作用是禁用 watchdog 定时器。Watchdog 定时器是一种硬件定时器,用于检测系统是否出现死锁或错误,如果在规定时间内没有得到重置,就会触发复位。这条语句的作用是防止 watchdog 定时器过早地重置系统,从而保证系统的正常运行。
相关问题
TMS320F28379D 单片机的库函数外部中断延时函数实现多个按键消抖的程序:
针对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 控制函数,实现了按键状态的指示功能。
#include "DSP2833x_Device.h" #include "DSP2833x_Examples.h" #define GEN_BUZZ_CLK GpioDataRegs.GPBTOGGLE.bit.GPIO35 = 1 //蜂鸣器控制IO,IO电平翻转,产生控制脉冲 #define BUZZ_OFF GpioDataRegs.GPBCLEAR.bit.GPIO35 = 1 //关闭蜂鸣器 #define MAXWARNTIMES 3 float t1=1; float t2=3; Uint16 N1=0; Uint16 N2=0; Uint16 WarnTimes=0; float freq0=1000; // 定时器0的中断频率(Hz) float prd0=0; // 定时器0的中断周期(sec)=1/freq0/2,对于方波,一个周期要中断2次 void InitBuzzGpio(void); interrupt void cpu_timer0_isr(void); void main(void) { N1=(Uint16)(t1/prd0); N2=(Uint16)(t1+t2/prd0); // Step 1. 系统控制初始化 InitSysCtrl(); // 蜂鸣器(Buzz)引脚初始化 InitBuzzGpio(); // Step 3. 清除所有中断、初始化PIE向量表,关闭cpu中断 DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); // 初始化TIMER0功能 EALLOW; PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; InitCpuTimers(); prd0=1/(freq0*2); // 一个时钟周期,前半为H电平,后半为L电平。 ConfigCpuTimer(&CpuTimer0, 150, prd0*1e6);//定时周期单位:us IER |= M_INT1; // 使能TINT0(TINT0在INT1的第7个) PieCtrlRegs.PIEIER1.bit.INTx7 = 1; EINT; // 使能全局中断(EINT) ERTM; // 使能实时中断(ERTM) StartCpuTimer0(); // 启动定时器0 for(;;); // 或while(1); 死循环,不能让CPU停下来 } /*****************************************初始化IO端口************************************************/ void InitBuzzGpio(void) { EALLOW; GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 0; // GPIO35 = GPIO GpioCtrlRegs.GPBDIR.bit.GPIO35 = 1; // GPIO35 = output GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0; // Enable pullup on GPIO35 GpioDataRegs.GPBSET.bit.GPIO35 = 1; // Load output latch EDIS; } interrupt void cpu_timer0_isr(void) { CpuTimer0.InterruptCount++; if(CpuTimer0.InterruptCount<=N1) { GEN_BUZZ_CLK; } else if(CpuTimer0.InterruptCount<=N2) { BUZZ_OFF; } else { CpuTimer0.InterruptCount=0; } PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }
这段代码是用来控制蜂鸣器的,主要包括初始化IO口、配置定时器、编写定时器中断服务程序等。具体来说,它通过定时器0的中断来产生控制脉冲,从而驱动蜂鸣器发声。其中使用了一些宏定义来方便代码的编写,例如GEN_BUZZ_CLK用于产生控制脉冲,BUZZ_OFF用于关闭蜂鸣器。同时,它也设置了一些变量来控制蜂鸣器的鸣叫次数和频率等参数。最后,在main函数中启动了定时器0并进入死循环,以确保程序一直运行。
阅读全文