C6748_NMI

来源:互联网 发布:朝鲜脱北者 知乎 编辑:程序博客网 时间:2024/05/29 03:39

1.主函数流程

此程序的作用是实现不可屏蔽中断功能。NMI(NonMaskableInterrupt)——不可屏蔽中断(即CPU不能屏蔽),无论状态寄存器中IF位的状态如何,CPU收到有效的NMI必须进行响应。主函数如下:

intmain(void)

{

    //外设使能配置

    PSCInit();

     

    // GPIO管脚复用配置

    GPIOBankPinMuxSet();

 

    // DSP中断初始化

    InterruptInit();

 

    // GPIO管脚初始化

    GPIOBankPinInit();

 

    //主循环

    for(;;)

    {

 

    }

}

2.外设使能配置

    函数首先在PSC模块中使能外设,这里是GPIO模块。外设使能配置函数PSCInit如下:

voidPSCInit(void)

{

    //使能 GPIO模块

    //对相应外设模块的使能也可以在 BootLoader中完成

PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

}

函数在PSC中使能HW_PSC_GPIO(#3)模块,该模块的Power Domain是ALWAYS_ON域(POWER DOMAIN 0),PSCModuleControl细节可参考这里:

C6748_UART_EDMA

(指南P163)

3.GPIO管脚复用配置

    GPIO管脚复用配置函数如下:

voidGPIOBankPinMuxSet(void)

{

    //配置相应的 GPIO口功能为普通输入输出口

    //核心板 LED

    GPIOBank6Pin12PinMuxSetup();

    GPIOBank6Pin13PinMuxSetup();

}

GPIOBank6Pin12PinMuxSetup函数和GPIOBank6Pin13PinMuxSetup函数将GPIO[12]和GPIO[13]这两个引脚设为普通输入输出口(即GPIO口)。这两个函数在demo\StarterWare\Application\Platform工程下的GPIO.c文件中,GPIOBank6Pin12PinMuxSetup函数如下:

voidGPIOBank6Pin12PinMuxSetup(void)

{

unsignedint savePinmux=0;

 

savePinmux= (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(13))&

~(SYSCFG_PINMUX13_PINMUX13_15_12));

 

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(13))=

(PINMUX13_GPIO6_12_ENABLE| savePinmux);

}

GPIOBank6Pin13PinMuxSetup函数如下:

voidGPIOBank6Pin13PinMuxSetup(void)

{

unsignedint savePinmux=0;

 

savePinmux= (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(13))&

~(SYSCFG_PINMUX13_PINMUX13_11_8));

 

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(13))=

(PINMUX13_GPIO6_13_ENABLE| savePinmux);

}

4.DSP中断初始化

    DSP中断初始化函数InterruptInit如下:

voidInterruptInit(void)

{

    //初始化 DSP中断控制器

    IntDSPINTCInit();

 

    //注册中断服务函数

    IntRegister(C674X_MASK_NMI, NMIIsr);

}

该函数中,首先初始化DSP中断控制器,IntDSPINTCInit函数细节见这篇博文:

C6748_SPI_FLASH

然后,程序将CPU不可屏蔽中断C674X_MASK_NMI#1)的中断服务函数注册为NMIIsr函数。IntRegister函数参考这里:

C6748_EDMA_GPIO_中断学习笔记

NMI引脚低电平有效,当该引脚输入低电平时,将会发送不可屏蔽中断(NMEVT)。

(指南P27

Megamodule手册P167

5.GPIO管脚初始化

    GPIO管脚初始化函数GPIOBankPinInit如下:

voidGPIOBankPinInit(void)

{

    //配置 LED对应管脚为输出管脚

// OMAPL138 DSP C6748共有 144 GPIO

    //以下为各组 GPIO BANK起始管脚对应值

//范围 1-144

    // GPIO0[0] 1

// GPIO1[0] 17

    // GPIO2[0] 33

// GPIO3[0] 49

    // GPIO4[0] 65

// GPIO5[0] 81

    // GPIO6[0] 97

    // GPIO7[0] 113

    // GPIO8[0] 129

 

    //核心板 LED

GPIODirModeSet(SOC_GPIO_0_REGS,109, GPIO_DIR_OUTPUT); // GPIO6[12]

GPIODirModeSet(SOC_GPIO_0_REGS,110, GPIO_DIR_OUTPUT); // GPIO6[13]

}

该函数将GPIO6[12]脚和GPIO6[13]脚方向设为输出,GPIODirModeSet函数如下:

voidGPIODirModeSet(unsignedint baseAdd, unsignedint pinNumber,

unsignedint pinDir)

 

{

unsignedint regNumber=0;

unsignedint pinOffset=0;

 

/*

** Each register contains settings for each pin of two banks. The 32 bits

** represent 16 pins each from the banks. Thus the register number must be

** calculated based on 32 pins boundary.

*/

regNumber= (pinNumber -1)/32;

 

/*

** In every register the least significant bits starts with a GPIO number on

** a boundary of 32. Thus the pin offset must be calculated based on 32

** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in

** 'register_name01'.

*/

pinOffset= (pinNumber -1)%32;

 

if(GPIO_DIR_OUTPUT== pinDir)

{

HWREG(baseAdd+GPIO_DIR(regNumber))&=~(1<< pinOffset);

}

else

{

HWREG(baseAdd+GPIO_DIR(regNumber))|= (1<< pinOffset);

}

}

该函数设置GPIO_DIRn寄存器,从而配置GPIO引脚的输入输出方向。

6.中断服务函数

    中断服务函数如下:

#pragmaNMI_INTERRUPT(NMIIsr)

voidNMIIsr(void)

{

    GPIOPinWrite(SOC_GPIO_0_REGS,109, Flag);

    //翻转标志位

    Flag=!Flag;

    GPIOPinWrite(SOC_GPIO_0_REGS,110, Flag);

}

 

其中,第一条语句为Pragma预处理指令,该指令使能直接用C代码处理不可屏蔽中断。

(CCS帮助文档)

在中断服务函数中,程序实现GPIO6[12]和GPIO6[13]两个引脚的输出翻转,GPIOPinWrite函数如下:

voidGPIOPinWrite(unsignedint baseAdd, unsignedint pinNumber,

unsignedint bitValue)

{

unsignedint regNumber=0;

unsignedint pinOffset=0;

 

/*

** Each register contains settings for each pin of two banks. The 32 bits

** represent 16 pins each from the banks. Thus the register number must be

** calculated based on 32 pins boundary.

*/

 

regNumber= (pinNumber -1)/32;

 

/*

** In every register the least significant bits starts with a GPIO number on

** a boundary of 32. Thus the pin offset must be calculated based on 32

** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in

** 'register_name01'.

*/

 

pinOffset= (pinNumber -1)%32;

 

if(GPIO_PIN_LOW== bitValue)

{

HWREG(baseAdd+GPIO_CLR_DATA(regNumber))= (1<< pinOffset);

}

elseif(GPIO_PIN_HIGH== bitValue)

{

HWREG(baseAdd+GPIO_SET_DATA(regNumber))= (1<< pinOffset);

}

}

函数根据要输出的电平是高还是低,往GPIO_CLR_DATA寄存器和GPIO_SET_DATA寄存器的相应位写1,如果输出的是低电平,则往GPIO_CLR_DATA寄存器的相应位写1;如果输出的是高电平,则往GPIO_SET_DATA寄存器的相应位写1。

(指南P853)

(指南P854)

(指南P855)

(指南P856)

原创粉丝点击